День добрый. Соединены пo UART две ардуинки (Uno и Mega). Схема соединения: UNO ___ MEGA +5 В -> +5 В GND -> GND TX(1)->RX(0) RX(0)->TX(1) В MEGA выполняется некоторая задача, но при получении по UART от UNO сообщения необходимо в MEGA прервать выполнении основной программы и обработать пришедшее сообщение. Скетч UNO Код (Text): int dT = 2000; char str[128]; void setup() { Serial.begin(9600); } void loop() { Serial.write("on"); delay(dT); Serial.write("of"); delay(dT); } Скетч MEGA Код (Text): #include <avr/interrupt.h> //библиотека прерываний char s[2];//Массив для приема байтов int i=0;//счетчик принятых байтов int ledpin = 13; void USART_Init(int baudrate ) //Функция инициализации USART { /* Set baud rate */ UBRR0H = baudrate>>8; UBRR0L = baudrate; //Разрешение на прием и на передачу через USART, прерывания по поступлению и по опустошению UCSR0B = (1<<RXCIE0)|(1<<RXEN0); UCSR0C = (1<<UCSZ01)|(1<<UCSZ00); //размер слова 8 разрядов sei(); } // USART_Init void setup() { // initialize the digital pin as an output. pinMode(ledpin, OUTPUT); USART_Init(103);// число 103 соответствует baudrate 9600 при 16MHz. смотреть datasheet нa ATMega 2560 } //Обрабатываем прерывание по поступлению байта ISR(USART0_RX_vect) { s[i]=UDR0;//принимаем байт в массив char i++; if (i == 2)//если приняли 2 байта { if (s[0] == 'o' and s[1] == 'n')//проверяем что приняли, если команду "on" { digitalWrite(ledpin, HIGH);//зажигаем светодиод } if (s[0] == 'o' and s[1] == 'f')//проверяем что приняли, если команду "of" { digitalWrite(ledpin, LOW);//гасим светодиод } // сбрасываем все i=0; s[0]='0'; s[1]='0'; } } // the loop routine runs over and over again forever: void loop() { } В данном случае работает прерывание по окончанию приема сообщения в MEGA. Но как быть если необходимо в MEGA использовать не Serial0, а Serial1 ? Менял ISR(USART0_RX_vect) на ISR(USART1_RX_vect), но прерывание не работает.
Может ерунду пишу... Но Serial1 он, того, программный. Там фунции библиотеки дергают за пины сами. А значит инициализировать его как аппаратный (только другой порт) не получится.
Сам разобрался Вот скетч на прием байт по Serial1. Код (Text): #include <avr/interrupt.h> //библиотека прерываний char s[2];//Массив для приема байтов int i=0;//счетчик принятых байтов int ledpin = 13; void USART_Init(int baudrate ) //Функция инициализации USART { /* Set baud rate */ UBRR1H = baudrate>>8; UBRR1L = baudrate; //Разрешение на прием и на передачу через USART, прерывания по поступлению и по опустошению UCSR1B = (1<<RXCIE1)|(1<<RXEN1); UCSR1C = (1<<UCSZ01)|(1<<UCSZ00); //размер слова 8 разрядов sei(); } // USART_Init void setup() { // initialize the digital pin as an output. pinMode(ledpin, OUTPUT); USART_Init(103);// число 103 соответствует baudrate 9600 при 16MHz. смотреть datasheet нa ATMega 2560 } //Обрабатываем прерывание по поступлению байта ISR(USART1_RX_vect) { s[i]=UDR1;//принимаем байт в массив char i++; if (i == 2)//если приняли 2 байта { if (s[0] == 'o' and s[1] == 'n')//проверяем что приняли, если команду "on" { digitalWrite(ledpin, HIGH);//зажигаем светодиод } if (s[0] == 'o' and s[1] == 'f')//проверяем что приняли, если команду "of" { digitalWrite(ledpin, LOW);//гасим светодиод } // сбрасываем все i=0; s[0]='0'; s[1]='0'; } } // the loop routine runs over and over again forever: void loop() { }