蓝牙设备使用无线电波连接手机和电脑。蓝牙产品包含一块小小的蓝牙模块以及支持连接的蓝牙无线电和软件。当两台蓝牙设备想要相互交流时,它们需要进行配对。蓝牙设备之间的通信在短程(被称为微微网,指设备使用蓝牙技术连接而成的网络)的临时网络中进行。这种网络可容纳两至八台设备进行连接。当网络环境创建成功,一台设备作为主设备,而所有其它设备作为从设备。英唐众创在蓝牙设备加入和离开无线电短程传感时动态、自动建立。
随着近年来蓝牙技术的不断发展,在功耗不断降低的情形下,蓝牙的传输速率也不断地得到提高,使蓝牙的应用范围更加广泛。但若想设计一套完善的蓝牙系统,就必须充分掌握蓝牙的相关技术知识,如:射频设计、协议堆栈、系统集成及蓝牙模块的选型等方面的专门知识。
蓝牙模块可以通过串口(SPI、IIC)和MCU控制设备进行数据传输。蓝牙模块可以做为主机和从机。主机就是能够搜索别的蓝牙模块并主动建立连接,从机则不能主动建立连接,只能等别人连接自己。
1、HC-05蓝牙模块介绍
HC-05 蓝牙串口通讯模块(以下简称模块)具有两种工作模式:命令响应工作模式和自动连接工作模式,在自动连接工作模式下模块又可分为主(Master)、从(Slave)和回环(Loopback)三种工作角色。
当模块处于自动连接工作模式时,将自动根据事先设定的方式进行数据传输;当模块处于命令响应工作模式时能执行下述所有AT命令,用户可向模块发送各种AT指令,为模块设定控制参数或发布控制命令。通过控制模块外部引脚(PIO11)的输入电平,可以实现模块两种工作模式的切换。
2、HC-06从机蓝牙模块
只能作为从机
其他的还有低功耗BLE蓝牙4.0模块(cc2540或cc2541)、JDY-10 蓝牙4.0 BLE模块等等,这里我们用的是HC-05蓝牙模块作为示例。
配置步骤:
(1)按住蓝牙模块上的en按键通过USB转TTL模块接入电脑,:
若模块以两秒的间隔闪烁,表示连接成功,进入AT命令模式
注:若无按键,则将en引脚接高,再通过USB转TTL接入电脑
(2)打开XCOM(串口调试助手),选择连接的串口,配置波特率38400,打开串口:

注:若找不到串口,请检查是否安装CH340驱动。
(3)指令配置:
输入:AT+ORGL \\恢复默认状态
返回:OK
输入:AT
返回:OK
输入:AT+NAME=xiaoguang \\设置蓝牙设备名称
返回:OK
输入:AT+PSWD=1234 \\设置蓝牙设备密码
返回:OK
输入:AT+UART=9600,0,0 \\设置串口波特率115200,无停止位,无校验位
返回:OK
输入:AT+CMODE=1 \\任意蓝牙地址连接
返回:OK
注:若除AT+NAME?指令外未返回OK,请检查蓝牙模块是否进入命令响应模式
(4)蓝牙模块重新上电,指示灯快速闪烁,打开我们手机上面的蓝牙调试器连接我们的蓝牙模块,连接后蓝牙模块以间隔两秒闪烁两次:

如果找不到名字,可以根据AT+ADDR?指令查看地址进行连接
到这里说明我们的蓝牙模块已经可以和手机连接了。
我们配置的通信协议是:
包头(0xA5)+数据+校验位+包尾(0x5A)
我们的示例中需要接收的数据是一个int整形和一个char型,一共是5个字节,所以一整个的数据包就是8个字节
/*bsp_usart.h*/
#ifndef __BSP_USART_H
#define __BSP_USART_H
#include "stm32f10x.h"
#include <stdio.h>
#define REC_BUF_SIZE 8 //接收数据包的大小
#define DEBUG_USARTx USART2 //蓝牙所用串口2
#define DEBUG_USART_CLK RCC_APB1Periph_USART2 //串口时钟
#define DEBUG_USART_APBxClkCmd RCC_APB1PeriphClockCmd //串口时钟使能
#define DEBUG_USART_BAUDRATE 9600 //波特率设置·
#define DEBUG_USART_GPIO_CLK RCC_APB2Periph_GPIOA
#define DEBUG_USART_GPIO_APBxClkCmd RCC_APB2PeriphClockCmd //端口时钟
#define DEBUG_USART_TX_GPIO_PORT GPIOA //端口宏定义
#define DEBUG_USART_TX_GPIO_PIN GPIO_Pin_2
#define DEBUG_USART_RX_GPIO_PORT GPIOA
#define DEBUG_USART_RX_GPIO_PIN GPIO_Pin_3
#define DEBUG_USART_IRQ USART2_IRQn
#define DEBUG_USART_IRQHandler USART2_IRQHandler //中断服务函数
static void NVIC_Config(void);
void USART_Config(void);
void Usart_SendByte(USART_TypeDef*pUSARTx,uint8_t data);
#endif
/*bsp_usart.c*/
__IO uint8_t usart_value=0;//接收一个字节数据的变量
uint8_t len=0; //接收数据的数组当前下标
uint8_t num[20]; //存放接收一次数据包的数组
uint8_t Flag=0; //接收到数据之后Flag=1
static uint8_t f = 0; //从0xA5开始接收0x5A结束
// 中断服务函数
void DEBUG_USART_IRQHandler(void){
if(USART_GetITStatus(DEBUG_USARTx,USART_IT_RXNE)){ //接收中断标志位变化
usart_value=USART_ReceiveData(DEBUG_USARTx); //接收一个字节的数据
if(usart_value == 0xA5) //从0xA5开始
{
f = 1;
}
if(f == 1) //0xA5之后的数据存放到num[]数组
{
num[len]=usart_value;
len++;
}
}
if(len==REC_BUF_SIZE && usart_value == 0x5A){ //接收到包尾,结束本次接收
Flag=1;
len=0;
f = 0;
}
else if(len > REC_BUF_SIZE){ //如果长度大于数据包的长度,也结束本次接收
f = 0;
len = 0;
}
USART_ClearFlag(DEBUG_USARTx,USART_IT_RXNE); //清除中断标志位
}
