GD32 蓝牙模块调试

GD32 蓝牙模块调试记录

本篇博文介绍一下PB-03F蓝牙模组与GD32通信的调试过程。

蓝牙模块介绍

PB-03 是由深圳市安信可科技有限公司开发的蓝牙块。该模块核心处理器芯片PHY6252(SSOP24)是一款高集成度的低功耗蓝牙系统级芯片(SoC),专为物联网(IoT)、移动设备、可穿戴电子设备、智能家居等各种应用而设计。

PHY6252(SSOP24)芯片具有行业领先的低功耗性能和射频性能,支持蓝牙 BLE 5.2。芯片内置64 KB SRAM,256KB fash,96 KB ROM,256bitefse。芯片支持多种低功耗工作状态,能够满足各种应用场景的功耗需求。射频输出功率可调节功能等特性,可以实现通信距离、通信速率和功耗之间的最佳平衡。

PB-03 模块提供丰富的外设接口,包括 UART,PWM,ADC,I2C,SPIPDM,DMA 和多达 19个 I0 口。

PB-03 模块具有多种特有的硬件安全机制。硬件加密加速器支持 AES 算法。

PB-03 模块支持低功耗蓝牙:Bluetooth5.2,Bluetoothmesh。蓝牙速率支持:125Kbps,500Kbps,1Mbps,2Mbps。支持广播扩展,多广播,信道选择。

芯片硬件连接

PB-03得管脚功能定义如下图所示,芯片供电3.3V,然后通过串口与MCU进行通信。

注意:需要在TX&RX串口线路上,预留2个电阻,串联在线路中。用于防止串口自带的3.3V电压会影响到模组的复位。

程序

基本AT指令

基本AT指令,本博文就介绍几个常用的指令,有其需要可以参考《pb系列模组通用at_v1006版本指令_v1.1.3

1、AT+BLEMODE 查询和设置蓝牙模式

bash 复制代码
AT+RST
AT+BLEMODE?
AT+BLEMODE=9
AT+BLEMODE?
AT+BLEMODE=0
AT+BLEMODE?

2、AT+BLESTATE 查询连接状态


未连接

已连接
模块反馈
断开连接

从机指令

1、设置蓝牙名称

bash 复制代码
AT+RST
AT+BLENAME?
AT+BLENAME=GW7001
AT+RST
AT+BLENAME?

2、AT+BLESERUUID 查询或者设置服务 UUID

bash 复制代码
AT+RST
AT+BLESERUUID?
AT+BLESERUUID=55535343fe7d50010000120230500001
AT+BLEMODE=0
AT+BLESERUUID?
更改UUID前
更改查询操作
更改UUID后

3、 AT+BLEAUTH 查询或设置蓝牙配对码

bash 复制代码
AT+RST
AT+BLEAUTH?
AT+BLEAUTH=123456
AT+BLEAUTH?

GD32程序

配置

1、读写
c 复制代码
static uint8_t Proto_BLE_Cmd(char* str, const char *ExpRcvStr, uint32_t timeOutMs)
{
	uint8_t i, buf[100], length=0;
	do
	{
		uint8_t tmpbuf[32];
		if(0 == drv_usart_read(BLE_COM , tmpbuf, 32, 10))
		{
			break;
		}
	}while(1);//串口读空
	
	for(i=0; i<1; i++)
	{
		if(drv_usart_write(BLE_COM, (uint8_t*)str, strlen(str), 10))
		{
			memset(buf,0,sizeof(buf));
			length = drv_usart_read(BLE_COM, buf, 100, timeOutMs);
			if((length)&&(length<100))
			{
				if(strstr((char *)buf, ExpRcvStr) !=NULL)
				{
					return 1;
				}
			}
		}
	}
	return 0;
}
2、配置流程
c 复制代码
/**
 * @brief  蓝牙模块初始化
 * @param  pName 蓝牙名称
 * @retval 
 */
