问题:
在使用zigbee模块时,使用串口作为无线收发的载体,与stm32通信,使用DHT11作为简单的受控源,出现了bug:
当在while(1)里使用delay函数,或者使用DHT11_Read_Data函数时,程序无法进入串口接收中断,无法使用远程控制
其中的while函数为:
while (1){ DHT11_Read_Data(&temp,&humi);//DHT11读取温度 bufFun(); if(dht11Res){ USART2_SendByte('1'); OLED_ShowNum(1,8,temp,2); temp++; }else{ USART2_SendByte('2'); } delay_ms(1000); }
解决思路:
一、常规检查
检查接线之后,我首先想到的是可能数据量过大无法进入中断,或者是某一步出错,使用STlink debug后,发现程序一直在主函数里,没有进入串口接收中断
二、延时函数
随后我仔细排查函数体,发现DHT11_Read_Data 或者其他函数体内,都存在延时函数,在之前的学习开发中,也遇到过因为滴答定时器优先级问题而出现的奇怪bug,尝试使用简单的软件延时代替:
//粗延时函数,微秒 void delay_us(u16 time) { u16 i=0; while(time--) { i=10; //自己定义 while(i--) ; } } //毫秒级的延时 void delay_ms(u16 time) { u16 i=0; while(time--) { i=12000; //自己定义 while(i--) ; } }
无果后尝试另一种无需中断的硬件延时:
#include "delay.h" void delay_us(u32 nus) { u32 temp; SysTick->LOAD = 9*nus; SysTick->VAL=0X00;//清空计数器 SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源 do { temp=SysTick->CTRL;//读取当前倒计数值 }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达 SysTick->CTRL=0x00; //关闭计数器 SysTick->VAL =0X00; //清空计数器 } void delay_ms(u16 nms) { u32 temp; SysTick->LOAD = 9000*nms; SysTick->VAL=0X00;//清空计数器 SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源 do { temp=SysTick->CTRL;//读取当前倒计数值 }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达 SysTick->CTRL=0x00; //关闭计数器 SysTick->VAL =0X00; //清空计数器 }
三、串口处理函数
经过以上调试后,我开始注意到串口处理函数:bufFun
原本的想法是把它放在主函数里,读取数据帧,然后用来判断命令
void bufFun(void){//数据帧接收 if(res){ switch(USARTReceIn){ case 0: if(udata=='@'){//头 databuf[USARTReceIn++] = udata; } else{ USARTReceIn = 0; } break; default: databuf[USARTReceIn++] = udata; break; } res=0; } if(USARTReceIn >= maxSizebuf)//数据帧接收完成 { USARTReceFullFlag = 1; } dataProcess(); } void dataProcess(void){//数据帧处理 if(USARTReceFullFlag) { //处理 //USART_Send_Str(databuf,maxSizebuf); func(); //清空 USARTReceFullFlag = 0; USARTReceIn = 0; memset(databuf,0x00,sizeof(udata)); } }
但是此处逻辑出现问题:
读取数据帧的前提是,串口接收中断成功接收一组数据帧,同时,while(1)里运行到bufFun,才可以识别一帧数据
但是当有延时,或者while中出现大量代码时,可能会出现,数据已经接收好,但是程序还没有运行到读取位,出现bug
尝试修改为在USART2_IRQHandler中运行bufFun:文章来源:https://www.toymoban.com/news/detail-658542.html
问题解决文章来源地址https://www.toymoban.com/news/detail-658542.html
到了这里,关于解决STM32在延时时无法进入中断的问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!