前言 注意看 !
如果朋友們遇到了如下問(wèn)題,可以仔細(xì)借鑒本文章和另一篇專門講解藍(lán)牙通信問(wèn)題的文章,一定能夠解決你在藍(lán)牙通信時(shí)遇到的諸多困難
1.在調(diào)試藍(lán)牙模塊AT指令時(shí)無(wú)返回值
2.身邊無(wú)USB轉(zhuǎn)TTL模塊可以直接調(diào)試藍(lán)牙模塊(本人就是由于無(wú)模塊花了了整整一天才調(diào)試成功)
3.在調(diào)試藍(lán)牙模塊AT指令時(shí)存在諸多異常
(1)上位機(jī)接收數(shù)據(jù)時(shí)亂碼
(2)卡死在數(shù)據(jù)接受中斷當(dāng)中,導(dǎo)致接受不了數(shù)據(jù)或者一直發(fā)送數(shù)據(jù)等異常情況。
(3)撥動(dòng),或者拔掉數(shù)據(jù)線,會(huì)出現(xiàn)大量的數(shù)據(jù)發(fā)送情況等異常。
如果朋友們只是想了解藍(lán)牙通信過(guò)程或者應(yīng)用思路那這篇文章基本可以滿足入門的朋友。(本文章采用藍(lán)牙模塊為HC-06模塊)
提示:以下是本篇文章正文內(nèi)容,下面案例可供參考
一、藍(lán)牙通信流程
最簡(jiǎn)單實(shí)際的的藍(lán)牙通信過(guò)程就是
單片機(jī)——藍(lán)牙——手機(jī)藍(lán)牙app
藍(lán)牙作為橋梁進(jìn)行單片機(jī)與手機(jī)數(shù)據(jù)的交換
藍(lán)牙就如同一個(gè)無(wú)線的USART一樣,將兩者連接。
二、怎么實(shí)現(xiàn)藍(lán)牙通信
1.了解藍(lán)牙模塊功能
1.引腳功能:
HC-06共有4個(gè)外接引腳分別為RXD(接收數(shù)據(jù)),TXD(發(fā)送數(shù)據(jù))
工作電源3.6-6v,我采用STM32F103C8t6的5V電源口供電。(其余兩個(gè)引腳功能可以自查,如果圖效率也可以不用管)
2.傳輸數(shù)據(jù)格式:數(shù)據(jù)位8位,停止位1位,無(wú)校驗(yàn),無(wú)流控制,除了波特率以外,和基礎(chǔ)USART串口通信設(shè)置基本一致。
2.了解藍(lán)牙通信本質(zhì)
**就是將藍(lán)牙當(dāng)做一個(gè)無(wú)線的額外的串口模塊進(jìn)行單片機(jī)與其他通信源的連接。
而要正確的使用串口,一定要知道的三要素是:
1.波特率 2.串口號(hào) 3.數(shù)據(jù)格式
3.進(jìn)行AT命令調(diào)試
之前說(shuō)過(guò),藍(lán)牙通信的本質(zhì)就是串口通信,那么我們?cè)贏T命令調(diào)試時(shí),也相當(dāng)于串口通信,**電腦發(fā)送調(diào)試命令給單片機(jī),單片機(jī)再發(fā)送給藍(lán)牙,藍(lán)牙再返還命令處理結(jié)果給單片機(jī),單片機(jī)再上傳給電腦。所以需要兩個(gè)USART串口,分別連接電腦與藍(lán)牙。
(有額外的USB轉(zhuǎn)TTL模塊則不需要這么麻煩)
所以,我們需要先編寫串口通信的代碼。
以下是usart.c文件 在其中編寫串口初始化與NVIC中斷管理設(shè)置
(一般都為數(shù)據(jù)接受中斷,當(dāng)某個(gè)串口接收到數(shù)據(jù)時(shí),執(zhí)行中斷服務(wù)函數(shù))
#include "usart.h"
//設(shè)置NVIC中斷管理器
void NVIC_config(USART_TypeDef* USARTx,uint8_t USARTx_IRQn,uint8_t Sub)
{
NVIC_InitTypeDef NVIC_InitStruct; //構(gòu)建NVIC結(jié)構(gòu)體
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中斷優(yōu)先級(jí)分組
NVIC_InitStruct.NVIC_IRQChannel=USARTx_IRQn; //設(shè)置中斷源
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1; //主優(yōu)先級(jí)
NVIC_InitStruct.NVIC_IRQChannelSubPriority=Sub; //子優(yōu)先級(jí)
NVIC_Init(&NVIC_InitStruct);
}
//可以多次調(diào)用,從而初始化多個(gè)USART串口
//利用續(xù)行符來(lái)聲明變量
void usart_config(GPIO_TypeDef* GPIOx, \
uint16_t USART_Pin_RX,uint16_t USART_Pin_TX, \
uint32_t USART_IO_Clock,uint32_t USART_Clock, \
USART_TypeDef* USARTx,uint8_t USARTx_IRQn,uint8_t Sub,uint32_t BaudRate) //對(duì)應(yīng)的GPIO時(shí)鐘與USART的時(shí)鐘
{
GPIO_InitTypeDef GPIO_RXInitStruct; //兩個(gè)Pin 兩個(gè)結(jié)構(gòu)體
GPIO_InitTypeDef GPIO_TXInitStruct;
USART_InitTypeDef USART_InitStruct; //聲明USART初始化結(jié)構(gòu)體
RCC_APB2PeriphClockCmd(USART_IO_Clock , ENABLE); //開IO時(shí)鐘
GPIO_RXInitStruct.GPIO_Pin=USART_Pin_RX;
GPIO_RXInitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING; //設(shè)置為浮空輸入,不需要設(shè)置速度
GPIO_TXInitStruct.GPIO_Pin=USART_Pin_TX;
GPIO_TXInitStruct.GPIO_Mode=GPIO_Mode_AF_PP; //要使用復(fù)用推挽輸出
GPIO_TXInitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOx, &GPIO_RXInitStruct); //加&指明結(jié)構(gòu)體位置
GPIO_Init(GPIOx, &GPIO_TXInitStruct); //初始化USART 所用的 GPIO
if(USARTx_IRQn==USART1_IRQn)
{
RCC_APB2PeriphClockCmd(USART_Clock , ENABLE); //開串口外設(shè)時(shí)鐘
}
if(USARTx_IRQn==USART2_IRQn)
{
RCC_APB1PeriphClockCmd(USART_Clock , ENABLE); //!!!!!!時(shí)鐘線不一樣
}
USART_InitStruct.USART_BaudRate=BaudRate; //B Rate
USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None; //No controlFlow
USART_InitStruct.USART_Mode=USART_Mode_Rx|USART_Mode_Tx; //雙向
USART_InitStruct.USART_Parity=USART_Parity_No; //No Parity 無(wú)校驗(yàn)
USART_InitStruct.USART_StopBits=USART_StopBits_1; //1stop Bit
USART_InitStruct.USART_WordLength=USART_WordLength_8b; //8bit data
USART_Init(USARTx,&USART_InitStruct); //初始化串口結(jié)構(gòu)體
NVIC_config(USARTx,USARTx_IRQn,Sub);
USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE); //使能串口接收中斷
USART_Cmd(USARTx,ENABLE); //使能串口
}
可以看出來(lái)函數(shù)體中的參數(shù)較多,是為了減少編寫的數(shù)次,之后調(diào)用函數(shù)體,輸入對(duì)應(yīng)的參數(shù)即可,注意除了USART1掛載在APB2時(shí)鐘上其他都掛載在APB1上!
代碼執(zhí)行功能如下
NVIC_Init(&NVIC_InitStruct);//初始化NVIC中斷管理器
RCC_APB2PeriphClockCmd(USART_IO_Clock , ENABLE); //開GPIO時(shí)鐘
if(USARTx_IRQn==USART1_IRQn)
RCC_APB2PeriphClockCmd(USART_Clock , ENABLE);//開串口時(shí)鐘
if(USARTx_IRQn==USART2_IRQn)
RCC_APB1PeriphClockCmd(USART_Clock , ENABLE);
USART_Init(USARTx,&USART_InitStruct); //初始化串口結(jié)構(gòu)體
USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE); //使能串口接收中斷
USART_Cmd(USARTx,ENABLE); //使能串口
此時(shí)已經(jīng)配置好了串口,還需要編寫中斷服務(wù)函數(shù),編寫中斷服務(wù)函數(shù)時(shí)要在stm32f10x.it.c文件下編寫(其他問(wèn)題如函數(shù)名,中斷號(hào)可自查)
uint8_t temp1;
uint8_t temp2;
void USART1_IRQHandler(void)
{
if(USART_GetITStatus(USART1,USART_IT_RXNE) != RESET)//判斷中斷位
{
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
temp1 = USART_ReceiveData(USART1); //接收數(shù)據(jù)
usart_sendByte(USART2,temp1);
LED1_TOOGLE; //作為可視信號(hào),亮燈
}
}
void USART2_IRQHandler(void)
{
if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET)//判斷中斷位
{
USART_ClearITPendingBit(USART2, USART_IT_RXNE);
temp2 = USART_ReceiveData(USART2); //接收數(shù)據(jù)
usart_sendByte(USART1,temp2);
LED1_TOOGLE;
}
}
中斷函數(shù)的功能與完整調(diào)試過(guò)程如下:
當(dāng)上PC端發(fā)送調(diào)試命令給USART1時(shí),接受的命令再通過(guò)USART2發(fā)送給藍(lán)牙。
當(dāng)藍(lán)牙接收到調(diào)試命令,反饋出調(diào)試結(jié)果發(fā)送到USART2,接收到的結(jié)果再通過(guò)USART1發(fā)送到PC端。
接線方式:
STM32連接電腦任意端口
藍(lán)牙上電后與STM32連接
藍(lán)牙 RXD: PA2(USART2 TXD)
藍(lán)牙 TXD: PA3(USART2 RXD)
開始調(diào)試
打開串口調(diào)試軟件 設(shè)置波特率,數(shù)據(jù)格式與編寫時(shí)的格式一致,開始調(diào)試可以看到我們發(fā)送出AT后,回得到一個(gè)OK返還信息,說(shuō)明調(diào)試成功,如果沒(méi)有得到返還需要去找出錯(cuò)誤原因。如果需要執(zhí)行其他命令操作,比如修改密碼,藍(lán)牙名稱,可以查找對(duì)應(yīng)的命令表。
4.調(diào)試完成,連接通信
在進(jìn)行正式通信前我們還需要下載一個(gè)藍(lán)牙串口助手這樣才能更簡(jiǎn)單的進(jìn)行數(shù)據(jù)發(fā)送與接受。(要設(shè)置好接收到的數(shù)據(jù)編碼,與發(fā)送出去的數(shù)據(jù)編碼)
通信效果如下。
三、結(jié)尾
藍(lán)牙通信的過(guò)程十分簡(jiǎn)單,可以說(shuō)就是一個(gè)串口通信的過(guò)程,不過(guò)需要一個(gè)調(diào)試命令和連接的階段,不過(guò)藍(lán)牙通信可以說(shuō)是我們?nèi)腴TSTM32的一個(gè)很重要的時(shí)刻,因?yàn)闊o(wú)線操作永遠(yuǎn)比按鍵或者有線操作來(lái)得騷,可以給我們極大的發(fā)揮空間,比如可以遠(yuǎn)程控制LLED亮滅,或者藍(lán)牙小車,遠(yuǎn)程監(jiān)控等等更加高級(jí)的思路就應(yīng)運(yùn)而生。
但是調(diào)試的過(guò)程中遇到困難是不可避免的,打擊和bug層出不窮,希望不是很富裕又想學(xué)STM32的同志們看到這篇文章時(shí),堅(jiān)持的走下去,就像在實(shí)現(xiàn)調(diào)試過(guò)程中,絕大部分人 包括我去詢問(wèn)的B站UP主,和眾多帖吧老哥,都是用了額外的USB轉(zhuǎn)TTL模塊進(jìn)行調(diào)試,不過(guò)我沒(méi)有米,所以才不得不采另辟蹊徑。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-778851.html
謝謝同志們閱讀!文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-778851.html
到了這里,關(guān)于基于STM32F103C8T6的HC-06藍(lán)牙通信的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!