uint8_t Proto_ble_init(uint8_t *pName, uint32_t pPin)
{
	static uint8_t init_step = 0, recount = 0, reSetCnt = 0;
	static uint32_t waitConnect = 0;
	char cmd[128];
	
	if(recount>5)
	{
		init_step++;
	}
	switch(init_step)
	{
		case 0:	//进入AT命令模式并确保成功
		{
			Proto_BLE_Cmd("+++", "OK\r\n", 200);
			//osDelay(1000);
			//Proto_BLE_Cmd("ATE1\r\n", "OK\r\n", 200);//关闭回显
			recount   = 0;
			init_step = 2;
			break;	
		}
		case 1:	//进入AT命令模式并确保成功
		{
			recount++;
			if(1 == Proto_BLE_Cmd("AT+BLEDISCON\r\n", "OK\r\n", 200))//重连时确保断开了连接
			{
				recount   = 0;
				init_step = 2;
			}
			break;
		}
		case 2:	//进入AT命令模式并确保成功
		{
			recount++;
			if(1 == Proto_BLE_Cmd("AT\r\n", "OK\r\n", 200))
			{
				recount   = 0;
				init_step = 3;
			}
			break;
		}
		case 3:	//设置从机模式
		{
			recount++;
			if(1 == Proto_BLE_Cmd("AT+BLEMODE=0\r\n", "OK\r\n", 200))
			{
				recount   = 0;
				init_step = 4;
			}
			break;
		}
		case 4:	//设置名称
		{
			recount++;
			sprintf(cmd, "AT+BLENAME=%s\r\n\r\n", pName);
			if(1 == Proto_BLE_Cmd(cmd, "OK\r\n", 200))
			{
				recount   = 0;
				init_step = 5;
			}
			break;
		}
		case 5:	//设置配对码
		{
			recount++;
			sprintf(cmd, "AT+BLEAUTH=%d\r\n", pPin);
			if(1 == Proto_BLE_Cmd(cmd, "OK\r\n", 200))
			{
				recount   = 0;
				init_step = 6;
			}
			break;
		}
		case 6:	//确认蓝牙是否连接
		{
			recount++;
			if(1 == Proto_BLE_Cmd("AT+BLESTATE?\r\n", "OK\r\n", 200))
			{
				recount   = 0;
				init_step = 7;
			}
			break;
		}
		case 7:	//进入透传模式
		{
			uint8_t buf[100], length=0;
			memset(buf,0,sizeof(buf));
			length = drv_usart_read(BLE_COM, buf, 100, 200);
			if((length)&&(length<100))
			{
				if(strstr((char *)buf, "+EVENT:BLE_CONNECTED") != NULL)
				{
					recount   = 0;
					init_step = 0;
					reSetCnt  = 0;
					waitConnect = 0;
					return 1;
				}
			}
			else
			{
				waitConnect++;
				//1-上电1分钟重设一次,再连不上5分钟重设一次,再连不上10分钟重设一次,最后还是连不上就等待连接或者手动下电尝试/每15分钟重设一次
				if((0 == reSetCnt)&&(waitConnect>(60000/500)))	//500ms周期 60000/500
				{
					recount   = 0;
					init_step = 0;
					reSetCnt  = 1;
					waitConnect = 0;
				}
				else if((1 == reSetCnt)&&(waitConnect>(5*60000/500)))	//500ms周期 5*60000/500
				{
					recount   = 0;
					init_step = 0;
					reSetCnt  = 2;
					waitConnect = 0;		
				}
				else if((2 == reSetCnt)&&(waitConnect>(15*60000/500)))	//500ms周期 15*60000/500
				{
					recount   = 0;
					init_step = 0;
					reSetCnt  = 3;
					waitConnect = 0;
				}		
			}
			break;
		}
		default:
		{
			recount   = 0;
			init_step = 0;
			waitConnect = 0;
			break;
		}
	}
	osDelay(300);	/* AT指令之间时间定位500ms, 后续再优化重连时间 */
	return 0;
}
 
3、调用配置
c 复制代码
				if(1==Proto_ble_init((uint8_t *)"GWDC7000", 123456))
				{
					bleLoginStatus = 2;
				}

蓝牙连接

根据我们前面从机命令介绍的反馈,调试助手接收到的连接状态返回,蓝牙模块就进入了连接状态。所以判断连接如下:

c 复制代码
				memset(rcvBuf, 0, sizeof(rcvBuf));
				rdvLen = Proto_ble_recv(rcvBuf, 100, 100);
				if(rdvLen>0)
				{
					if(strstr((char *)rcvBuf, "+EVENT:BLE_CONNECTED") != NULL)
					{
						bleLoginStatus = 2;
					}
				}

断开连接

同理,断开连接判断

