一、简介
本文介绍如何使用STM32控制蓝牙透传模块,蓝牙透传模块使用昇润科技的HY-254124 V8
。
二、实验平台
库版本:STM32F10x_StdPeriph_Lib_V3.5.0
编译软件:MDK4.53
硬件平台:STM32开发板(主芯片stm32f103c8t6)
仿真器:JLINK
三
、
版权声明
博主:甜甜的大香瓜
声明:喝水不忘挖井人,转载请注明出处。
原文地址:http://blog.csdn
.NET
/feilusia
联系方式:897503845@qq.com
香瓜BLE之CC2541群:127442605
香瓜BLE之CC2640群:557278427
香瓜单片机之STM8/STM32群:164311667
甜甜的大香瓜的小店(淘宝店):https://shop217632629.taobao.com/?spm=2013.1.1000126.d21.hd2o8i
四、
实验前提
在进行本文步骤前,请先
阅读并实现
以下博文:
1、《STM32之NVIC》:http://blog.csdn
.NET
/feilusia/article/details/52819709
2、《STM32之串口》:http://blog.csdn.net/feilusia/article/details/52819571
五、
基础知识
1、蓝牙透传模块是什么?
答:蓝牙透传模块上有两个接口:UART/IIC/SPI、蓝牙,可对连接这两个接口的设备进行数据透传
。
例如STM32与蓝牙透传模块通过串口连接、蓝牙透传模块与手机app通过蓝牙连接,则当手机app发送一串数据给蓝牙透传模块后,这串数据会被STM32收到。以此达到手机app控制STM32的作用。
2、为什么要用蓝牙透传模块,而不直接使用蓝牙芯片?
答:
1)蓝牙透传模块
①优点:快速开发、不用做蓝牙认证。
②缺点:模块成本高。
2)直接使用蓝牙芯片
①优点:成本低、板子尺寸能做更小。
②缺点:有一定开发难度、需要蓝牙认证。
3、蓝牙透传模块如何使用?
答:
1)硬件接口
本次使用的模块上有SPI、IIC、UART三种接口,香瓜选择其中的UART。
硬件接口上需要控制以下几个引脚:
其中REST是复位脚、串口接口使用RX和TX、WAKEUP是唤醒脚、INT是模块响应脚,以及电源GND和VCC。
REST不是必须进行控制的,但进行控制REST可方便仿真调试,否则仿真时需要手动拔插模块进行复位。
2)初始化流程
①通过控制REST对模块进行复位。
3)使用注意事项
①昇润的文档有误,只有在唤醒后才会INT中断应答。
②蓝牙透传数据包一包仅有17字节的应用数据可使用。
五、实验步骤
1、编写并添加串口透传模块驱动
1)
编写驱动
BLE_Uart.c(存放在“
……
\HARDWARE
”)
-
//******************************************************************************
-
//name: BLE_Uart.c
-
//introduce: 蓝牙串口透传驱动
-
//author: 甜甜的大香瓜
-
//email: 897503845@qq.com
-
//QQ group 香瓜单片机之STM8/STM32(164311667)
-
//changetime: 2016.10.17
-
//******************************************************************************
-
#include “stm32f10x.h”
-
#include “BLE_Uart.h”
-
#include “GUA_USART.h”
-
#include <string.h>
-
#include “main.h”
-
/*********************宏定义************************/
-
#ifndef U8
-
typedef
unsigned
char
U8;
-
#endif
-
-
#ifndef U16
-
typedef
unsigned
short
U16;
-
#endif
-
-
#ifndef U32
-
typedef
unsigned
long
U32;
-
#endif
-
-
#ifndef int32
-
typedef
signed
long
int32;
-
#endif
-
-
//引脚宏定义
-
#define BLE_UART_INT GPIOA
-
#define BLE_UART_INT_PIN GPIO_Pin_6
-
-
#define BLE_UART_WAKEUP GPIOA
-
#define BLE_UART_WAKEUP_PIN GPIO_Pin_5
-
-
#define BLE_UART_RESET GPIOA
-
#define BLE_UART_RESET_PIN GPIO_Pin_0
-
/*********************全局变量************************/
-
U8 gBLE_Uart_IntPulse = BLE_UART_INTPULSE_IDLE;
//无脉冲
-
-
/*********************内部函数声明************************/
-
static
void
BLE_Uart_IO_Init(
void
);
-
static
void
BLE_Uart_Exti_Init(
void
);
-
//******************************************************************************
-
//name: BLE_Uart_IO_Init
-
//introduce: 蓝牙串口模块的IO初始化
-
//parameter: none
-
//return: none
-
//author: 甜甜的大香瓜
-
//email: 897503845@qq.com
-
//QQ group 香瓜单片机之STM8/STM32(164311667)
-
//changetime: 2016.10.17
-
//******************************************************************************
-
static
void
BLE_Uart_IO_Init(
void
)
-
{
-
//IO结构体
-
GPIO_InitTypeDef GPIO_InitStructure;
-
-
//时钟使能
-
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
-
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
-
-
//RESET配置
-
GPIO_InitStructure.GPIO_Pin = BLE_UART_RESET_PIN;
-
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
-
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-
GPIO_Init(BLE_UART_RESET, &GPIO_InitStructure);
-
-
-
//WAKEUP配置
-
GPIO_InitStructure.GPIO_Pin = BLE_UART_WAKEUP_PIN;
-
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
-
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-
GPIO_Init(BLE_UART_WAKEUP, &GPIO_InitStructure);
-
-
-
//INT配置
-
GPIO_InitStructure.GPIO_Pin = BLE_UART_INT_PIN;
-
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
-
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-
GPIO_Init(BLE_UART_INT, &GPIO_InitStructure);
-
}
-
-
//******************************************************************************
-
//name: BLE_Uart_Exti_Init
-
//introduce: 蓝牙串口模块的IO中断初始化
-
//parameter: none
-
//return: none
-
//author: 甜甜的大香瓜
-
//email: 897503845@qq.com
-
//QQ group 香瓜单片机之STM8/STM32(164311667)
-
//changetime: 2016.10.17
-
//******************************************************************************
-
static
void
BLE_Uart_Exti_Init(
void
)
-
{
-
EXTI_InitTypeDef EXTI_InitStructure;
-
-
//配置中断线
-
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource6);
-
-
//配置中断参数
-
EXTI_InitStructure.EXTI_Line = EXTI_Line6;
-
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
-
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
-
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
-
EXTI_Init(&EXTI_InitStructure);
-
}
-
//******************************************************************************
-
//name: BLE_Uart_Init
-
//introduce: 蓝牙串口模块初始化
-
//parameter: none
-
//return: none
-
//author: 甜甜的大香瓜
-
//email: 897503845@qq.com
-
//QQ group 香瓜单片机之STM8/STM32(164311667)
-
//changetime: 2016.10.17
-
//******************************************************************************
-
void
BLE_Uart_Init(
void
)
-
{
-
u32 i;
-
-
/**********初始化***************/
-
//初始化IO
-
BLE_Uart_IO_Init();
-
-
//初始化IO的中断配置
-
BLE_Uart_Exti_Init();
-
-
//复位
-
GPIO_ResetBits(BLE_UART_RESET, BLE_UART_RESET_PIN);
//RESET低
-
for
(i = 0; i < 1000000; i++);
-
GPIO_SetBits(BLE_UART_RESET, BLE_UART_RESET_PIN);
//RESET高
-
for
(i = 0; i < 1000000; i++);
-
-
//唤醒
-
GPIO_SetBits(BLE_UART_WAKEUP, BLE_UART_WAKEUP_PIN);
//WAKE UP 高
-
for
(i = 0; i < 1000000; i++);
-
GPIO_ResetBits(BLE_UART_WAKEUP, BLE_UART_WAKEUP_PIN);
//WAKE UP 低
-
for
(i = 0; i < 1000000; i++);
-
-
//等待INT的低脉冲
-
while
(gBLE_Uart_IntPulse == BLE_UART_INTPULSE_IDLE);
//低脉冲
-
gBLE_Uart_IntPulse = BLE_UART_INTPULSE_IDLE;
//清空脉冲计数
-
while
(!GPIO_ReadInputDataBit(BLE_UART_INT, BLE_UART_INT_PIN));
//等待INT被拉高
-
-
-
/**********串口测试***************/
-
//发现串口测试指令
-
memset(gGUA_USART2_rx_buf, 0xff, GUA_USART2_RX_SIZE);
-
-
gGUA_USART2_tx_buf[0] = 0x41;
-
gGUA_USART2_tx_buf[1] = 0x54;
-
gGUA_USART2_tx_buf[2] = 0x0d;
-
gGUA_USART2_tx_buf[3] = 0x0a;
-
-
GUA_USARTx_Send(USART2, gGUA_USART2_tx_buf, 4);
-
-
//接收完毕
-
while
(!GPIO_ReadInputDataBit(BLE_UART_INT, BLE_UART_INT_PIN));
//等待INT被拉高
-
gBLE_Uart_IntPulse = BLE_UART_INTPULSE_IDLE;
//清空脉冲计数
-
-
while
(function != FUNC_AT_OK);
//等待串口数据接收完毕
-
function = FUNC_IDLE_EVENT;
//置位
-
-
-
/*********设置从模式***************/
-
//发送设置从模式指令
-
memset(gGUA_USART2_rx_buf, 0xff, GUA_USART2_RX_SIZE);
-
-
gGUA_USART2_tx_buf[0] = 0x41;
-
gGUA_USART2_tx_buf[1] = 0x54;
-
gGUA_USART2_tx_buf[2] = 0x2b;
-
gGUA_USART2_tx_buf[3] = 0x53;
-
gGUA_USART2_tx_buf[4] = 0x45;
-
gGUA_USART2_tx_buf[5] = 0x54;
-
gGUA_USART2_tx_buf[6] = 0x3d;
-
gGUA_USART2_tx_buf[7] = 0x31;
-
gGUA_USART2_tx_buf[8] = 0x0d;
-
gGUA_USART2_tx_buf[9] = 0x0a;
-
-
GUA_USARTx_Send(USART2, gGUA_USART2_tx_buf, 10);
-
-
//接收完毕(两个OK应答)
-
while
(!GPIO_ReadInputDataBit(BLE_UART_INT, BLE_UART_INT_PIN));
//等待INT被拉高
-
gBLE_Uart_IntPulse = BLE_UART_INTPULSE_IDLE;
//清空脉冲计数
-
-
while
(function != FUNC_AT_OK);
//等待串口数据接收完毕
-
function = FUNC_IDLE_EVENT;
//置位
-
-
while
(!GPIO_ReadInputDataBit(BLE_UART_INT, BLE_UART_INT_PIN));
//等待INT被拉高
-
gBLE_Uart_IntPulse = BLE_UART_INTPULSE_IDLE;
//清空脉冲计数
-
-
while
(function != FUNC_AT_OK);
//等待串口数据接收完毕
-
function = FUNC_IDLE_EVENT;
//置位
-
-
/*********进入透传模式***************/
-
//发送透传模式指令
-
memset(gGUA_USART2_rx_buf, 0xff, GUA_USART2_RX_SIZE);
-
-
gGUA_USART2_tx_buf[0] = 0x41;
-
gGUA_USART2_tx_buf[1] = 0x54;
-
gGUA_USART2_tx_buf[2] = 0x2b;
-
gGUA_USART2_tx_buf[3] = 0x4d;
-
gGUA_USART2_tx_buf[4] = 0x4f;
-
gGUA_USART2_tx_buf[5] = 0x44;
-
gGUA_USART2_tx_buf[6] = 0x45;
-
gGUA_USART2_tx_buf[7] = 0x3d;
-
gGUA_USART2_tx_buf[8] = 0x44;
-
gGUA_USART2_tx_buf[9] = 0x41;
-
gGUA_USART2_tx_buf[10] = 0x54;
-
gGUA_USART2_tx_buf[11] = 0x41;
-
gGUA_USART2_tx_buf[12] = 0x0d;
-
gGUA_USART2_tx_buf[13] = 0x0a;
-
-
GUA_USARTx_Send(USART2, gGUA_USART2_tx_buf, 14);
-
-
//接收完毕
-
while
(!GPIO_ReadInputDataBit(BLE_UART_INT, BLE_UART_INT_PIN));
//等待INT被拉高
-
gBLE_Uart_IntPulse = BLE_UART_INTPULSE_IDLE;
//清空脉冲计数
-
-
while
(function != FUNC_AT_OK);
//等待串口数据接收完毕
-
function = FUNC_IDLE_EVENT;
//置位
-
}
2)
编写驱动头文件
BLE_Uart.h(存放在“
……
\HARDWARE
”)
-
//******************************************************************************
-
//name: BLE_Uart.h
-
//introduce: 蓝牙串口透传驱动头文件
-
//author: 甜甜的大香瓜
-
//email: 897503845@qq.com
-
//QQ group 香瓜单片机之STM8/STM32(164311667)
-
//changetime: 2016.10.17
-
//******************************************************************************
-
#ifndef _BLE_UART_H_
-
#define _BLE_UART_H_
-
-
/*********************宏定义************************/
-
#define BLE_UART_INTPULSE_IDLE 0x00 //没有脉冲
-
#define BLE_UART_INTPULSE_ON 0x01 //一个INT脉冲
-
-
/*********************全局变量声明************************/
-
extern
unsigned
char
gBLE_Uart_IntPulse;
-
-
/*********************外部函数声明************************/
-
void
BLE_Uart_Init(
void
);
-
-
#endif
3)
工程中添加
BLE_Uart
.c
4)
在MDK设置中添加驱动源文件路径
2、添加库的GPIO、外部中断驱动
1)
添加库的驱动头文件(stm32f10x_conf.h 中)
-
#include “stm32f10x_exti.h”
-
#include “stm32f10x_gpio.h”
2)
添加库的
GPIO、外部中断
驱动文件
3、设置NVIC中断优先级(
GUA_NVIC.c的GUA_NVIC_Init中
)
-
//串口透传模块
-
GUA_NVIC_Config(NVIC_PriorityGroup_2, EXTI9_5_IRQn, 0, 2, ENABLE);
INT引脚的中断优先级配置。
4、写中断服务函数
(stm32f10x_it.c中)
1)
添加头文件
-
#include “BLE_Uart.h”
2)编写INT使用的中断服务函数、修改串口中断服务函数
-
//******************************************************************************
-
//name: EXTI9_5_IRQn
-
//introduce: 中断服务函数
-
//parameter: none
-
//return: none
-
//author: 甜甜的大香瓜
-
//email: 897503845@qq.com
-
//QQ group 香瓜单片机之STM8/STM32(164311667)
-
//changetime: 2016.10.17
-
//******************************************************************************
-
void
EXTI9_5_IRQHandler(
void
)
-
{
-
if
(EXTI_GetITStatus(EXTI_Line6) != RESET)
-
{
-
//有低脉冲
-
gBLE_Uart_IntPulse = BLE_UART_INTPULSE_ON;
-
-
//清除标志位
-
EXTI_ClearITPendingBit(EXTI_Line6);
-
}
-
}
-
-
//******************************************************************************
-
//name: USART2_IRQHandler
-
//introduce: 串口2中断服务函数
-
//parameter: none
-
//return: none
-
//author: 甜甜的大香瓜
-
//email: 897503845@qq.com
-
//QQ group 香瓜单片机之STM8/STM32(164311667)
-
//changetime: 2016.10.17
-
//******************************************************************************
-
void
USART2_IRQHandler(
void
)
-
{
-
u8 nRet = 0;
-
u8 nNum = 0;
-
u8 nbAT_OK_Buf[7] =
“AT+OK\r\n”
;
-
-
//接收串口数据
-
nNum = GUA_USARTx_Reveive(USART2, gGUA_USART2_rx_buf);
-
-
//如果是AT指令
-
if
(memcmp(nbAT_OK_Buf, gGUA_USART2_rx_buf, nNum) == 0)
-
{
-
//function = FUNC_AT_OK;
-
}
-
else
-
{
-
/*
-
nRet = USARTx_Judgment(gGUA_USART2_rx_buf);
//串口数据判断
-
if
(nRet ==
true
)
-
{
-
USARTx_Process(gGUA_USART2_rx_buf);
//串口数据处理
-
}
-
else
-
{
-
function = FUNC_RETRUN_ERROR_EVENT;
//空闲
-
}
-
*/
-
}
-
}
5、在应用层中调用
1)添加头文件(main.c中)
-
#include “BLE_Uart.h”
2)
添加驱动初始化代码(main.c的main函数中)
-
//串口模块初始化
-
BLE_Uart_Init();
六、实验结果
仿真并全速运行,用手机的BLE读写器可查看到此时蓝牙透传模块已广播出来
说明蓝牙透传模块已经被正确初始化并广播数据出来,此时就可以连接上进行数据透传了。