реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> WinAvr. UART + ISR = Reset :(
ISG2015
сообщение Jun 11 2015, 13:20
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 33
Регистрация: 6-05-15
Пользователь №: 86 547



Код UART
CODE
/*
********************************************************************************
* GLOBAL FUNCTION
********************************************************************************
*/

INT08U UART_RxBuf[UART_RX_BUFFER_SIZE];
volatile INT08U UART_RxHead;
volatile INT08U UART_RxTail;

INT08U UART_TxBuf[UART_TX_BUFFER_SIZE];
volatile INT08U UART_TxHead;
volatile INT08U UART_TxTail;


INT08U UARTDataInReceiveBuffer (void) {
INT08U temp1 = UART_RxHead, temp2 = UART_RxTail;
return (temp1 != temp2);
}

INT08U UARTReceiveByte (void) {
INT08U temp=UART_RxHead;
INT08U tmptail;



while (temp == UART_RxTail) {
temp = UART_RxHead;
};

tmptail = ( UART_RxTail + 1 ) & UART_RX_BUFFER_MASK;
UART_RxTail = tmptail;
return UART_RxBuf[tmptail];
}

void UARTTransmitByte (INT08U data ) {
INT08U tmphead;
tmphead = ( UART_TxHead + 1 ) & UART_TX_BUFFER_MASK;
while ( tmphead == UART_TxTail );
UART_TxBuf[tmphead] = data;
UART_TxHead = tmphead;
UCSR1B |= (1<<UDRIE1);
}


/*
********************************************************************************
* LOCAL FUNCTION
********************************************************************************
*/


ISR(USART1_RX_vect) {
INT08U data;
INT08U tmphead;

data = UDR1;
tmphead = ( UART_RxHead + 1 ) & UART_RX_BUFFER_MASK;
UART_RxHead = tmphead;
if (tmphead == UART_RxTail) { /* ERROR! Receive buffer overflow */ }
UART_RxBuf[tmphead] = data;
}

ISR(USART1_UDRE_vect ) {
INT08U temp1 = UART_TxHead, temp2 = UART_TxTail;
INT08U tmptail;

if (temp1 != temp2) {
tmptail = ( UART_TxTail + 1 ) & UART_TX_BUFFER_MASK;
UART_TxTail = tmptail;
UDR1=UART_TxBuf[tmptail];
}
else {
UCSR1B &= ~(1<<UDRIE1);
}
}


Код "перенаправления" вывода
Код
// прототип функции вывода символа
int my_putchar(char c, FILE *stream);

// определяем дескриптор для стандартного вывода
FILE mystdout = FDEV_SETUP_STREAM(
                my_putchar,     // функция вывода символа
                NULL,           // функция ввода символа, нам сейчас не нужна
                _FDEV_SETUP_WRITE // флаги потока - только вывод
);
// функция вывода символа
int my_putchar(char c, FILE *stream)
{
        UARTTransmitByte(c);
        return 0;
}



Код я перетащил из старого IAR проекта в WINAVR. Так нужно было.
Если "printf" вызываю из main - ок. Если из других модулей - перегружается проц.
Просто не понимаю даже куда смотреть. Спасибо за советы.

Не ясно еще как память посмотреть. Может быть я что то навтыкал с оперативой/стеком/кучей..
В IAR я просто в настройках проекта менял границы этих областей и иногда все разруливалось. Что делать в WinAVR совсем не понимаю.

Сообщение отредактировал IgorKossak - Jun 11 2015, 16:20
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post
demiurg1978
сообщение Jun 12 2015, 05:01
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 333
Регистрация: 19-12-13
Из: Новосибирск
Пользователь №: 79 709



Watchdog?
У сторожевого таймера есть флаг,который устанавливается, когда сработает сброс. Напишите тестовый модуль в начале программы, чтобы проверялся этот флаг. При подаче напряжения питания флаг сброшен. Если мк сбросится по watchdog, флаг будет установлен.
Go to the top of the page
 
+Quote Post
ISG2015
сообщение Jun 12 2015, 07:11
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 33
Регистрация: 6-05-15
Пользователь №: 86 547



Разобрался. Оказывается не устраивал компилятор подход к инициализации UART
Код
UCSR1B = (1<<RXEN1)|(1<<TXEN1)|(1<<UDRIE1)|(1<<RXCIE1);//|(1<<TXCIE1);

Заремил "|(1<<TXCIE1)" и все поехало.

Пришлось весь проект перепахатьsm.gif Спасибо!
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jun 12 2015, 08:41
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(ISG2015 @ Jun 12 2015, 10:11) *
Оказывается не устраивал компилятор подход к инициализации UART
Вот причем тут компилятор? Он сделал именно то, что вы попросили. Вы разрешили прерывание, не прописав для него обработчик. Компилятор сделал все как просили, процессор выполнил именно то, что вы попросили. Не их вина, что вы попросили не то, что хотели на самом деле. Понятно, что ошибаются все, но зачем валить с больной головы на здоровую?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
ISG2015
сообщение Jun 12 2015, 10:50
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 33
Регистрация: 6-05-15
Пользователь №: 86 547



Все именно так. Я хотел было поправить сообщение, но поленился. Меня подвело то, что я в IAR пользовался этим кодом и там работал UART с такой инициализацией. С WinAvr такой номер не прокатил так как вероятнее нет чего то типа reti из прерываний описанных по умолчанию где то в пучинах IAR.
Самое главное ,что я понял как важно быть внимательным и не тупить на ровном местеsm.gif
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 13:23
Рейтинг@Mail.ru


Страница сгенерированна за 0.01379 секунд с 7
ELECTRONIX ©2004-2016