简介
具有两种工作模式:命令响应工作模式和自动连接工作模式。支持UART和USB接口。
命令响应工作模式:发送AT指令,配置蓝牙模块。(与TTL转USB模块连接,USB连接电脑,另一端与蓝牙模块串口形式连接)。
自动连接工作模式:连接手机APP进行数据和命令的发送与接收。
模块使用
1、蓝牙配置(通过串口调试助手发送AT指令)(TTL转USB)
2、手机与蓝牙的传输(此时蓝牙模块与单片机,通过串口的形式连接)
3、手机通过蓝牙模块控制单片机(手机蓝牙调试助手软件)
准备物品
蓝牙模块、TTL转USB、蓝牙调试助手APP(资源)
AT指令(常用)
1)测试通讯
发送:AT(返回 OK,一秒左右发一次)
返回:OK
2)改蓝牙串口通讯波特率
发送:AT+BAUD1
返回:+BAUD=1
此时波特率为 1200
发送:AT+BAUD2
返回:+BAUD=2
此时波特率为 2400
……
1---------1200
2---------2400
3---------4800
4---------9600
5---------19200
6---------38400
7---------57600
8---------115200
9---------230400
A---------460800
B---------921600
C---------1382400
不建议用在超过 115200 的波特率,信号的干扰会使系统不稳定。
设置超过 115200 后用电脑无法使用,要用单片机编程于高于
115200 才能使用此波特率和重新发 AT 命令设低波特率
用 AT 命令设好波特率后,下次上电使用不需再设,可以掉电保存波
特率。
3)改蓝牙名称
发送:AT+NAMEname
返回:OK
参数 name:所要设置的当前名称,即蓝牙被搜索到的名称。20 个
字符以内。
例:发送 AT+NAME123
返回+NAME=123
这时蓝牙名称改为 123
参数可以掉电保存,只需修改一次。PDA 端刷新服务可以看到更
改后的蓝牙名称。
4)改蓝牙配对密码
发送:AT+PINxxxx
返回:+PIN=xxxx
参数 xxxx:所要设置的配对密码,4 个字节,此命令可用于从机或
主机。从机则是适配器或手机弹出要求输入配对密码窗口时,则手工
输入此参数就可以连接从机。主机则是在用主蓝牙模块连数码相机
时,数码相机是从机,找到相机的配对密码,再设入主蓝牙模块,则
主蓝牙模块就可以自动连接相机。
例:发送 AT+PIN8888
返回+PIN=8888
这时蓝牙配对密码改为 8888,模块在出厂时的默认配对密码是
1234。
参数可以掉电保存,只需修改一次。
5)更改模块的主从模式(V1.7 版本以后支持)
发送:AT+ROLE=1(设置模块为主模式 Master)
返回:+ROLE=1
发送:AT+ROLE=0(设置模块为从模式 Slave)
返回:+ROLE=0
代码
其配置按照串口的形式配置。(物理层与协议层(数据链路层))
.c文件
#include "stm32f10x.h"
#include <stdio.h>
#include "sys.h"
#include "Bluetooth.h"
#include "string.h"
#include "delay.h"
u8 USART_RX_BUF[USART_REC_LEN];
u16 USART_RX_STA;
//加入以下代码,支持printf函数,而不需要选择use MicroLIB,避免出现半主机模式 ,写在模块程序上面
#if 1
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{ int handle;
};
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
void _sys_exit(int x)
{ x = x; }
//重定义fputc函数
int fputc(int ch, FILE *f) //文件流方式
{
while((USART3->SR&0X40)==0);//循环发送,直到发送完毕 //寄存器TC位,在没有置1时一直循环,置1后跳出循环
USART3->DR = (u8) ch;
return ch;
}
#endif
void bluetooth_init()
{
GPIO_InitTypeDef GPIOInitDef;
NVIC_InitTypeDef NVICInitDef;
USART_InitTypeDef USARTInitDef;
//----------------------------------------------------
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
GPIOInitDef.GPIO_Pin=GPIO_Pin_11; //PB11-RX
GPIOInitDef.GPIO_Mode=GPIO_Mode_IN_FLOATING; //浮空输入
GPIOInitDef.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIOInitDef);
GPIOInitDef.GPIO_Pin=GPIO_Pin_10; //PB10-TX
GPIOInitDef.GPIO_Mode=GPIO_Mode_AF_PP; //复用推挽
GPIOInitDef.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIOInitDef);
//----------------------------------------------------
USARTInitDef.USART_BaudRate=9600;
USARTInitDef.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
USARTInitDef.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
USARTInitDef.USART_Parity=USART_Parity_No;
USARTInitDef.USART_StopBits=USART_StopBits_1;
USARTInitDef.USART_WordLength=USART_WordLength_8b;
USART_Init(USART3,&USARTInitDef);
//----------------------------------------------------
NVICInitDef.NVIC_IRQChannel=USART3_IRQn; //设置中断通道
NVICInitDef.NVIC_IRQChannelCmd=ENABLE;
NVICInitDef.NVIC_IRQChannelPreemptionPriority=0;
NVICInitDef.NVIC_IRQChannelSubPriority=2;
NVIC_Init(&NVICInitDef);
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
USART_ITConfig(USART3, USART_IT_IDLE, ENABLE);
USART_Cmd(USART3,ENABLE); //使能串口
}
//中断接收
void USART3_IRQHandler()
{
u8 res;
if(USART_GetITStatus(USART3,USART_IT_RXNE)) //SR寄存器的 RXNE位,读寄存器非空,判断是否有数据
{
res = USART_ReceiveData(USART3); //读取数据相当于清除中断
USART_RX_BUF[USART_RX_STA&0X3FFF]=res; //将接收到数据存入数组
USART_RX_STA++; //数组长度变量++
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接受的数据长度超过数组最大值,重新开始
}
if(USART_GetITStatus(USART3,USART_IT_IDLE)) //SR寄存器的 IDLE位,判断总线是否空闲,也就是判断是否接受完数据
{
res = USART3->SR;
res = USART3->DR; //清空闲中断标志位,看中文数据操作手册:先读SR,再读DR,后清除中断
USART_RX_STA|=0x8000;//第十五位置一
}
}
//发送一个字节数据
void usart_sendbyte(USART_TypeDef* pUSARTx, uint8_t data)
{
//等待发送数据寄存器为空
while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TXE) == RESET);
//发送一个字节数据
USART_SendData(pUSARTx,data);
}
//发送一个数组数据
void usart_sendarr(USART_TypeDef* pUSARTx, uint8_t *arr, uint8_t len)
{
uint8_t i;
for(i = 0; i < len; i++)
{
//发送一个字节数据
usart_sendbyte(pUSARTx,*arr++);
}
//等待发送完成
while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC) == RESET);
}
//发送字符串数据
void usart_sendstr(USART_TypeDef* pUSARTx, char *str)
{
do
{
//发送一个字节数据
usart_sendbyte(pUSARTx,*str++);
}while((*str) != '\0');
//等待发送完成
while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC) == RESET);
}
.h文件
#ifndef BLUETOOTH_H
#define BLUETOOTH_H
#include "stm32f10x.h"
#define USART_REC_LEN 200
extern u8 USART_RX_BUF[USART_REC_LEN];
extern u16 USART_RX_STA;
void bluetooth_init(void);
void usart_sendbyte(USART_TypeDef* pUSARTx, uint8_t data);
void usart_sendarr(USART_TypeDef* pUSARTx, uint8_t *arr, uint8_t len);
void usart_sendstr(USART_TypeDef* pUSARTx, char *str);
#endif