Arduino串口中断

5
我正在开发一个Arduino Mega 2560项目。在Windows 7 PC上,我使用Arduino1.0 IDE。我需要建立一个波特率为115200的串行蓝牙通信。当RX有数据可用时,我需要接收中断。我看到的所有代码都使用“轮询”,即将Serial.available条件放置在Arduino的循环内。如何用中断及其服务例程替换Arduino循环中的这种方法?似乎attachInterrupt()不能提供此目的。我依赖于中断来唤醒Arduino从睡眠模式中醒来。
我已经开发了这个简单的代码,它应该打开连接到13号引脚的LED灯。
    #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          
    }

问题在于子程序从未被调用。

你的问题与蓝牙有什么关系?看起来你只是在问如何使用带中断的常规UART? - TJD
3个回答

7

最终我找到了问题所在。我将中断向量“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
}

感谢回复!!!

什么?绝对不允许在中断处理程序中调用delay。中断处理程序应该尽可能少地执行操作,并且尽可能快地完成,最重要的是不应该依赖于其他中断是否启用以及它们之间的优先级。 - hlovdal
当然可以在中断处理程序中延迟!这并不会破坏设备或任何东西。是的,这不是一个好的实践。如果你正在编写生产代码和重要的设备,那么它确实很重要。没有什么能阻止任何人定义一个中断处理程序,使整个系统等待几秒钟甚至几天,或者干脆锁定系统。尽管如此,我同意在中断处理程序中放置非时间关键代码不是一个好的做法。 - Jani Kärkkäinen

2

您尝试过该代码,但它没有起作用吗?我认为问题在于您没有开启中断。您可以尝试在setup函数中调用sei();interrupts();


-1

在执行UBRR0L = 8之后,不要这样做:

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

改成这样:

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

嗨,Abdelhalim,欢迎来到SO。也许考虑解释一下代码背后的思想?我猜这会大大改善你的答案。无论如何,感谢你的贡献 :-) - Romain Valeri

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接