Прием строки по UART с помощью прерываний

Обсуждаем контроллеры компании Atmel.
Ответить
Нашел транзистор. Понюхал.
Сообщения: 194
Зарегистрирован: Сб ноя 07, 2009 15:27:59

Сообщение kushman »

Добрый день!
Набросал небольшую функцию приема строки с помощью прерываний, код приведен ниже. Конец строки определяется по задержке в 3 секунды. Все в принципе работает, за исключением того, что принимаются только 3 символа. При отправке строки ABCD на экран выводится ABD и т.д.
Что я делаю не так?)

Код: Выделить всё

unsigned char UART_buffer[16];

interrupt [USART_RXC] void UART_Receive(void) {

    UART_buffer[i]=UDR;
    i++;
    SREG.7=1; 
    UCSRA.7=1;
    UCSRB.7=1;    
    send_lcd(set_first_line, UART_buffer);  
    delay_ms(3000);
    i=0;      
}
Реклама
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1518
Зарегистрирован: Пт дек 28, 2012 21:56:46
Откуда: St. Petersburg

Сообщение blackx »

Не знаю точно, отчего вы получаете такое поведение. Однако, не зря рекомендуют делать процедуры прерываний как можно более короткими в плане времени выполнения. У вас же прямо в прерывании задержка поставлена - так делать нельзя.

Лучше всего сделать разделение строк по символам переноса строки - "\r\n" (CR LF) или просто "\n" (LF).
Изображение only pure true norwegian blackx Изображение
Реклама
Вымогатель припоя
Аватара пользователя
Сообщения: 672
Зарегистрирован: Ср фев 29, 2012 01:58:32
Откуда: Харьков, Украина

Сообщение eess9 »

уберите это

Код: Выделить всё

delay_ms(3000);
и сделайте через таймер. Получается пока 3 сек задержка не выполнится из прерывания вы не выйдете. А представьте сколько данных по uart за 3 сек вы можете пропустить. Либо разрешите прерывания внутри этого прерывания. Но вложенные прерывания - это отдельная тема, с ними надо быть очень осторожным...
Открыл глаза
Аватара пользователя
Сообщения: 69
Зарегистрирован: Чт авг 11, 2011 12:59:42
Откуда: Луганск

Сообщение legalize »

Посмотри в моей теме, в этой же ветке. Может что прояснится
Реклама
Эиком - электронные компоненты и радиодетали
Вымогатель припоя
Аватара пользователя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Сообщение zero648 »

Вот это, я, бы тоже в main выкинул:

Код: Выделить всё

    send_lcd(set_first_line, UART_buffer);  
Короче, все что не касается приема, все нужно выкинуть в main.
Реклама
Нашел транзистор. Понюхал.
Сообщения: 194
Зарегистрирован: Сб ноя 07, 2009 15:27:59

Сообщение kushman »

Решил проблему очень просто, сделал свою функции задержки, которая состоит из пустых циклов. Понимаю, что это не совсем правильно и корректно, но вот нижеприведенный код прекрасно работает) Следующим шагом сделаю остановку приема по символу конца строки.

Код: Выделить всё

interrupt [USART_RXC] void UART_Receive(void) {
  
    UART_buffer[i]=UDR;
    i++;    
    SREG.7=1; 
    UCSRA.7=1;
    UCSRB.7=1;      
    delay(); 
    i=0;    
    send_lcd(set_first_line, UART_buffer);
}
Реклама
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень

Сообщение vitalik_1984 »

А зачем вообще эта задержка в прерывании, разрешите узнать?

Код: Выделить всё

interrupt [USART_RXC] void UART_Receive(void) {
  
    UART_buffer[i]=UDR;
    i++;    //Две ненужные команды это первая
    SREG.7=1; 
    UCSRA.7=1;
    UCSRB.7=1;      
    delay(); //Это третья  :))) 
    i=0;    //Это вторая :)
    send_lcd(set_first_line, UART_buffer);
} 
вы ведь не используете сам буфер между прибавлением числа и обнулением индекса :dont_know:
Тут можно почитать про обмен данными через UART
Контактная информация:
Ответить

Вернуться в «AVR»