STM32+USART+藍芽模組(BT04)
阿新 • • 發佈:2020-07-22
硬體:正點原子戰艦V3
藍芽模組BT04(HC-05也一樣的,不過指令不一樣)
USB轉TTL模組
軟體:XCOM串列埠除錯助手(PC)
藍芽除錯寶(安卓平臺)
昨晚除錯藍芽模組,這個藍芽模組因為只需要連線串列埠就可以正常工作,應該來說比較簡單。但是還是遇到一個小問題,找了很久的原因,除錯了很長時間。
我想要測試的功能是利用手機APP傳送命令控制LED燈,下面是主函式:
int main(void) { u16 t; u16 len; u16 times=0; delay_init(); LED_Init(); KEY_Init(); USART_Config(); while(1) { if(USART_RX_STA&0x8000) { switch(USART_RX_BUF[0]) { case('A'): Send_data(DEBUG_USARTx,"首位為A,LED1亮\r\n"); LED0=1; LED1=0; break; case('B'): Send_data(DEBUG_USARTx,"首位為B,LED0亮\r\n"); LED0=0; LED1=1; break; } USART_RX_STA=0; } } }
我的想法是,命令中第一位字元為“A”則LED1亮,LED0滅,第一位字元為B則相反。
這裡我用的是中斷接收函式,我最開始使用的是正點原子一樣的函式直接搬過來,使用PC端的串列埠除錯助手使用USB轉TTL模組除錯可以正常工作,但是當我利用藍芽模組連線到手機發送命令無法正常工作,下面是正點原子的中斷服務函式:
void DEBUG_USART_IRQHandler(void) //串列埠1中斷服務程式 { u8 Res; if(USART_GetITStatus(DEBUG_USARTx, USART_IT_RXNE) != RESET) //接收中斷(接收到的資料必須是0x0d 0x0a結尾) { Res =USART_ReceiveData(DEBUG_USARTx); //讀取接收到的資料 if((USART_RX_STA&0x8000)==0)//接收未完成 { if(USART_RX_STA&0x4000)//接收到了0x0d { if(Res!='D')USART_RX_STA=0;//接收錯誤,重新開始 else {USART_RX_STA|=0x8000;//接收完成了 Send_data(DEBUG_USARTx,"完成一次傳輸\r\n"); } } else //還沒收到0X0D { if(Res=='+')USART_RX_STA|=0x8000; else { Send_data(DEBUG_USARTx,"寫入緩衝\r\n"); USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ; USART_RX_STA++; if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收資料錯誤,重新開始接收 } } } } }
後來找了很多原因也找不到,最後發現是因為這個中斷函式接受的資料要求0x0a 0x0d結束,電腦串列埠助手傳送新行會發送這兩個字元,但是按說換行符只有一個0x0a,沒有0x0d,所以無法接收到正確的命令。感謝這位大哥。
後面改了程式,把示意命令結束的符號設定為“+”,這樣在PC和安卓端都能正常發出命令。
void DEBUG_USART_IRQHandler(void) //串列埠1中斷服務程式 { u8 Res; if(USART_GetITStatus(DEBUG_USARTx, USART_IT_RXNE) != RESET) { Res =USART_ReceiveData(DEBUG_USARTx); //讀取接收到的資料 if((USART_RX_STA&0x8000)==0)//接收未完成 { if(Res=='+')USART_RX_STA|=0x8000; else { // Send_data(DEBUG_USARTx,"寫入緩衝\r\n"); USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ; USART_RX_STA++; if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0; } } } }
後記
在除錯藍芽時,發現有些app不能搜到我這個藍芽模組,試了好幾個才找到這個藍芽除錯寶可以,雖然有廣告,但至少能用TAT.