12363| 3
|
[常见问题] 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[7]; 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[n++]=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[2]=(date[2]&0x7f); date[2]=(((date[2]&0xf0)>>4)*10)+(date[2]&0x0f); } } // Use the serial monitor to see information being transmitted Serial.print("Sec = ");//second Serial.print(date[0]); Serial.print(" Min = ");//minute Serial.print(date[1]); Serial.print(" H = ");//hour Serial.print(date[2]); Serial.print(" W = ");//week Serial.print(date[3]); Serial.print(" D = ");//day Serial.print(date[4]); Serial.print(" M = ");//month Serial.print(date[5]); Serial.print(" Y = ");//year Serial.print(date[6]); Serial.println(); } |
Youyou 发表于 2014-7-3 13:01 如果中断中只是设置标志位,在我看来中断的意义就不是特别大了,因为对标志位的判读还是要在主循环中进行,不一定能实现及时处理。 |
本帖最后由 Angelo 于 2014-7-6 21:13 编辑 具体的原因是这个: Serial串口的类里面有个用于发送的BUFFER,这个BUFFER大小是有限的。 当在运行Serial.print函数的时候,会做一个判断:如果发现Buffer已经满了,程序就会挂死在那边,等待串口发送完数据。 这时就有很痛苦的事情发生了,串口发送数据是基于中断的,它会在中断服务程序中读取Buffer中的值然后发送, 但是此时Serial.print却在中段中挂死了,串口中断服务程序无法进入,于是再也不会发送数据,程序就卡在那里了 其实不用设置标志位也可以,但是最好不要在中断中使用串口发送数据,毕竟串口发送只是调试的目的,实时性不需要很高。 可以读完RTC之后在主程序里面使用串口。 或者可以直接黑掉Serial.write函数,当发现buffer满了,直接return,但是这样就会丢失数据,不太推荐 |
© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed