百度网盘
https://pan.baidu.com/s/1pAMU6Q03_DYojdlX8RNbVQ?pwd=6543
csdn资源
https://download.csdn.net/download/qq_49053936/88515308
正常通讯时,一般只接四线:VCC、GND、TXD、RXD。建议增加STA连接以判断状态。
模块上,集成了一颗蓝色LED,用于显示当前连接状态。
5.4.1 测试指令 AT
5.4.2 查询当前参数 AT+RX
5.4.3 恢复出石设置 AT+DEFAULT
5.4.4 设置主、从模式 AT+ROLE
5.4.5 设置蓝牙名称 AT+NAME
5.4.6 设置波特率 AT+BAUD
5.4.7 清除记忆地址 AT+CLEAR
使用最常用的串口通信接线方式即可。重点:双方的RX、TX反接。
蓝牙 HC-08 模块 | USB转TTL模块 |
---|---|
RXD | TXD |
TXD | RXD |
GND | GND |
VCC | 3.3V 或 5V |
打开任意一款串口软件,如XCOM, SSCOM等等。本笔记中,使用HC的串口助手。
( HC-T 串口助手,已包含在文末网盘的资料包中 。)
6.3.1 在串口助手 下方,输入 AT指令:"AT+RX" ,作用是查询当前通信参数 。
点击发送按钮,可返回上图中信息。
如果没有返回信息,逐一检查下面步骤:
6.3.2 分析返回的信息
本步骤,先不急于测试其它指令用法,等下一步连接成功了,再综合测试。
按上面几个方法,先使用USB转TTL模块、串口软件、APP,测试好连接、通信链路。
两个HC-08,分别与两个STM32开发板连接。
本笔记使用串口3(TX-PB10, RX-PB11)。
当然,没有规定一定要使用串口3, 可自行修改为其它空闲的串口引脚
注意:STM32F103C8,只有串口123, 而RC及以上,才有串口12345.
本篇笔记代码,使用引脚连接,如下表:
蓝牙 HC-08 模块 | STM32 开发板 |
---|---|
RXD | TX-PB10 |
TXD | RX-PB11 |
GND | GND |
VCC | 3.3V |
在程序上,要做两份工程代码,分主机程序、从机程序。
下面所附,是主机程序的main.c文件。
其实,主、从机的配置程序,几乎一样,只是初始化时那行主从模式配置AT指令不同:
其它的配置,是一样的。
而为了在串口助手上方便区别,两者发送的数据testData[ ],做了一点修改。
static uint8_t testData[20]={'1','3','1','4', 1,3,1,4, 0xFF,0xAA}; // 测试用数据; 在串口助手上,前4字节可以在ASCII模式下显示,后6字节要打勾16进制才能显示, 至于原因,请自行百度ASCII
/******************************************************************************
* 函 数: delay_ms
* 功 能: 简单的延时函数
* 参 数: uint32_t _ms 毫秒值
* 返回值: 无
******************************************************************************/
// 简单的延时函数
static void delay_ms(uint32_t _ms) // 定义一个ms延时函数,减少移植时对外部文件依赖; 本函数仅作粗略延时使用,而并非精准延时;
{
_ms *= 10286; // 注意:此参考值运行条件:打勾 Options/ c++ / One ELF Section per Function
for (uint32_t i = 0; i < _ms; i++); // 72MHz系统时钟下,大约多少个空循环耗时1ms
}
/******************************************************************************
* 函 数: USART3_WaitACK
* 功 能: 等待指令返回值 *
* 参 数: char* _ackStr 期待返回的字符串
* uint32_t _timeout 超时值
* 返回值: 0-超时没有返回、
* 1-正常返回期待值
******************************************************************************/
static uint8_t USART3_WaitACK(char* _ackStr, uint32_t _timeout)
{
while (_timeout--) // 判断是否起时(这里只作简单的循环判断次数处理)
{
if (xUSART3.ReceivedNum) // 判断是否接收到数据
{
xUSART3.ReceivedNum = 0; // 清0接收字节数
if (strstr((char *)xUSART3.ReceivedData, _ackStr)) // 判断返回数据中是否有期待的字符
{
return 1; // 返回:0-超时没有返回、1-正常返回期待值
}
}
delay_ms(1); // 延时; 用于超时退出处理,避免死等
}
return 0; // 返回:0-超时没有返回、1-正常返回期待值
}
/******************************************************************************
* 函 数: main
* 功 能: 程序主函数
******************************************************************************/
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // 中断分组,组2:抢占级0~3,子优先级0~3 ; 全局只设置一次,尽量放在显眼的地方
USART1_Init(115200); // 串口1初始化; 用于与串口软件通信,方便代码调试; USART1(115200-N-8-1), 且工程已把printf重定向至USART1输出
Led_Init(); // LED 初始化
LED_BLUE_ON ; // 点亮蓝灯
Key_Init(); // 按键 初始化
delay_ms(160); // 重要延时:HC08在上电或复位后,需要150ms,才能进入工作状态
USART3_Init(9600); // 串口3初始化; 用于与HC08通信;
USART3_SendString("AT+ROLE=M"); // 发送AT+ROLE指令,配置主从模式, 指令参数:S-从机模式、M-主机模式
if(USART3_WaitACK("OK",500)) // 等待返回期待值; 配置类指令返回:执行成功返回"OK"、执行失败不返回任何数据
printf("\r蓝牙HC-08 主从模式配置成功:主机模式\r"); // 输出提示:配置成功
else
printf("\r蓝牙HC-08 配置超时,请检查模块接线、连接状态\r"); // 输出提示:超时没有返回
while (1) // while函数死循环,不能让main函数运行结束,否则会产生硬件错误
{
delay_ms(100); // 间隔延时
USART3_SendData(testData, 15); // 间隔不断地发送数据。提醒:新手需要先行百度, 搞明白ASCII,哪些数值在串口助手用ASCII直接可见,哪些数值需要打勾16进制才能显示。另外注意,这里特意发送15个字节,特意显示数组尾部的乱码数据
// 监察串口:调试串口是否接收到数据,判断处理 // 电脑串口助手发过来的数据
if (xUSART1.ReceivedNum) // 检查调试用的串口,是否收到数据
{
USART3_SendString((char *)xUSART1.ReceivedData); // 把上位机发过来的数据,发送给HC08
printf("\r\n发送数据>>>:%s\r", (char *)xUSART1.ReceivedData); // 把所发送的数据,输出到串口上位机,方便观察
xUSART1.ReceivedNum = 0; // 清空串口的接收标志,避免下次循环重复进入判断
}
// 监察串口:HC08是否接收到数据,判断处理
if (xUSART3.ReceivedNum) // 检查HC08所用的串口,是否收到数据
{
printf("\r\nHC08收到%d字节<<<:\r", xUSART3.ReceivedNum); // 把接收收到的数据,输出到串口上位机,方便观察
printf("%s\r", xUSART3.ReceivedData); // 把接收收到的数据,输出到串口上位机,方便观察
// 判断数据以执行动作
if (strstr((char *)xUSART3.ReceivedData, "LED_ON")) LED_RED_ON; // 判断APP发过来的数据包,是否包含字符串:LED_RED_ON
if (strstr((char *)xUSART3.ReceivedData, "LED_OFF")) LED_RED_OFF; // 判断APP发过来的数据包,是否包含字符串:LED_RED_OFF
if (strstr((char *)xUSART3.ReceivedData, "RELAY_ON")) LED_BLUE_ON; // 判断APP发过来的数据包,是否包含字符串:RELAY_ON
if (strstr((char *)xUSART3.ReceivedData, "RELAY_OFF")) LED_BLUE_OFF; // 判断APP发过来的数据包,是否包含字符串:RELAY_OFF
xUSART3.ReceivedNum = 0; // 清空串口的接收标志,避免下次循环重复进入判断
}
}
}
上面代码中,初始化了两个串口:
USART1_Init(115200); // 与串口助手通信
USART3_Init(9600); // 串口3初始化; 用于与HC08通信;
具体的初始化代码、收发机制代码,使用了魔女开发板家的串口代码,通用所有STM32F103芯片.
已附网盘中。
USART3_SendString("AT+ROLE=M");
直接如普通串口通信般发送即可。
切记,如果发送AT指令,只有在未连接状态才生效。
AT指令,大写,无需像8266那样加换行。
如果已经处在连接状态(蓝灯长亮),所有发送的AT指令、数据,都会直接发送给对方。
if (xUSART3.ReceivedNum) // 检查HC08所用的串口是否收到数据
{
printf("\r\nHC08收到%d字节<<<:\r", xUSART3.ReceivedNum); // 把接收收到的数据,输出到串口上位机,方便观察
printf("%s\r", xUSART3.ReceivedData); // 把接收收到的数据,输出到串口上位机,方便观察
// 判断数据以执行动作
if (strstr((char *)xUSART3.ReceivedData, "LED_ON")) LED_RED_ON; // 判断APP发过来的数据包,是否包含字符串:LED_RED_ON
if (strstr((char *)xUSART3.ReceivedData, "LED_OFF")) LED_RED_OFF; // 判断APP发过来的数据包,是否包含字符串:LED_RED_OFF
if (strstr((char *)xUSART3.ReceivedData, "RELAY_ON")) LED_BLUE_ON; // 判断APP发过来的数据包,是否包含字符串:LED_BLUE_ON
if (strstr((char *)xUSART3.ReceivedData, "RELAY_OFF")) LED_BLUE_OFF; // 判断APP发过来的数据包,是否包含字符串:LED_BLUE_OFF
xUSART3.ReceivedNum = 0; // 清空串口1的接收标志
}
主、从机程序,分别烧录到两个STM32F103开发板。
打开两个串口助手,即可观察到相互间的通信。