Arduino外部中断使用问题,求助
本帖最后由 lilin16821 于 2014-7-1 17:41 编辑采用Arduino UNO制作一个温湿度采集并按照一定逻辑控制外部继电器动作的应用,采集到的温湿度要保存到本地的TF卡上,同时要上传至网络。
因为需要时间戳,所以增加了SD2405时钟模块,考虑到SD2405有比较灵活的中断输出,可以给主控板UNO提供稳定的外部中断,于是决定用中断来控制采样的上传,比如每间隔5分钟采用上传一次。
SD2405提供时钟查询和中断脉冲,中断信号接到了Arduino的D2口,并且编写了中断处理函数int0_ISR()
setup()中挂接了中断处理:attachInterrupt(0,int0_ISR,FALLING);(中断号0,下降沿触发)
目前还没有实际去接传感器,为测试中断工作在loop()中,每隔1秒去取时钟信息并串口打印,中断处理函数如果也去取时钟信息,运行必死。
后来简化处理,中断中只是串口打印中断次数计数器值,并且随意取了两个模拟口的值(没有接设备,值应该是随机的),此时,程序可以运行,但是跑不了几个中断就会死掉。
请教:外部中断应该怎么用,我的问题在哪里?
代码如下:
#include <Wire.h>
#define RTC_Address 0x32//RTC_Address
unsigned char date;
unsigned int intNum = 0;
void int0_ISR(void)
{
digitalWrite(13, HIGH);
Serial.print("IntNum: ");
Serial.print(intNum++);
Serial.println(" Int......");
Serial.print("A0 ");
Serial.println(analogRead(0));
Serial.print("A1 ");
Serial.println(analogRead(1));
//Read time from SD2405 and show in serial
//I2CReadDate();
//Data_process();
//如果上面两句不注释掉,必死机。
}
void setup()
{
Wire.begin();//Open I2C as maste
Serial.begin(9600);
pinMode(13, OUTPUT);
Serial.println("Start...");
attachInterrupt(0,int0_ISR,FALLING);
}
void loop()
{
I2CReadDate(); //Read time
Data_process(); //Show time
delay(1000);
}
//Read the Real-time data register of SD2405
void I2CReadDate(void)
{
unsigned char n=0;
Wire.requestFrom(RTC_Address,7);
while(Wire.available())
{
date=Wire.read();
}
delayMicroseconds(1);
Wire.endTransmission();
}
//Process the time_data
void Data_process(void)
{
unsigned char i;
for(i=0;i<7;i++)
{
if(i!=2)
date=(((date&0xf0)>>4)*10)+(date&0x0f);
else
{
date=(date&0x7f);
date=(((date&0xf0)>>4)*10)+(date&0x0f);
}
}
// Use the serial monitor to see information being transmitted
Serial.print("Sec = ");//second
Serial.print(date);
Serial.print(" Min = ");//minute
Serial.print(date);
Serial.print(" H = ");//hour
Serial.print(date);
Serial.print(" W = ");//week
Serial.print(date);
Serial.print(" D = ");//day
Serial.print(date);
Serial.print(" M = ");//month
Serial.print(date);
Serial.print(" Y = ");//year
Serial.print(date);
Serial.println();
}
中断程序里面不要放print之类的语句,也就是不要进行复杂的操作,不然很容易会卡死的,一般在中断程序里面设定标志位,然后在主程序里面进行判断,再进行相应的操作。因此,按照你的程序,很容易出现卡死等状况。 Youyou 发表于 2014-7-3 13:01
中断程序里面不要放print之类的语句,也就是不要进行复杂的操作,不然很容易会卡死的,一般在中断程序里面 ...
如果中断中只是设置标志位,在我看来中断的意义就不是特别大了,因为对标志位的判读还是要在主循环中进行,不一定能实现及时处理。 本帖最后由 Angelo 于 2014-7-6 21:13 编辑
具体的原因是这个:
Serial串口的类里面有个用于发送的BUFFER,这个BUFFER大小是有限的。
当在运行Serial.print函数的时候,会做一个判断:如果发现Buffer已经满了,程序就会挂死在那边,等待串口发送完数据。
这时就有很痛苦的事情发生了,串口发送数据是基于中断的,它会在中断服务程序中读取Buffer中的值然后发送,
但是此时Serial.print却在中段中挂死了,串口中断服务程序无法进入,于是再也不会发送数据,程序就卡在那里了
其实不用设置标志位也可以,但是最好不要在中断中使用串口发送数据,毕竟串口发送只是调试的目的,实时性不需要很高。
可以读完RTC之后在主程序里面使用串口。
或者可以直接黑掉Serial.write函数,当发现buffer满了,直接return,但是这样就会丢失数据,不太推荐
页:
[1]