零基础STM32单片机编程入门(三十四) JDY-31蓝牙模块实战含源码

一.概要

JDY-31 蓝牙基于蓝牙3.0 SPP设计,这样可以支持Windows、Linux、android数据透传,工作频段2.4GHZ,调制方式GFSK,最大发射功率8db,最大发射距离30米,支持用户通过AT 命令修改设备名、波特率等指令,方便快捷使用灵活。
从机模式是蓝牙中的一种工作模式,该模式下,蓝牙设备处于连接状态并且接受主设备的控制,JDY-31 蓝牙是工作在从机模式,手机或者电脑作为蓝牙主机。

在这里插入图片描述

在这里插入图片描述

二.JDY-31 蓝牙模块主要性能参数

在这里插入图片描述

模块接口说明:
在这里插入图片描述

在这里插入图片描述

三.JDY-31 蓝牙模块主芯片BK3432内部框图

BK3432芯片是一款高度集成的蓝牙4.2双模式。它集成了高性能RF收发器、基带、ARM9E内核、丰富的功能外设单元、PR支持BLE应用的可编程协议和概要文件。Flash程序内存使其适合自定义应用程序。
BK3432芯片特性:
低功耗2.4GHz收发器
ARM968E核心微处理器集成
160KB可编程闪存用于程序,20KB RAM用于数据
程序码读保护
操作电压从0.9V到3.6V
时钟:16 MHz晶体参考时钟;64MHz数字PLL时钟;32kHz环形振荡器
接口和外围单元:I2C,SPI,双UART,GPIO
多路PWM输出;片上10位通用ADC;真随机数发生器

在这里插入图片描述

JDY-31 蓝牙模块只用了其中的蓝牙跟串口通讯功能。外围STM32单片机通过UART串口跟蓝牙芯片通讯。

四.BK3432参考设计

在这里插入图片描述

五.JDY-31 蓝牙模块与单片机通讯方法

1.与STM32F103板子硬件连接

单片机板子跟JDY-31 蓝牙模块,只需要连接4根线就可以了,除了电源,地,就是串口的收发信号脚,PB6(USART1_TX)接模块的RXD,PB7(USART1_RX)接模块的TXD。
在这里插入图片描述

默认通讯参数:9600波特率,8位数据,1位停止位,无校验。

2.JDY-31 蓝牙模块AT指令介绍

在这里插入图片描述

六.STM32单片机与JDY-31 蓝牙模块通讯实验

1.硬件准备

STLINK接STM32F103C8T6小系统板,STLINK接电脑USB口。

在这里插入图片描述

2.软件工程

打开STM32CubeMX软件,新建工程
在这里插入图片描述
Part Number处输入STM32F103C8,再双击就创建新的工程
在这里插入图片描述
配置下载口引脚
在这里插入图片描述
配置外部晶振引脚
在这里插入图片描述
配置系统主频
在这里插入图片描述
配置USART1,PB6为发送,PB7为接收
在这里插入图片描述

配置USART1中断
在这里插入图片描述

配置工程文件名,保存路径,KEIL5工程输出方式
在这里插入图片描述
生成工程
在这里插入图片描述
用Keil5打开工程
在这里插入图片描述

添加代码
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

3.软件主要代码

串口数据接收相关代码

volatile uint8_t UartRxData;
uint8_t UartTxbuf[1000]={1,2,3,4,5,6,7,8,9,10};
uint8_t UartRxbuf[1024],UartIntRxbuf[1024];
uint16_t UartRxIndex=0,UartRxFlag,UartRxLen=0,UartRxTimer,UartRxOKFlag,UartIntRxLen;

//串口清除
uint8_t UartRecv_Clear(void)
{
	UartRxOKFlag=0;
	UartRxLen=0;
	UartIntRxLen=0;
	UartRxIndex=0;
	return 1;
}


uint8_t Blue_ConnectFlag;//1:连接上,0:断开
//接收标志函数,返回0说明没收据接收,返回1说明有数据收到
uint8_t Uart_RecvFlag(void)
{
		if(UartRxOKFlag==0x55)
		{
			UartRxOKFlag=0;
			UartRxLen=UartIntRxLen;
			memcpy(UartRxbuf,UartIntRxbuf,UartIntRxLen);//把缓冲区的数据,放入需要解析的数组
			UartIntRxLen=0;
			
			if(Blue_ConnectFlag==0)//没连接上,才判断是否有连接信号
			{
				Blue_ConnectFlag = strstr ((const char*)UartRxbuf, "CONNECTED" ) ? 1 : 0;//说明蓝牙跟手机连上
				if(Blue_ConnectFlag)//如果刚连接上,先发送一个HELLOWORLD
				{
					UartRxLen=0;
					HAL_UART_Transmit(&huart1, "HELLOWORLD\r\n", 12,100);
					
				}
			}

			if(Blue_ConnectFlag==1)//连接上了,才判断断开
			{
			Blue_ConnectFlag = strstr ((const char*)UartRxbuf, "+DISC:SUCCESS" ) ? 0 : 1;//说明蓝牙跟手机断开
				
			}
			return 1;
		}
		return 0;
}
//串口2在1字节接收完成回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	
	if(huart==&huart1)//判断是否串口1
	{
		UartRxFlag=0x55;//接收标志置位
		UartIntRxbuf[UartRxIndex]=UartRxData;//数据写入缓冲区
		UartRxIndex++;//记载数目加1
		if(UartRxIndex>=1024)//缓冲区是1024字节,如果存满,归零
		{
			UartRxIndex=0;
		}
		HAL_UART_Receive_IT(&huart1,(unsigned char*)&UartRxData,1);//继续接收下一字节
 }

}

