Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Не могу заставить работать UART по прерываниям на ATXMega128A1
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
Spider
Всем привет.

За основу взят AVR1307. Там 2 примера, один по прерываниям, второй по опросу. Так вот тот что с прерываниями не работает. Кроме того, я не первый день работаю с AVR, но до этого всё на GCC, и там у меня всё работает. Вот решил освоить IAR и вот sad.gif

Помогите, может в IAR что-то как-то особенно должно быть? (хотя в AVR1307 пример именно для IAR)
Shtirlits
В разных компиляторах по-разному оформляются функции прерывания и прочие абсолютно необходимые вещи, которых нет в стандарте языка. Раз дело не в железе, то начинать нужно с документации на эти #pragma.
Если можно, то текст в студию!
Spider
Оказалось что дело не в прерывании а в чём-то, непонятно в чём.
Следующий код работает:
Код
uint8_t sendArray[NUM_BYTES] = {0x55, 0xaa, 0xf0, 0xff, 0x00, 0x11};

/* Send sendArray. */
    i = 0;
    while (i < NUM_BYTES) {
                if(USART_TXBuffer_PutByte(&USART_data,sendArray[i]))  i++;
    }

и на выходе имеем последовательно 6 байт.
а в принципе то же самое но вот так:
Код
uint8_t sendArray[NUM_BYTES] = {0x55, 0xaa, 0xf0, 0xff, 0x00, 0x11};

int putchar(int data)
{
        if (!USART_TXBuffer_PutByte(&USART_data,data)) return EOF;
        else return data;
}

/* Send sendArray. */
    i = 0;
    while (i < NUM_BYTES) {
            if(putchar(sendArray[i])!=EOF) i++;
    }

уже не работает. На выходе имеем первые 2 байта и всё.
MrYuran
Нифига они не одинаковые.
И что такое USART_TXBuffer_PutByte()?
Хотя нет, похожи...

Случайно в цикле не зависает?
В ИАРе у меня лично с if-ами были глюки.
После того как разобрался, всегда все условия писал в явном виде.
Попробуйте оттрассировать.
Spider
Цитата(MrYuran @ Dec 2 2009, 18:41) *
Нифига они не одинаковые.
И что такое USART_TXBuffer_PutByte()?
Хотя нет, похожи...

А что в корне разного? Мож я чего не понимаю или пропустил.
Это функа из uart_driver из AVR1307.
rezident
А где у вас определен EOF? И покажите прототип USART_TXBuffer_PutByte. Возможно у вас проблемы с неявным приведением типов.
Spider
EOF в stdio.h

bool USART_TXBuffer_PutByte(USART_data_t * usart_data, uint8_t data);
_Pasha
Возьмите и приведите к вменяемому типу параметры и возвращаемые значения - хоть так
Код
int putchar (uint8_t data);

И расскажите, для чего нужны обертки для оберток, которые еще будут использоваться в других обертках smile.gif Кроме утечки стека, разумеется.
Spider
int putchar (int data);
объявлен в stdio.h и нужен для printf()
_Pasha
Цитата(Alexey Belyaev @ Dec 2 2009, 19:43) *
int putchar (int data);
объявлен в stdio.h и нужен для printf()

Понятно, тогда
Код
int putchar(int data)
{
uint8_t tmp = data & 0xff;
        if (!USART_TXBuffer_PutByte(&USART_data, tmp)) return EOF;
        else return data;
}
rezident
Цитата(Alexey Belyaev @ Dec 2 2009, 19:26) *
EOF в stdio.h

bool USART_TXBuffer_PutByte(USART_data_t * usart_data, uint8_t data);

Попробуйте явно привести типы данных к их определениям
Код
if(putchar(sendArray[i])!=EOF) i++;

изменить на
Код
if(putchar((int)(sendArray[i]))!=EOF) i++;

и
Код
if (!USART_TXBuffer_PutByte(&USART_data,data)) return EOF;

на
Код
if (!USART_TXBuffer_PutByte(&USART_data, (uint8_t)data)) return EOF;

