Прерывание по поступлению байта, USART прерывание - Arduino mega 2560
- Войдите на сайт для отправки комментариев
Втр, 01/10/2013 - 13:20
Добрый день! Вот решил разместить здесь мануальчик по работе с прерыванием USART, может кому понадобится. Мне понадобилось работать с этим прерыванием, но поиск по форуму мне ничего вразумительного недал пришлось гумозить самому вот результат. /* ARDUINO MEGA 2560 */ /* Простой пример */ /* Обработка прерываний по поступлению байта */ #include <avr/interrupt.h> //библиотека прерываний char s[2];//Массив для приема байтов int i=0;//счетчик принятых байтов void USART_Init(int baudrate ) //Функция инициализации USART { /* Set baud rate */ UBRR0H = baudrate>>8; UBRR0L = baudrate; //Разрешение на прием и на передачу через USART, прерывания по поступлению и по опустошению UCSR0B = (1<<RXCIE0)|(1<<TXCIE0)|(1<<RXEN0)|(1<<TXEN0); UCSR0C = (1<<UCSZ01)|(1<<UCSZ00); //размер слова 8 разрядов sei(); } // USART_Init // the setup routine runs once when you press reset: void setup() { // initialize the digital pin as an output. pinMode(15, OUTPUT); USART_Init(103);// число 103 соответствует baudrate 9600 при 16MHz. смотреть datasheet нa ATMega 2560 } void USART_Transmit( unsigned char data )//Функция отправки данных { /* Wait for empty transmit buffer */ while ( !( UCSR0A & (1<<UDRE0)) ); /* Put data into buffer, sends the data */ UDR0 = data; } unsigned char USART_Receive( void )//Функция приема данных { /* Wait for data to be received */ while ( !(UCSR0A & (1<<RXC0)) ); /* Get and return received data from buffer */ return UDR0; } //Обрабатываем прерывание по поступлению байта ISR(USART0_RX_vect) { s[i]=UDR0;//принимаем байт в массив char i++; if (i == 2)//если приняли 2 байта { if (s[0] == 'o' and s[1] == 'n')//проверяем что приняли, если команду "on" { digitalWrite(15, HIGH);//зажигаем светодиод /* отправляем обратно в порт команду "on" (типо все ок команда принята) */ USART_Transmit('o'); delay(1); USART_Transmit('n'); } if (s[0] == 'o' and s[1] == 'f')//проверяем что приняли, если команду "of" { digitalWrite(15, LOW);//гасим светодиод /* отправляем обратно в порт команду "of" (типо все ок команда принята) */ USART_Transmit('o'); delay(1); USART_Transmit('f'); } // сбрасываем все i=0; s[0]='0'; s[1]='0'; } } // the loop routine runs over and over again forever: void loop() { }
http://arduino.cc/en/Reference/SerialEvent
http://arduino.cc/en/Reference/SerialEvent
Ухты тоже не плохо. Спасибо!
Вот мой аналог этого скетча (файл прошивки весит в три раза меньше) :
бабтист вы на форуме бываете естьвопрос по прерываниям
http://arduino.cc/en/Reference/SerialEvent
SerialEvent() не работает по прерыванию, а вызывается в главном цикле loop() программы.
Т.о., если поставить большую задержку (или выпонять громоздкий код) в главном цикле,
то получим перезатирание буфера RX.
Фиговый мануальчик - после отправки данных на терминал Arduino перезагружается
Зачем нужна функция //Функция приема данных ? В которой части кода она используется ?
Код работает , как надо. Ничего не перезагружается. По команде "on" подает 5 вольт на 15 ногу и шлет в сериал "on", по команде "of" сбрасывает напряжение до нуля и шлет в сериал "of".
Код работает , как надо. Ничего не перезагружается. По команде "on" подает 5 вольт на 15 ногу и шлет в сериал "on", по команде "of" сбрасывает напряжение до нуля и шлет в сериал "of".
А вы подключите экранчик или еще что-нибудь и результат Вас приятно удивит ;-)
Где в Вашем коде обработчик (1<<TXCIE0) по опустошению ? Программа действительно все делает до конца, а поскольку обработчика данного прерывания нет Arduino благополучно уходит в перезагрузку обнуляя все переменные (регистры при аварийной перезагрузке не обнуляются) в этом легко убедиться если воткнуть экран и выводить время с помощью функции millis(); Скопировали откуда-то код а как он работает не разобрались.
Такая длинная обработка в прерывании не есть хорошо... Делаи и диджиталврайты в прерывании это сильно.
люди, простите за безграмотность в микроконтроллерах, но в двух словах: зачем в вышеприведенном примере описывается процедура
unsigned
char
USART_Receive(
void
)
//Функция приема данных
49
{
50
/* Wait for data to be received */
51
while
( !(UCSR0A & (1<<RXC0)) );
52
/* Get and return received data from buffer */
53
return
UDR0;
54
}
если явно она нигде не вызывается?
как она вызывается, в каких условиях, когда...
and.pi она не вызывается. т.к. настроен прием по прерыванию. если отключить прерывание то надо задействовать эту функцию.
алекс, на даты смотрим? Вопрос протух давно, да к тому же ваш ответ ну ничего ценного не несет
Привет. Второй день ни как не получается словить оба спец символа \n\r. Вчера ловил n сегодня r и на этом передача заканчивается.
Принимаю в таком прерывании для nano
Подскажите как подправить код чтоб словить оба спец символа ?
на этом передача заканчивается.
не удивительно. функцию delay() в прерывании использовать нельзя.
Кстати. нафига она тут?
без delay тоже самое. это я уже в конце эксперементировал. может буфер не успевал опусташаться.
c делей точно работать не будет. А почему без нее не работает...
Вот вы пишете в другой теме. что понимаете, что по UART приходят байты. Я вот по коду вижу - что нифига не понимаете.
Попробуйте записать свои "\r" "\n" как байты в числовом виде - 100% не уверен. но что-то мне подсказывает. что может помочь
может буфер не успевал опусташаться.
Какой, в болото, буфер?
b707 если проблема в "байты в числовом виде" ни один вариант не срабатывал бы. логично?
но байты тоже писал. местами строки переставлял , через переменные, флаги и прочее... плюс вообще не понятно вчера N печатал только а сегодня (другая компелация) только R...
b707 если проблема в "байты в числовом виде" ни один вариант не срабатывал бы. логично?
нет, не логично. Я бы вам вообще посоветовал ничего в программировании исходя из своей логики не решать, ибо вы логику программного кода не понимаете вовсе. Читайте учебники.
Запись '1' - это один символ, а '\n' - это непонятно что, ни два ни полтора, ибо эскейп-последовательности работают только в двойных кавычках.
но байты тоже писал. местами строки переставлял , через переменные, флаги и прочее... плюс вообще не понятно вчера N печатал только а сегодня (другая компелация) только R...
я ответ давно знаю. И вы тоже. Просто вы - .... ну вы знаете.
Вы тоже, как обезьянка. втупую стучите по клавишам. надеясь что выйдет шедевр. Но у вас рождаются только "шедевры".
Я не знаю, почему у вас байты не срабатывали. Может вы их с делеями пробовали, может еще какую хрень учудили. Да и остальной код я не видел. Но сам результат меня абсолютно не удивляет
так тоже только R печатает. может это зависит от ардуино монитора ? может он N не предает
может это зависит от ардуино монитора ? может он N не предает
пипец... а настройки монитора посмотреть?
выделено внизу справа
Запись '1' - это один символ, а '\n' - это непонятно что, ни два ни полтора, ибо эскейп-последовательности работают только в двойных кавычках.
no comment
вначале написал а потом проверил. всмысле что надо было наоборот. наэксперементировал так что забыл вернуть обратно. снял с ручника. поставил NL&CR. вопрос отпал.
но про полтора и в кавычках это шедевр :)
'\n' - это непонятно что, ни два ни полтора, ибо эскейп-последовательности работают только в двойных кавычках.
Чойта? Я что-то пропустил, видимо? Всегда думал, что это вполне себе вменяемый char. '\r','\t' или вапще '\x20'
Запись '1' - это один символ, а '\n' - это непонятно что, ни два ни полтора, ибо эскейп-последовательности работают только в двойных кавычках.
no comment
Хочешь поспорить? Или просто впервые услыхал?
Читай http://cppstudio.com/post/256/
Цитата:
Все управляющие символы, при использовании, обрамляются двойными кавычками,
Все управляющие символы, при использовании, обрамляются двойными кавычками,
О_О
а самому проверить c == 10 и c == '\n' ?
пожалуйста https://onlinegdb.com/HktuO1yP_
Все управляющие символы, при использовании, обрамляются двойными кавычками,
О_О
ну не знаю :) меня так учили, что последовательность "\r" - это 0х0d, а '\r' - это просто '\' + 'r'
Петрович придёт, расскажет, что неправильно или меня или тебя учили.
а самому проверить c == 10 и c == '\n' ?
пожалуйста https://onlinegdb.com/HktuO1yP_
Я с дедсименом разговариваю, а ты не веселись - у тебя "шедевров" на 20 таких как я хватит
b707 и что мне тебя тоже к мартышкам послать? все ошибаются . + это (№13) вопрос был. на форуме о помощи. чо бычить то сразу
Я с дедсименом разговариваю, а ты не веселись - у тебя "шедевров" на 20 таких как я хватит
Вопщем, если этот сайт не врёть, то сётаки тебя плохо учили. :)
что мне тебя тоже к мартышкам послать? все ошибаются
так посылай. Когда заслуженно - я не обижаюсь.
Но мне хотелось бы, чтобы еще кто-то выступил по двойным кавычкам. Я ж не сейчас это придумал. я это знаю (или "знаю") много лет. да и ссылку вон с подтверждением - выше - нашел в гугле на раз. не один я так думаю. если это ошибка - то распространенная
Нинаю, я с децтва использовал, допустим, '\t' и не знал, что так делать низя. :)
Вопщем, если этот сайт не врёть, то сётаки тебя плохо учили. :)
ок, поял :) Значит был неправ.
Но я бы все равно вот так
писать не стал бы, байт намного проще с 0x0D сравнивать - да и не ошибешься в типе кавычек
Но я бы все равно вот так
писать не стал бы, байт намного проще с 0x0D сравнивать - да и не ошибешься в типе кавычек
А я вот даже и не помню, чему соответствует '/n', 0x0D или 0x0А, всегда char именно так и сравнивал, как ты говоришь "не стал бы".
А я вот даже и не помню, чему соответствует '/n', 0x0D или 0x0А, всегда char именно так и сравнивал, как ты говоришь "не стал бы".
да я не настаиваю. У меня просто выбора не было :)
то же самое что и
кстати заметил что некоторые терминалы/девайсы оканчивают строку \n\r а некоторые \r\n
вы как обычно отлавливаете конец строки/передачи ? проверяте оба случая?
т.е. если проверять только что конец это "\n\r" скетч глюканет на другом девайсе/терминале. или както по другому проверяете?
про такое никто и не говорит, тут слева Чар, справа строка - ничего хорошего из этого не выйдет
Ладно, проехали.
"Сколько можно напоминать! я уже принес свои извинения" (с) Покровские ворота :)
кстати заметил что некоторые терминалы/девайсы оканчивают строку \n\r а некоторые \r\n
вы как обычно отлавливаете конец строки/передачи ? проверяте оба случая?
\n\r - никогда такого не встречал, поэтому не отлавливаю.
\r\n 1.8.10 (и ранее/ а выше не проверял) ардуино мне например так шлёт. какойто gsm модем тоже мне так слал... долго тогда еще тупил, тоже считал (до того момента) что может быть только \n\r
warning: initialization makes integer from pointer without a cast
\r\n 1.8.10 (и ранее/ а выше не проверял) ардуино мне например так шлёт. какойто gsm модем тоже мне так слал...
Вы опять все перепутали. Оно и должно слать \r\n
никакого "тоже" нет, меня не примазывайте. Вы ожидали \n\r, тогда как у всех наоборот.
Есть примеры. чтобы кто-то слал \n\r ?
warning: initialization makes integer from pointer without a cast
Ну а чего вы хотели ? У вас переменная char , а пихаете вы в нее два байта...
Может стоит написать char ch='\n' ?
никакого "тоже" нет, меня не примазывайте. Вы ожидали \n\r, тогда как у всех наоборот.
Есть примеры. чтобы кто-то слал \n\r ?
Вот тут кстати нет правил :( И ИМХО нужно писать так, что бы обрабатывалось три варианта 1- \n, 2-\n\r, 3-\r\n
Ну а чего вы хотели ? У вас переменная char , а пихаете вы в нее два байта...
Может стоит написать char ch='\n' ?
не, это они меня все троллят, что я написал что '\n' писать нельзя :)
Почему-то был уверен. что эскейп-последовательности компилятор обрабатывает только внутри двойных кавычек. Ну и, естесственно, что применять их можно только внутри многосимвольных строк.
Вот тут кстати нет правил :( И ИМХО нужно писать так, что бы обрабатывалось три варианта 1- \n, 2-\n\r, 3-\r\n
а оно такое есть? - \n\r
Аааа, понял :) Ну тогда ch=*(char*)&"\n" .
Вот тут кстати нет правил :( И ИМХО нужно писать так, что бы обрабатывалось три варианта 1- \n, 2-\n\r, 3-\r\n
а оно такое есть? - \n\r
Конечно ! Еще как. Даже в терминалке ИДЕ имеет место быть и это не с проста :)