//1ms调用一次,用来判断是否收完一帧
void UART_RecvDealwith(void)
{
	if(UartRxFlag==0x55)
	{
		if(UartIntRxLen<UartRxIndex)//UartIntRxLen小于UartRxIndex,说明有收到新的数据,把接收长度增加
		{
		UartIntRxLen=UartRxIndex;
		}else
		{
			UartRxTimer++;
			if(UartRxTimer>=50)//50ms,等待,没收到新数据,说明已经收完一帧
			{
				UartRxTimer=0;
				UartRxFlag=0;
				UartRxOKFlag=0x55;
				UartRxIndex=0;
			}
		}
	}
}

void SysTick_Handler(void)
{
  /* USER CODE BEGIN SysTick_IRQn 0 */

  /* USER CODE END SysTick_IRQn 0 */
  HAL_IncTick();
  /* USER CODE BEGIN SysTick_IRQn 1 */
	UART_RecvDealwith();
  /* USER CODE END SysTick_IRQn 1 */
}

main函数代码

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();//8M外部晶振,72M系统主频

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();//串口1配置,PB6 发送,PB7 接收,9600波特率
  /* USER CODE BEGIN 2 */
	HAL_UART_Receive_IT(&huart1, (uint8_t *)&UartRxData, 1);//接收中断使能
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
	
	JDY31_AT_Test();//蓝牙AT指令测试
	JDY31_BaudRateSet();//波特率设置,9600
	JDY31_PINRead();//读PIN
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
			
		if(Uart_RecvFlag()==1)//判断串口是否有数据收到
		{
				if(Blue_ConnectFlag)//如果蓝牙已经连接上,把收到的数据发出去
				{
					if(UartRxLen)//判断收到的数据长度有效
					{
						HAL_UART_Transmit(&huart1,UartRxbuf, UartRxLen,100);//发送数据
					}
				}
		}

  }
  /* USER CODE END 3 */
}

JDY-31蓝牙AT指令相关

//对JDY31模块发送AT指令
// cmd 待发送的指令
// ack1,ack2;期待的响应,为NULL表不需响应,两者为或逻辑关系
// time 等待响应时间
//返回1发送成功, 0失败
bool JDY31_Send_AT_Cmd(char *cmd,char *ack1,char *ack2,u32 time)
{ 
    UartRecv_Clear(); //重新接收新的数据包
    JDY31_USART("%s\r\n", cmd);
    if(ack1==0&&ack2==0)     //不需要接收数据
    {
    return true;
    }
    HAL_Delay(time);   //延时
		HAL_Delay(1000);
		if(Uart_RecvFlag()==1)
		{
		UartRxbuf[UartRxLen]='\0';
		}
    if(ack1!=0&&ack2!=0)
    {
        return ( ( bool ) strstr ( (const char*)UartRxbuf, ack1 ) || 
                         ( bool ) strstr ( (const char*)UartRxbuf, ack2 ) );
    }
    else if( ack1 != 0 ) 
        return ( ( bool ) strstr ( (const char*)UartRxbuf, ack1 ) );

    else
        return ( ( bool ) strstr ( (const char*)UartRxbuf, ack2 ) );

}





//AT
void JDY31_AT_Test(void)
{
    HAL_Delay(1000); 
    while(1)//如果AT指令不通过,说明硬件连接有问题
    {
        if(JDY31_Send_AT_Cmd("AT","+OK",NULL,500)) 
        {
            return;
        }
	      if(JDY31_Send_AT_Cmd("AT+DISC","+OK",NULL,500)) //有可能是原先连接着,先断开连接,再执行AT指令判断
        {
					
        }			
    }
}

 

4.实验效果

手机APP与单片机连接的蓝牙模块通讯

在这里插入图片描述

实验视频

手机通过JDY-31蓝牙模块跟STM32F103C8T6单片机通讯

七.CubeMX工程源代码下载

通过百度网盘分享的文件:34.JDY-31蓝牙通讯实验.rar
链接:https://pan.baidu.com/s/1dU0dHPCeQ0I0zezdVlVdYg
提取码:gg2u
如果链接失效,可以联系博主给最新链接
程序下载下来之后解压就行

CSDN蓝牙例程

八.小结

JDY-31 为经典蓝牙协议、可以与支持蓝牙的电脑(台式、笔记本)、手机(android)通信。
可应用于 Windows 电脑蓝牙串口透传,Android 蓝牙串口透传 ,智能家居控制 ,汽车ODB检测设备,蓝牙玩具,共享移动电源、共享体重称,医疗仪器

  • 20
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值