Хотя, если честно, мне тоже непонятны причины применения таких "оберток" для реализации функций IAP.
DpInRock
Недавно тоже делал проект на xmege в IAR. 4 UART. Прием-передача по прерываниям.
В атемловский пример смотрел исключительно для справки. Чисто удостовериться - правильно ли понимаю даташит.
А так - они какие-то бесполезные (именно что только бросить взгляд).
Но в процессе каких-либо особенностей или глюков не отметил. Тупо инициализировал, тупо расставил прерывания.
Тупо работает. Проц - реактивный, в сравнении с атмега48. Байты не считаешь, ни о чем не думаешь.

От атмела самый правильный и хороший пример - это про преодолении защиты записи в всякие защищенные регистры.
Spider
Игрался с разными ситуациями с примером от атмела. И получил следующие результаты:
Работает:
Код
/*! Test data to send. */
uint8_t sendArray[NUM_BYTES] = {0x55, 0xaa, 0xf0};

....

... main(...)
{
...
    /* Send sendArray. */
    i = 0;
    while (i < NUM_BYTES) {
        bool byteToBuffer;
        byteToBuffer = USART_TXBuffer_PutByte(&USART_data, sendArray[i]);
        if(byteToBuffer){
            i++;
        }
    }
...
}

Тоже работает:
Код
uint8_t Test[]="Test";


....

... main(...)
{
...
    i = 0;
    while (i < 4) {
        bool byteToBuffer;
        byteToBuffer = USART_TXBuffer_PutByte(&USART_data, Test[i]);
        if(byteToBuffer) i++;
    }
...
}

А следующие куски кода не работают:
Код
....

... main(...)
{
...
    uint8_t Test[]="Test";


    i = 0;
    while (i < 4) {
        bool byteToBuffer;
        byteToBuffer = USART_TXBuffer_PutByte(&USART_data, Test[i]);
        if(byteToBuffer) i++;
    }
...
}

И вот этот
Код
uint8_t Test[]="Test";


....

void send_str(uint8_t *data)
{
  while (*data) USART_TXBuffer_PutByte(&USART_data,*data++);
}

... main(...)
{
...
    send_str(Test);
...
}


Что не так то? в GCC всё это работает.
Сергей Борщ
Цитата(Alexey Belyaev @ Dec 30 2009, 14:35) *
Что не так то? в GCC всё это работает.
У IAR два стека. В третьем примере ваш массив размещается на стеке данных. В четвертом примере стек данных занимается на сохранение регистров при вызове функции. Возможно, его размера не хватает и стек данных налезает на стек возвратов.
P.S. и неплохо бы давать расшифровку понятия "не работает".
Spider
Цитата(Сергей Борщ @ Dec 30 2009, 19:53) *
У IAR два стека. В третьем примере ваш массив размещается на стеке данных. В четвертом примере стек данных занимается на сохранение регистров при вызове функции. Возможно, его размера не хватает и стек данных налезает на стек возвратов.

А есть возможность приблизить это всё к GCC, там с этим проблем никогда не было. И что это за стек такой, который переполняется уже в самом начале программы из сотни строк?
Цитата(Сергей Борщ @ Dec 30 2009, 19:53) *
P.S. и неплохо бы давать расшифровку понятия "не работает".
В 3ем сообщении последняя строка. Из UART выходит в случае с "Test" только "T" и проц как бы подвисает.
Сергей Борщ
Цитата(Alexey Belyaev @ Dec 31 2009, 07:51) *
А есть возможность приблизить это всё к GCC, там с этим проблем никогда не было.
Нет, нельзя. Хотите без таких проблем - используйте GCC. Хотите более эффективный код - будьте добры вручную следить за стеками.
Цитата(Alexey Belyaev @ Dec 31 2009, 07:51) *
И что это за стек такой, который переполняется уже в самом начале программы из сотни строк?
Это зависит не от количества строк, а от размера, который вы дали стеку в настройках проекта. Покопайтесь и выделите там места с запасом: RSTACK - стек возвратов. Прикиньте максимальный уровень вложенности ваших подпрограмм, добавьте максимальный уровень вложенности подпрограмм в прерываниях, умножьте на размер сохраняемого командой call адреса. Мне обычно хватет уровня вложенности 16. CSTACK - стек данных. Выделите ему памяти с хорошим запасом (лучше всего - всю свободную).
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.