rt-thread nano stm32f103cbt6 蓝牙模块的通信(有整个工程的代码仓库)
本項目代碼倉庫的網頁:董昊旻/rt_nano_bluetoothhttps://gitee.com/donghaomin/rt_nano_bluetooth
目錄
一,任務來源
二,任務描述
三,代碼編寫思路
(一)數據存儲,刪減
(二)藍牙初始化,藍牙發送過來的數據進行解析
四,總結
一,任務來源
清明節在家呆著無聊就看了一個豬八戒發布的一個簡單的任務,但是不會操作那些程序外包的東西,就把這個任務作為一個練手的小項目,打發一下時間,代碼的思考,撰寫和調試應該花了12個小時,昨天晚上5點到半夜1點(代碼寫到興奮的睡不著覺,在地上站著玩了一個半小時手機才睡著),第二天的早上8點到12點。很大一部分時間花在了調試stm32的引腳,中斷和串口上了,大學畢業之后就沒用過stm32了,也沒用過stm32clubMx,所以學習這個工具花了一點時間。
藍牙模塊我手里沒有,因為長春疫情的原因我也沒辦法買,啥時候疫情結束我也不知道,就對著大夏龍雀的藍牙文檔盲寫了。
硬件如下
二,任務描述
下邊這個圖就是他發布的任務,這個東西仁者見仁智者見智,我感覺難度還行,就是比較費時間。
三,代碼編寫思路
這個要是我大學的時候寫,也就是三個小時之內,現在至少需要20個小時,哈哈。不是能力下降了,就是思考的問題不一樣了。大學的時候一切以能用主義,寫上去能用就OK,現在開始思考代碼的可讀性,可維護性,穩定性等等...
言歸正傳,既然思考的問題不一樣,所以我們就先分割一下這個項目的功能。
1.帶id的數據存儲,還可以刪除數據(我的理解是不用存儲到norflash上,暫存到sram即可)
2.一個下降沿中斷的GPIO
3.一路串口(我用的是UART2)
這個是硬件上的基礎需求,然后我們聊一下軟件的代碼邏輯:
(一)數據存儲,刪減
我沒有采取鏈表的結構來存儲數據,第一是沒必要這么復雜,它只要幾十個數據用不了那么多,寫著也麻煩。我就用一個機構體存儲了溫度數據和連接狀態。DATA_SUM是40,這么一寫的話就能存儲40條數據了,還能存儲藍牙硬件初始化的完成狀況和藍牙連接的狀態。
數據增加,你一按動按鍵的時候就將中斷中的flag置1,在主循環的while(1)將數據加進去一個結構體中,將結構體中的useDataCount加一,超出40就報錯,讓他清空。
刪除的話就更簡單了,直接讓這個大結構體memset為0,就OK了。
typedef enum UsrState {DATA_UN_USED_Sta = 0x00, // 溫度值不正確(不存在)DATA_USED_Sta = 0x01, // 溫度值正確(存在)DATA_SUM_Sta }usrsta;typedef struct D_USR_DATA{unsigned char id; // 計數標簽float value; // 溫度值usrsta state; // 狀態值,溫度值是否正確 }d_data;typedef struct Dong_BLUE_TEMP{unsigned int blueTooth_state; // 藍牙啟動的狀態位unsigned int blueTooth_connect_state; // 藍牙連接的狀態位,是否斷了連接unsigned char usedDataCount; // 當前存儲了多少個溫度數據d_data data[DATA_SUM]; // 溫度數據 }d_bule_temp;(二)藍牙初始化,藍牙發送過來的數據進行解析
藍牙模塊初始化:藍牙模塊是通過"AT"指令進行配置的,為了避免有人用沒配置過的藍牙模塊進行連接,所以我們就需要每次初始化的時候初始化,避免出現藍牙模塊配置的問題出現的BUG。
藍牙數據解析:藍牙發過來的數據是串口發送與接收的,我設置串口的緩沖BUFFER為10Byte,對這10Byte進行解析我們就能知道要做的事情。我用一個結構體來存儲這10個Byte。代碼里有注釋,我就不詳細描述了。
有了這個結構體,我們就可以做一個類似于"診斷"的接口,因此代碼運行的邏輯就是,接收到串口的數據,在主函數中判斷結構體的第一個數據really是不是0x01,是0x01的話就判斷function id,在進入到不同得一級分支,在根據sub function id進入到二級分支,再根據datalenght來判斷data的6Byte用了幾個。具體這個6個Byte表達了那些內容就由,二級分支自己決定了。
/*** 一級主功能ID* */ typedef enum FUNCTION_ID {BLUE_TOOTH_IMG = 0x00, // 藍牙信息獲取TEMP_DATA_OPT = 0x01, // 溫度信息獲取,刪除DIAG_CODE_OPT = 0x02, // 診斷IDFUNCTION_ID_SUM // ID總數 }d_function_id;typedef struct Dong_BLUETOOTH_RECIVE_CMD{unsigned char really; // 判斷是否當前有數據(你也可以理解為器件ID),有數據的話就是0x01,沒有就是0x00,也就是說藍牙發送數據的時候第一位必須是0x01d_function_id function_id; // 藍牙接收數據的主功能idunsigned char sub_function_id; // 藍牙接收數據的二級功能idunsigned char datalenght; // 藍牙發送過來的數據長度unsigned char data[6]; // 藍牙發送過來的數據6個byte }d_bule_revcmd;藍牙模塊AT指令的判斷我寫了一個代碼覺得很有趣下邊貼出來,加了一個超時的處理。
// 藍牙狀態運行檢測 errornum bluetooth_AT_OK(void) {errornum ret = DIAG_OK;unsigned int overtime = 0;while(d_revbuffer.really == 0x00) {HAL_UART_Transmit_IT(&huart2,(uint8_t *)AT_OK_ACK,strlen(AT_OK_ACK));rt_thread_mdelay(500);overtime++;if(overtime > OVERTIME_TIMES) {ret = DIAG_OVERTIM_ERR;rt_kprintf("AT_OK time out\n");return ret;}}memcpy(locat_data,&d_revbuffer,sizeof(locat_data));int dong = memcmp(locat_data,AT_OK_ANS,strlen(AT_OK_ANS));if(dong!=0){rt_kprintf("AT False\n");ret = DIAG_BLUE_ERR;}else {rt_kprintf("AT OK\n");ret = DIAG_OK;}return ret; }運行的LOG,用串口模擬藍牙,主機主動發AT,從機在10次請求內發OK,主機就認為藍牙沒問題。
我的代碼結構如下圖:
diag負責分析和處理藍牙接收的串口數據。
bluetooth負責藍牙模塊的初始化,檢測藍牙信號強度,連接狀態等的函數(連接狀態函數我會放到一個一秒周期的task中,連接上了blueTooth_connect_state就置0x01,掉了就0x00),藍牙模塊正不正常的話我就用AT指令測試,能回OK就將blueTooth_connect_state置0x02,不能就0x03,類似于這個意思推之后的邏輯。
hardware就是硬件初始化相關的函數,我初始化了UART2,PC13(LED),PA11(KEY)。
urs_data就是存儲溫度和其他基礎結構體的頭文件,初始化函數。
四,總結
代碼目前還沒寫完,目前處于一個初版本demo的狀況,但是能用!你可以直接把代碼下載下來,用RT Thread Studio編譯下載到你的開發板,你也不用擔心,開發板不兼容,因為我用的是核心板。
總結
以上是生活随笔為你收集整理的rt-thread nano stm32f103cbt6 蓝牙模块的通信(有整个工程的代码仓库)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 为java程序添加字库
- 下一篇: 西门子200smart与台达MS300变