Обработка принятых по протоколу USART данных на примере ATmega8
Очень часто приходится осуществлять связь с различными устройствами через модуль USART микроконтроллера, принимать и отправлять данные. Вот как раз как можно обрабатывать данные и приведу пример обработки данных принятых по протоколу USART.
Для реализации нам понадобятся навыки работы с прерываниями , а именно нам понадобится вектор прерыванию срабатывающий на приход байта по каналу USART. Заглянув например в datasheet на микроконтроллер ATmega8 на странице 44 расположена таблица прерываний данного микроконтроллера.
Нам понадобится вектор номер 12 в таблице. В программе он будет обозначен как: USART_RXC_vect
Если коротко, то прерывание - это событие при выполнении которого основная программа на время останавливается, и начинает выполнятся подпрограмма, которая по алгоритму должна выполняется при срабатывании данного прерывания.
В таблице прерываний микроконтроллера показано что вектор прерывания (вектор - это по сути источник, причина прерывания) может быть от нажатия кнопки подключенной к одному из двух входов Int0 и Int1 до срабатывания на переполнение внутреннего 16-ти битного счетчика микроконтроллера.
кусок кода для прерывания по приходу байта по протоколу USART:
#include <avr/io.h>//Библиотека ввода/вывода #include <avr/interrupt.h>//Библиотека прерываний //Подпрограмма-обработчик прерывания //по приходу байта на модуль USART ISR(USART_RXC_vect) { int b; b = UDR;//Присваиваем переменной b содержимое регистра UDR именно в нем хранится принятый байт .....//Программа обработки принятого байта }
И так, основы прошли, теперь сама программа.
Для более приближенного знакомства давайте сделаем программку, которая будет определять что мы приняли и в соответствии с этим она будет выполнять определенное действие. В данной программа алгоритм следующий:
если мы получили по USART "1" - отправляем по USART букву "R",
а если приняли "2" - то отправляем по USART букву "L".
#include <avr/io.h>//Библиотека ввода/вывода #include <avr/interrupt.h>//Библиотека прерываний //Прототипы подпрограмм void USART_Transmit( unsigned char data ); void USART_Init( unsigned int ubrr); //Подпрограмма обработки прерывания ISR(USART_RXC_vect) { int b; b = UDR; // Выполняем обработку принятого байта if (b=='1')//Если приняли "1" { USART_Transmit('R');//Отправляем букву "R" USART_Transmit(0x0d);//переход в начало строки USART_Transmit(0x0a);//переход на новую строку } else//Если нет if (b=='2')//Если приняли "2" { USART_Transmit('L');//Отправляем букву "L" USART_Transmit(0x0d);//переход в начало строки USART_Transmit(0x0a);//переход на новую строку } } void USART_Init( unsigned int ubrr)//Инициализация модуля USART { /* Задаем скорость работы USART */ UBRRH = (unsigned char)(ubrr>>8); UBRRL = (unsigned char)ubrr; /* Разрешаем прием и передачу по USART */ UCSRB=(1<<RXEN)|( 1<<TXEN); UCSRB |= (1<<RXCIE); //UCSRB=(1<<RXEN)|(1<<TXEN)|(1<<RXCIE); /* Устанавливаем формат данных 8 бит данных, 2 стоп бита */ UCSRC=0x86;// Инициализация именно для ATmega8 UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0); } void USART_Transmit( unsigned char data ) //Функция отправки данных { while ( !(UCSRA & (1<<UDRE)) ); //Ожидание опустошения буфера приема UDR = data; //Начало передачи данных } int main(void)//главная программа { //Скорость USART 115200 при кварцевом генераторе 16MHz USART_Init (8); USART_Transmit('O');//Передаем при включении USART_Transmit('k');//сообщение "Ok!", что свидетельствует USART_Transmit('!');//о правильно работе программы USART_Transmit(0x0d);//переход в начало строки USART_Transmit(0x0a);//переход на новую строку sei();//разрешаем глобально прерывания while(1)//вечный цикл {//тут пусто, да можно и так писать :) }// }
Программа написана под микроконтроллер ATmega8 для других микроконтроллеров семейства AVR подпрограмма инициализации модуля USART может быть другой (для Attiny2313 точно другая, смотрите в разделе шаблоны).
Никак не хочет работать -
Никак не хочет работать - одно ехо. Скинте пожалуйста проект AVR Studio (исходники) пожалуйста.
строки uart
Добрый день. У меня появилась такая идея как управление мк через uart с пк.
Как отправлять строки на ПК я разобрался, только вот одна проблема как отправить строку с пк, которую приням мк выполнил команду например PORTB=0x01; ну или меняла какие то переменные. Вообще такое возможно?
да в обработчик прерывания
да в обработчик прерывания можно записать комманду выполнения любой функции.
Что касается функционала функции, то он ограничивается только возможностями микроконтроллера!
строки uart
Еще раз здравствуйте. Со строками разобрался. отправляю через терминал PUTTY контроллер принимает и с помощью функции сравнения strncmp(); выполняет команды. Появилась другая проблема, когда печатаешь символы в терминале и они отправляются на МК,но мк не отправляет мне обратно то что я напечатал, хочется сделать что то вроде консоли. То есть напечатал символ контроллер его принял и вывел сразу в терминал, а то получается что я печатаю в слепую.
А как ты принимаешь и
А как ты принимаешь и сравниваешь строки ?
Если не трудно кинь примерчик)
Сравнивать нужно функцией
Сравнивать нужно функцией strcmp(str1,str2);
Со строками лично я не
Со строками лично я не работал.
Но делал например так, чтобы сравнивались слова, имею в виду один и более символов подряд.
Была использована идея буфера, который сравнивается с эталонным поэлементно. Теоретически если увеличить буфер и у микроконтроллера хватит памяти на этот буфер то можно и строку загнать довольно большую.
Пример:
Шаблон программы USART
Шаблон программы USART ECHO
Вот код проги, которая просто принмает и отправляет назад символ.
протокол NMEA
А как обрабатывать сообщения из gps приемника в протоколе NMEA и выводить их на lcd?
GPS приемник периодически
GPS приемник периодически посылает по UART пакет данных (если он такого не делает - нужно его настроить, чтобы он посылал нам сообщение GGA, в котором содержиться широта-долгота-высота-полушария-время). Теперь нужно выдрать широту-долготу, высоту над уровнем моря, и что там тебе еще нужно. Структуру пакета можно прочитать в мануале описывающим NMEA. Выдирается все просто, знаем что широта - выводиться в байтах 18-24, делаем в цикле приема пакета счетчик, как только он достигает 18-ти, выводим принятые данные сразу на ЖКИ, а как достигнет 25 - уже ничего не выводим. И так для каждого измерения.