По просьбам трудящихся, было решено продолжить урок по передаче данных через UART. Основной проблемой, на мой взгляд, при общении двух микроконтроллеров является прием данных.
В качестве примера возьмем две Atmega8. Задача первого микроконтроллера переслать массив символов, задача второго принять их и вывести на экран LCD дисплея. Схема будет выглядеть так:
Код передающего микроконтроллера будет выглядеть так:
#include <mega8.h> #include <stdio.h> void main(void) { char massiv[5]={'h','e','l','l','o'}; bit on=0; int i=0; PORTC=0x01; DDRC=0x00; UCSRA=0x00; UCSRB=0x08; UCSRC=0x86; UBRRH=0x00; UBRRL=0x33; while (1) { if(PINC.0==0 && on==0) { UDR=massiv[i]; i++; if(i>4) { i=0; } on=1; } if(PINC.0!=0) { on=0; } }; } |
При нажатии на кнопку передается 1 элемент массива символов, при повторном нажатии — следующий символ и т.д. В результате должен передаться массив «hello». Переменная on нужна для исключения дребезга кнопки (для передачи следующего символа нужно отпустить кнопку и затем нажать).
Второй микроконтроллер принимает данные в прерывании. Код прерывания, CodeWizard создает автоматически. Обработка достаточно большая, пугаться не стоит. Отдельно посмотреть данный код можно выставив галочки как показано на рисунке и щелкнуть File — Program Preview.
Разберемся с нашим алгоритмом, для нас самое главное это само прерывание:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | // USART Receiver interrupt service routine interrupt [USART_RXC] void usart_rx_isr(void) { char status,data; status=UCSRA; data=UDR; if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0) { rx_buffer[rx_wr_index]=data; if (++rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0; if (++rx_counter == RX_BUFFER_SIZE) { rx_counter=0; rx_buffer_overflow=1; }; }; //здесь мы помещаем приходящие данные в массив, заранее известно количество //принимаемых символов = 5 uart_data[i]=data; i++; if(i>4) { i=0; } } |
Прием производится в прерывании, т.е. как только символ пришел срабатывает прерывание — символ записывается в первый элемент массива, инкрементируется счетчик. В следующее прерывание приходит следующий символ и т.д. Сразу оговорюсь, что количество приходящих символов заранее известно.
Теперь осталось только вывести результат на экран, для этого в цикле выводятся все символы на экран.
1 2 3 4 5 6 7 8 | while(j<5) // цикл пока все 5 символов не будут выведены на экран { lcd_gotoxy(j,0); //выбираем место куда будет выводиться символ sprintf(lcd_buffer,"%c",uart_data[j]); //преобразовываем символ в понятный для дисплея вид lcd_puts(lcd_buffer); //выводим на экран j++; //увеличить счетчик } j=0; // обнулить счетчик |

Схема и прошивка доступны тут




90 комментариев: Урок 8.2. Передача данных через UART в AVR микроконтроллерах. Продолжение