c 复制代码
				if(Tick_Out(&heartbeatMs, 1000))	//10s周期发送数据 -  后续再完善心跳超时 重连机制
				{
					Tick_Out(&heartbeatMs, TICK_OUT_RESTART);
					Proto_ble_send((uint8_t*) "TEST MSG FROM DC7000", strlen("TEST MSG FROM DC7000"), 100);
				}
				memset(rcvBuf, 0, sizeof(rcvBuf));
				rdvLen = Proto_ble_recv(rcvBuf, 100, 100); //根据协议最长字节确定接收长度
				if(rdvLen>0)
				{
					if(strstr((char *)rcvBuf, "+EVENT:BLE_DISCONNECT") !=NULL)
					{
						bleLoginStatus = 1;
					}
					Proto_ble_send((uint8_t*) rcvBuf, rdvLen, 100);
				}

蓝牙通信任务

c 复制代码
/**
 * @brief  蓝牙通信任务
 * @param  无
 * @retval 无
 */
void BLE_Com_Thread(void const * argument)
{
	static uint32_t heartbeatMs = 0;
	uint8_t rdvLen = 0;
	uint8_t rcvBuf[128];
	
	for( ; ; )
	{
		switch(bleLoginStatus)
		{
			case 0://配置-等待连接
			{
				if(1==Proto_ble_init((uint8_t *)"GWDC7000", 123456))
				{
					bleLoginStatus = 2;
				}
				break;
			}
			case 1://等待连接 - 考虑后续再等待一定时间后重新配置
			{
				memset(rcvBuf, 0, sizeof(rcvBuf));
				rdvLen = Proto_ble_recv(rcvBuf, 100, 100);
				if(rdvLen>0)
				{
					if(strstr((char *)rcvBuf, "+EVENT:BLE_CONNECTED") != NULL)
					{
						bleLoginStatus = 2;
					}
				}
				break;
			}			
			case 2://通信
			{
				if(Tick_Out(&heartbeatMs, 1000))	//10s周期发送数据 -  后续再完善心跳超时 重连机制
				{
					Tick_Out(&heartbeatMs, TICK_OUT_RESTART);
					Proto_ble_send((uint8_t*) "TEST MSG FROM DC7000", strlen("TEST MSG FROM DC7000"), 100);
				}
				memset(rcvBuf, 0, sizeof(rcvBuf));
				rdvLen = Proto_ble_recv(rcvBuf, 100, 100); //根据协议最长字节确定接收长度
				if(rdvLen>0)
				{
					if(strstr((char *)rcvBuf, "+EVENT:BLE_DISCONNECT") !=NULL)
					{
						bleLoginStatus = 1;
					}
					Proto_ble_send((uint8_t*) rcvBuf, rdvLen, 100);
				}
				break;
			}
			default:break;			
		}
       osDelay(50);
	}
    
}

运行结果

上位机测试
上位机接收数据
上位机发送数据
蓝牙模块接收透传给MCU

总结

本博文记录了PB-03蓝牙模块调试开发过程。实际调试过程中,和资料文档中的描述稍有差入。可能是固件版本的不一样。该模块还支持二次开发,提供二次开发SDK和文档, 有兴趣的同学可以学习尝试。

参考安可信官网资料

官方官网:https://www.ai-thinker.com

开发资料:https://docs.ai-thinker.com

官方论坛:http://bbs.ai-thinker.com

相关推荐
moringlightyn1 小时前
Linux---基础IO(文件理解 文件接口使用 文件系统层面)
linux·运维·服务器·c语言·笔记·系统·文件
Miuney_MAX9 小时前
【单片机】之HC32F460中断向量选择
单片机·嵌入式硬件
了一梨9 小时前
在Ubuntu中配置适配泰山派的交叉编译环境
linux·c语言·ubuntu
CQ_YM9 小时前
数据结构之单向链表
c语言·数据结构·链表
亦是远方11 小时前
南京邮电大学使用计算机求解问题实验一(C语言简单编程练习)
c语言·开发语言·实验报告·南京邮电大学
Gomiko12 小时前
C/C++基础(四):运算符
c语言·c++
wadesir13 小时前
C语言模块化设计入门指南(从零开始构建清晰可维护的C程序)
c语言·开发语言·算法
赖small强13 小时前
【Linux C/C++开发】 GCC -g 调试参数深度解析与最佳实践
linux·c语言·c++·gdb·-g
猫猫的小茶馆14 小时前
【ARM】ARM的介绍
c语言·开发语言·arm开发·stm32·单片机·嵌入式硬件·物联网