HC-05是一款不需要了解藍芽通訊知識 便能應用在微控制器上的模組,此文章將大概敘述如何應用HC-05實現手機控制微控制器
以下是本篇文章正文內容
HC-05共有六個引腳,分別為VCC、GND、Tx、Rx、LED和KEY。
LED : 藍芽連線狀態指示,快閃表示沒有藍芽連線,慢閃表示進入AT模式,雙閃表示藍芽已連線並開啟了埠
KEY : 用於進入AT偵錯狀態:高電平有效(懸空預設為低電平),在應用中,該引腳應該受微控制器的引腳控制,當微控制器的引腳有上拉電阻式,可以直接接KEY引腳,如果沒有,就要像VCC引腳一樣,通過一個三極體間接控制
Rx : 與微控制器的Tx引腳相連。
Tx :與微控制器的Rx引腳相連。
VCC接5V GND接地。
純屬本小白個人理解
HC-05作為一個模組,將他與微控制器相連之後微控制器就變成了一個擁有藍芽功能的機器,它可以將藍芽收發資料的複雜完全隱蔽,轉化為較為簡單的串列埠通訊,通過微控制器與它的串列埠通訊,使得我們的微控制器看起來擁有了藍芽通訊功能。實際使用中我們完全不必瞭解複雜的藍芽協定,只需要瞭解如何與該模組進行串列埠通訊即可。
這裡VCC、GND連線到相應IO口即可
Rx選擇連線PA2
Tx選擇連線PA3
KEY選擇連線PC4
LED選擇連線PA4
PA2與PA3對應的是串列埠2的傳送埠與接收埠
因此我們採用串列埠2進行資料的傳送與接收
這裡我給出白嫖的程式碼片段
void u2_printf(char* fmt,...)
{
va_list ap;
va_start(ap,fmt);
vsprintf((char*)USART2_TX_BUF,fmt,ap);
va_end(ap);
while(DMA_GetCurrDataCounter(DMA1_Channel7)!=0);
UART_DMA_Enable(DMA1_Channel7,strlen((const char*)USART2_TX_BUF)); //通過DMA傳送
}
va_list為一種引數形式 追根溯源,其型別還是char
va_start()函數可以找到fmt這個字串中對應ap所代表的多個引數的地址。
va_end()函數為清空ap這個參數列
這裡有兩個知識點
1.vsprintf()函數的使用
vsprintf()函數:將可變參數列的格式化資料寫入字串
舉例:int vsprintf (char * s, const char * format, va_list arg );
對於這個語句,其作用為 運用va_list型別的指標arg將format所代表的一堆不確定長度以及型別的字串載入到大字串s中。
同時可以拓展一下sprintf()函數,這兩個函數的應用類似
sprintf()函數:將一個格式化的字串輸出到一個目的字串中。他與vsprintf()的區別就是前者的入口引數可以多個,但是後者只有三個。
2.DMA通訊:DMA直接翻譯過來為direct memory access就是直接記憶傳輸,不需要cpu的處理,直接用DMA模組傳輸到另一個記憶體上。具體的使用方法可以參考網上的視訊,其實質就是一個串列埠通訊,但其具有不佔用cpu的優點,降低了cpu的工作壓力,提升cpu幸福指數。
這裡為什麼要採用va_等等有關宏的運算,本小白也有一點自己的理解
從u2_printf()這個函數的入口引數可以看到,入口引數的最後部分是個沒有確定個數的引數(省略號代表了可以輸入多個引數),為了達到這個目的,我們需要用到va_list型別的指標,再運用va_start()宏以及vsprintf()函數來確定引數的長度,從而使得我們的函數可以有一個不確定數量的引數入口。
對於這樣的 入口引數不限制個數的 函數,大部分都是使用va_list 、va_start 、va_end來達成這種效果。
這樣做的好處當然非常明顯,對於微控制器的使用過程中,傳輸的資料結構將變得更加多元,不必確定引數型別,可以讓我們的串列埠直接發出類似Vanilla.044這種混合型別的字串。
void TIM4_IRQHandler(void)
{
if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)
{
USART2_RX_STA|=1<<15;
TIM_ClearITPendingBit(TIM4, TIM_IT_Update );
TIM4_Set(0);
}
}
在整個過程中還運用一個定時器4來進行定時器中斷
其作用就是不斷判斷串列埠2傳送的資料有沒有結束,他說一個時間,10ms,沒有再次接收到資料就預設資料傳輸完成了。
這裡我以微控制器傳送資料到手機舉例
給出以下主函數片段
if(sendmask)
{
sprintf((char*)sendbuf,"ALIENTEK HC05 %d\r\n",sendcnt);
LCD_ShowString(30+40,160,200,16,16,sendbuf);
u2_printf("ALIENTEK HC05 %d\r\n",sendcnt);
sendcnt++;
if(sendcnt>99)sendcnt=0;
}
此處sendmask為一個判斷是發出訊息還是暫停發訊息的引數,當其值非零時進入該片段函數。
sprintf()函數將要傳送的資料sendcnt替換綠色程式碼裡的%d然後儲存在char型別的字串sendbuf中
LCD顯示函數顯示sendbuf,u2_printf函數將資料通過串列埠2傳送給藍芽模組從而使資料到達手機。
這裡的資料是從電腦通過串列埠連線傳送給的微控制器,實際使用中可以直接運用微控制器相連的模組所產生的資料,來達到手機與機器互傳資料的目的。
這裡給出一段程式碼
reclen=USART2_RX_STA&0X7FFF;
USART2_RX_BUF[reclen]=0;
if(reclen==9||reclen==8)
{
if(strcmp((const char*)USART2_RX_BUF,"+LED1 ON")==0)LED1=0;
if(strcmp((const char*)USART2_RX_BUF,"+LED1 OFF")==0)LED1=1;
}
這裡reclen為判斷接受到的資料長度,如果長度等於9或者等於8,則再進行判斷是否為+LED ON或者+LED OFF,從而控制LED的亮與滅。
實際應用中,可以控制任何你想控制但是前提是你會控制的IO口或者模組。
AT狀態可以查詢我們的裝置名稱裝置狀態等等資訊,可以通過AT指令的傳送與接收情況判斷我們的藍芽連線是否成功。
對於HC-05有兩種方式進入AT狀態:
上電同時或者上電之前將KEY接VCC,上電後,模組就進入AT模式。
上電之前KEY並沒有連線VCC,模組上電之後再將key連線VCC,此時就進入了AT模式。
沒有將KEY連線到VCC上之前是連線模式。
OS:第一種方法進入的AT模式波特率為38400,而第二種方法進入的AT模式波特率與通訊波特率一致。
HC-05模組須使用TTL訊號,所以應適當新增USB轉TTL模組。
對於不同的開發板,應該注意介面的數量,我這裡使用的為正點原子的STM32mini板,介面相對充足,而C8T6這種小板子,則需要根據IO口數量合理選擇串列埠以及定時器的使用,尤其是還需要LCD或者OLED 螢幕顯示的時候更應該好好分配。
在學習HC-05的過程讓我更多的瞭解了一部分有關mini板的知識。
對於PA9、PA10這兩個引腳,之所以在這兩個引腳上加跳線帽,是因為Rx與Tx連線到板載的CH340G晶片,並且PA9、PA10對應晶片的串列埠1,通過串列埠1的作用,才使得我們的mini板子可以用USB燒錄程式。
其次還了解了vsprintf()、va_list、va_start()、va_end的大致作用,並大致瞭解瞭如何寫出入口引數不限制個數的函數。
藍芽模組的可用性還是很高的,對外設與微控制器互通提供了更多可能。
本人小白一枚,這些僅僅是我個人的經驗與認知,也許含有多處錯誤,希望讀者給我指正。