Серийни прекъсвания на Arduino

Работя върху проект Arduino Mega 2560. На компютър с Windows 7 използвам Arduino1.0 IDE. Трябва да установя серийна Bluetooth комуникация със скорост на предаване 115200. Трябва да получа прекъсване, когато има налични данни при RX. Всяка част от кода, която съм виждал, използва „polling“, което поставя условие на Serial.available в цикъла на Arduino. Как мога да заменя този подход в цикъла на Arduino за прекъсване и неговата сервизна рутина? Изглежда, че attachInterrupt() не осигурява тази цел. Разчитам на прекъсване, за да събудя Arduino от режим на заспиване.

Разработих този прост код, който трябва да включи светодиод, свързан към пин 13.

    #include <avr/interrupt.h> 
    #include <avr/io.h> 
    void setup()
    {
       pinMode(13, OUTPUT);     //Set pin 13 as output

       UBRR0H = 0;//(BAUD_PRESCALE >> 8); // Load upper 8-bits of the baud rate value into the high byte of the UBRR register 
       UBRR0L = 8; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register 
       UCSR0C |= (1 << UCSZ00) | (1 << UCSZ10); // Use 8-bit character sizes 
       UCSR0B |= (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0);   // Turn on the transmission, reception, and Receive interrupt      
    }

    void loop()
    {
      //Do nothing
    }

    ISR(USART0_RXC_vect)
    {    
      digitalWrite(13, HIGH);   // Turn the LED on          
    }

Проблемът е, че подпрограмата никога не се обслужва.


person beb_lm    schedule 18.04.2012    source източник
comment
Какво общо има въпросът ти с bluetooth? Изглежда, че просто питате как да използвате обикновен UART с прекъсвания?   -  person TJD    schedule 19.04.2012


Отговори (3)


Най-накрая открих моя проблем. Промених вектора на прекъсване "USART0_RXC_vect" от USART0_RX_vect. Също така добавих interrupts();, за да активирам глобалното прекъсване и работи много добре.

Кодът е:

#include <avr/interrupt.h> 
#include <avr/io.h> 
void setup()
{
   pinMode(13, OUTPUT); 

   UBRR0H = 0; // Load upper 8-bits of the baud rate value into the high byte of the UBRR register 
   UBRR0L = 8; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register 
   UCSR0C |= (1 << UCSZ00) | (1 << UCSZ10); // Use 8-bit character sizes 
   UCSR0B |= (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0);   // Turn on the transmission, reception, and Receive interrupt      
   interrupts();
}

void loop()
{

}

ISR(USART0_RX_vect)
{  
  digitalWrite(13, HIGH);   // set the LED on
  delay(1000);              // wait for a second
}

Благодаря за отговорите!!!!

person beb_lm    schedule 19.04.2012
comment
Какво? По никакъв начин не ви е разрешено да извиквате delay вътре в манипулатор на прекъсвания. Обработчиците на прекъсвания трябва да правят възможно най-малко и възможно най-бързо и със сигурност нямат зависимости от това дали други прекъсвания са активирани или не и приоритетите между тях. - person hlovdal; 27.09.2019

Опитахте ли този код и той не работи? Мисля, че проблемът е, че не сте включили прекъсванията. Можете да опитате да извикате sei(); или interrupts(); във вашата setup функция.

person Guan Yang    schedule 18.04.2012

Точно след UBRR0L = 8 вместо това:

 UCSR0C |= (1 << UCSZ00) | (1 << UCSZ01);

промени на това:

 UCSR0C |= (1 << UCSZ00) | (1 << UCSZ10);
person Abdelhalim Zehana    schedule 26.01.2019
comment
Здравей Абделхалим, добре дошъл в SO. Може би също така обмислете да обясните идеята зад кода? Предполагам, че ще подобри много отговора ви. Благодаря все пак за вашия принос :-) - person RomainValeri; 26.01.2019