Перейти к содержанию
    

WinAvr. UART + ISR = Reset :(

Код UART

/*
********************************************************************************
*							 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
[codebox] для длинного кода, [code] - для короткого!!!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Watchdog?

У сторожевого таймера есть флаг,который устанавливается, когда сработает сброс. Напишите тестовый модуль в начале программы, чтобы проверялся этот флаг. При подаче напряжения питания флаг сброшен. Если мк сбросится по watchdog, флаг будет установлен.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Разобрался. Оказывается не устраивал компилятор подход к инициализации UART

UCSR1B = (1<<RXEN1)|(1<<TXEN1)|(1<<UDRIE1)|(1<<RXCIE1);//|(1<<TXCIE1);

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

 

Пришлось весь проект перепахать:) Спасибо!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Оказывается не устраивал компилятор подход к инициализации UART
Вот причем тут компилятор? Он сделал именно то, что вы попросили. Вы разрешили прерывание, не прописав для него обработчик. Компилятор сделал все как просили, процессор выполнил именно то, что вы попросили. Не их вина, что вы попросили не то, что хотели на самом деле. Понятно, что ошибаются все, но зачем валить с больной головы на здоровую?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Все именно так. Я хотел было поправить сообщение, но поленился. Меня подвело то, что я в IAR пользовался этим кодом и там работал UART с такой инициализацией. С WinAvr такой номер не прокатил так как вероятнее нет чего то типа reti из прерываний описанных по умолчанию где то в пучинах IAR.

Самое главное ,что я понял как важно быть внимательным и не тупить на ровном месте:)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...