問題:
在使用zigbee模塊時,使用串口作為無線收發(fā)的載體,與stm32通信,使用DHT11作為簡單的受控源,出現(xiàn)了bug:
當(dāng)在while(1)里使用delay函數(shù),或者使用DHT11_Read_Data函數(shù)時,程序無法進入串口接收中斷,無法使用遠程控制
其中的while函數(shù)為:
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); }
解決思路:
一、常規(guī)檢查
檢查接線之后,我首先想到的是可能數(shù)據(jù)量過大無法進入中斷,或者是某一步出錯,使用STlink debug后,發(fā)現(xiàn)程序一直在主函數(shù)里,沒有進入串口接收中斷
二、延時函數(shù)
隨后我仔細排查函數(shù)體,發(fā)現(xiàn)DHT11_Read_Data 或者其他函數(shù)體內(nèi),都存在延時函數(shù),在之前的學(xué)習(xí)開發(fā)中,也遇到過因為滴答定時器優(yōu)先級問題而出現(xiàn)的奇怪bug,嘗試使用簡單的軟件延時代替:
//粗延時函數(shù),微秒 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;//清空計數(shù)器 SysTick->CTRL=0X01;//使能,減到零是無動作,采用外部時鐘源 do { ?temp=SysTick->CTRL;//讀取當(dāng)前倒計數(shù)值 }while((temp&0x01)&&(!(temp&(1<<16))));//等待時間到達 ? ? SysTick->CTRL=0x00; //關(guān)閉計數(shù)器 ? ?SysTick->VAL =0X00; //清空計數(shù)器 } void delay_ms(u16 nms) { u32 temp; SysTick->LOAD = 9000*nms; SysTick->VAL=0X00;//清空計數(shù)器 SysTick->CTRL=0X01;//使能,減到零是無動作,采用外部時鐘源 do { ?temp=SysTick->CTRL;//讀取當(dāng)前倒計數(shù)值 }while((temp&0x01)&&(!(temp&(1<<16))));//等待時間到達 ? ?SysTick->CTRL=0x00; //關(guān)閉計數(shù)器 ? ?SysTick->VAL =0X00; //清空計數(shù)器 ? }
三、串口處理函數(shù)
經(jīng)過以上調(diào)試后,我開始注意到串口處理函數(shù):bufFun
原本的想法是把它放在主函數(shù)里,讀取數(shù)據(jù)幀,然后用來判斷命令
void bufFun(void){//數(shù)據(jù)幀接收 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)//數(shù)據(jù)幀接收完成 { USARTReceFullFlag = 1; } dataProcess(); } void dataProcess(void){//數(shù)據(jù)幀處理 if(USARTReceFullFlag) { //處理 //USART_Send_Str(databuf,maxSizebuf); func(); //清空 USARTReceFullFlag = 0; USARTReceIn = 0; memset(databuf,0x00,sizeof(udata)); } }
但是此處邏輯出現(xiàn)問題:
讀取數(shù)據(jù)幀的前提是,串口接收中斷成功接收一組數(shù)據(jù)幀,同時,while(1)里運行到bufFun,才可以識別一幀數(shù)據(jù)
但是當(dāng)有延時,或者while中出現(xiàn)大量代碼時,可能會出現(xiàn),數(shù)據(jù)已經(jīng)接收好,但是程序還沒有運行到讀取位,出現(xiàn)bug
嘗試修改為在USART2_IRQHandler中運行bufFun:文章來源:http://www.zghlxwxcb.cn/news/detail-658542.html
問題解決文章來源地址http://www.zghlxwxcb.cn/news/detail-658542.html
到了這里,關(guān)于解決STM32在延時時無法進入中斷的問題的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!