@toc
需要注意的是敷搪,兩款藍(lán)牙芯片都不是默認(rèn)波特率為115200啡捶,都是以AT指令進(jìn)行配置修改口蝠,所以驅(qū)動(dòng)做了修改柿究,自動(dòng)切換自身波特率進(jìn)行通訊诉字,修改波特率參數(shù)后多糠,調(diào)回115200累舷。
驅(qū)動(dòng)主要做了以下工作:
1、修改藍(lán)牙名稱
2夹孔、修改波特率到115200
3被盈、配置打包機(jī)制
4析孽、設(shè)置從站模式
驅(qū)動(dòng)代碼
/**
* @file Bluetooth_Port.c
*
* @date 2021-02-26
*
* @author aron566
*
* @copyright Copyright (c) 2021 aron566 <aron566@163.com>.
*
* @brief 藍(lán)牙接口初始化
*
* @details 1、與APP通訊使用20Bytes打包機(jī)制
*
* @version V1.0
*/
#ifdef __cplusplus ///<use C compiler
extern "C" {
#endif
/** Includes -----------------------------------------------------------------*/
/* Private includes ----------------------------------------------------------*/
#include "Bluetooth_Port.h"
#include "Uart_Port.h"
/** Private typedef ----------------------------------------------------------*/
/** Private macros -----------------------------------------------------------*/
/*BLE配置*/
#define USE_BLE_103_DEV 1 /**< 使用有人模塊*/
#define ENABLE_BLE_DEBUG 0 /**< 啟用BLE調(diào)試模式*/
#define SET_CMD_TIMEOUT_MAX 4U /**< 4s判定設(shè)置超時(shí)*/
#define USE_BAUD_REATE_VALUE 115200U /**< 設(shè)置波特率*/
#define BUF_SIZE_MAX 64U /**< 最大單次接收AT響應(yīng)長(zhǎng)度*/
/*模塊AT指令集*/
#if USE_BLE_103_DEV
/*有人WH_BLE-103*/
#define DEFAULT_BAUD_RATE 57600U /**< 默認(rèn)波特率*/
#define BLE_DEVICE_NAME "aidiWH" /**< 設(shè)定藍(lán)牙名稱*/
#define SLAVE_MODE_CMD "AT+MODE=S\r\n" /**< 設(shè)置模塊為從站模式*/
#define MASTER_MODE_CMD "AT+MODE=M\r\n" /**< 設(shè)置模塊為主站模式*/
#define BROADCAST_MODE_CMD "AT+MODE=B\r\n" /**< 設(shè)置模塊為廣播模式*/
#define DEV_DISCONNECT_CMD "AT+DISCONN\r\n"
#define CHECK_CONNECT_STA_CMD "AT+LINK?\r\n"
#define DEV_REBOOT_CMD "AT+Z\r\n" /**< 控制模塊重啟*/
#define SET_BAUD_RATE_CMD "AT+UART=%u,8,0,0\r\n"/**< 設(shè)置波特率*/
#define SET_BAUD_RETURN_STR "\r\n+UART:%u,8,0,0\r\nOK\r\n"
#define PACKAGE_MAXPUT "OFF\r\n" /**< 小包模式/100Bytes每包*/
#define PACKAGE_TIME "30\r\n" /**< 打包間隔時(shí)間>=30 value <=100*/
#define SEND_POWER "8\r\n" /**< 發(fā)送功率*/
#define SET_UUID_AA "AA0003CDD000001000800000805F9B0131\r\n"/**< 主服務(wù)UUID 返回:0003CDD0-00001000-8000-00805F9B0131*/
#define SET_UUID_BB "BB0003CDD100001000800000805F9B0131\r\n"/**< 串口讀服務(wù)只怎,一個(gè) Notify 服務(wù) 返回:0003CDD1-00001000-8000-00805F9B0131*/
#define SET_UUID_CC "CC0003CDD200001000800000805F9B0131\r\n"/**< 串口寫(xiě)服務(wù)袜瞬,一個(gè) WriteWithoutResponse 服務(wù) 返回:0003CDD2-00001000-8000-00805F9B0131*/
#else
/*HC-08*/
#define DEFAULT_BAUD_RATE 9600U /**< 默認(rèn)波特率*/
#define BLE_DEVICE_NAME "aidiHC" /**< 設(shè)定藍(lán)牙名稱*/
#define SET_BAUD_RATE_CMD "AT+BAUD=%u,N"
#define SET_BAUD_RETURN_STR "OK%u,NONE"
#endif
/** Private constants --------------------------------------------------------*/
/** Public variables ---------------------------------------------------------*/
/** Private variables --------------------------------------------------------*/
static Uart_Dev_Handle_t *uart_opt_handle = NULL;/**< 串口操作句柄*/
static char AT_Cmd_Str[BUF_SIZE_MAX];
static char AT_Reply_Str[BUF_SIZE_MAX];
/** Private function prototypes ----------------------------------------------*/
static bool Get_Result_State(const char *Cmd_Str, const char *Result_Str, uint32_t Time_Out_Sec);
static bool Set_Baudrate(uint32_t BaudRate);
static void Set_Self_Baudrate(uint32_t BaudRate);
static void Bluetooth_Port_Reset(void);
#if USE_BLE_103_DEV
static void Ble_103_Dev_Init(void);
#else
static void Ble_HC_08_Init(void);
#endif
/** Private user code --------------------------------------------------------*/
/** Private application code -------------------------------------------------*/
/*******************************************************************************
*
* Static code
*
********************************************************************************
*/
/**
******************************************************************
* @brief 設(shè)置自身通訊波特率
* @param [in]BaudRate 波特率
* @return None.
* @author aron566
* @version V1.0
* @date 2021-02-26
******************************************************************
*/
static void Set_Self_Baudrate(uint32_t BaudRate)
{
Uart_Port_Set_Baudrate(UART_NUM_6, BaudRate);
}
/**
******************************************************************
* @brief 設(shè)置藍(lán)牙通訊波特率
* @param [in]BaudRate 波特率
* @return true 設(shè)置成功.
* @author aron566
* @version V1.0
* @date 2021-02-26
******************************************************************
*/
static bool Set_Baudrate(uint32_t BaudRate)
{
static uint8_t Retry_Cnt = 0;
/*設(shè)置波特率*/
snprintf(AT_Cmd_Str, BUF_SIZE_MAX, SET_BAUD_RATE_CMD, BaudRate);
snprintf(AT_Reply_Str, BUF_SIZE_MAX, SET_BAUD_RETURN_STR, BaudRate);
/*發(fā)送設(shè)置*/
if(Get_Result_State(AT_Cmd_Str, AT_Reply_Str, SET_CMD_TIMEOUT_MAX) == true)
{
return true;
}
/*New Baudrate Retry*/
if(Retry_Cnt > 0)
{
return false;
}
Set_Self_Baudrate(BaudRate);
Retry_Cnt++;
Set_Baudrate(BaudRate);
return false;
}
/**
******************************************************************
* @brief 發(fā)送字符串命令等待返回結(jié)果
* @param [in]Cmd_Str 命令字符串.
* @param [in]Result_Str 預(yù)期等待返回字符串.
* @param [in]Time_Out_Sec 預(yù)期等待時(shí)間.
* @return true 返回成功.
* @author aron566
* @version V1.0
* @date 2021-03-18
******************************************************************
*/
static bool Get_Result_State(const char *Cmd_Str, const char *Result_Str, uint32_t Time_Out_Sec)
{
uint32_t len = 0;
uint8_t temp_buf[BUF_SIZE_MAX] = {0};
uint32_t Start_Sec = Timer_Port_Get_Current_Time(TIMER_SEC);
uint32_t Compare_Len = strlen(Result_Str);
while(1)
{
/*發(fā)送AT讀指令*/
Uart_Port_Transmit_Data(uart_opt_handle, (uint8_t *)Cmd_Str, strlen(Cmd_Str), 100);
HAL_Delay(500);
/*等待回復(fù)*/
len = CQ_skipInvaildU8Header(uart_opt_handle->cb, Result_Str[0]);
if(len < Compare_Len)
{
/*檢測(cè)超時(shí)*/
if((Timer_Port_Get_Current_Time(TIMER_SEC) - Start_Sec) >= Time_Out_Sec)
{
CQ_ManualOffsetInc(uart_opt_handle->cb, len);
return false;
}
continue;
}
len = len > BUF_SIZE_MAX?BUF_SIZE_MAX:len;
CQ_ManualGetData(uart_opt_handle->cb, temp_buf, len);
if(memcmp(temp_buf, Result_Str, Compare_Len) == 0)
{
CQ_ManualOffsetInc(uart_opt_handle->cb, len);
return true;
}
else
{
/*檢測(cè)超時(shí)*/
if((Timer_Port_Get_Current_Time(TIMER_SEC) - Start_Sec) >= Time_Out_Sec)
{
CQ_ManualOffsetInc(uart_opt_handle->cb, len);
return false;
}
CQ_ManualOffsetInc(uart_opt_handle->cb, 1);
}
}
}
/**
******************************************************************
* @brief 藍(lán)牙復(fù)位
* @param [in]None.
* @return None.
* @author aron566
* @version V1.0
* @date 2021-04-02
******************************************************************
*/
static void Bluetooth_Port_Reset(void)
{
#if USE_BLE_103_DEV
HAL_GPIO_WritePin(BLE_NRST_GPIO_Port, BLE_NRST_Pin, GPIO_PIN_RESET);
HAL_Delay(1);
HAL_GPIO_WritePin(BLE_NRST_GPIO_Port, BLE_NRST_Pin, GPIO_PIN_SET);
#else
#endif
}
/**
******************************************************************
* @brief 初始化BLE103藍(lán)牙
* @param [in]None.
* @return None.
* @author aron566
* @version V1.0
* @date 2021-03-18
******************************************************************
*/
#if USE_BLE_103_DEV
static void Ble_103_Dev_Init(void)
{
/*喚醒*/
Bluetooth_Port_Wakeup();
/*復(fù)位*/
Bluetooth_Port_Reset();
/*調(diào)節(jié)至設(shè)備默認(rèn)波特率*/
uint8_t Error_Cnt = 0;
Set_Self_Baudrate(DEFAULT_BAUD_RATE);
while(1)
{
/*進(jìn)入AT指令設(shè)置模式*/
snprintf(AT_Cmd_Str, BUF_SIZE_MAX, "%s", "+++a");
snprintf(AT_Reply_Str, BUF_SIZE_MAX, "%s", "a+ok");
/*發(fā)送設(shè)置*/
if(Get_Result_State(AT_Cmd_Str, AT_Reply_Str, SET_CMD_TIMEOUT_MAX) == true)
{
break;
}
else
{
if(Error_Cnt > 1)
{
return;
}
Set_Self_Baudrate(USE_BAUD_REATE_VALUE);
Error_Cnt++;
}
}
/*設(shè)置設(shè)備名稱*/
snprintf(AT_Cmd_Str, BUF_SIZE_MAX, "AT+NAME=%s%04X\r\n", BLE_DEVICE_NAME, HAL_GetUIDw0());
snprintf(AT_Reply_Str, BUF_SIZE_MAX, "%s", "\r\n+NAME:"BLE_DEVICE_NAME);
/*發(fā)送設(shè)置*/
if(Get_Result_State(AT_Cmd_Str, AT_Reply_Str, SET_CMD_TIMEOUT_MAX) == false)
{
#if ENABLE_BLE_DEBUG
while(1);
#endif
}
/*設(shè)置藍(lán)牙波特率*/
if(Set_Baudrate(USE_BAUD_REATE_VALUE) == false)
{
#if ENABLE_BLE_DEBUG
while(1);
#endif
}
/*設(shè)置打包機(jī)制*/
snprintf(AT_Cmd_Str, BUF_SIZE_MAX, "AT+MAXPUT=%s", PACKAGE_MAXPUT);
snprintf(AT_Reply_Str, BUF_SIZE_MAX, "%s", "\r\n+MAXPUT:"PACKAGE_MAXPUT);
/*發(fā)送設(shè)置*/
if(Get_Result_State(AT_Cmd_Str, AT_Reply_Str, SET_CMD_TIMEOUT_MAX) == false)
{
#if ENABLE_BLE_DEBUG
while(1);
#endif
}
/*設(shè)置發(fā)送功率*/
// snprintf(AT_Cmd_Str, BUF_SIZE_MAX, "AT+TPL=%s", SEND_POWER);
// snprintf(AT_Reply_Str, BUF_SIZE_MAX, "%s", "\r\n+TPL:");
// /*發(fā)送設(shè)置*/
// if(Get_Result_State(AT_Cmd_Str, AT_Reply_Str, SET_CMD_TIMEOUT_MAX) == false)
// {
//#if ENABLE_BLE_DEBUG
// while(1);
//#endif
// }
/*設(shè)置打包時(shí)間*/
snprintf(AT_Cmd_Str, BUF_SIZE_MAX, "AT+UARTTM=%s", PACKAGE_TIME);
snprintf(AT_Reply_Str, BUF_SIZE_MAX, "%s", "\r\n+UARTTM:"PACKAGE_TIME);
/*發(fā)送設(shè)置*/
if(Get_Result_State(AT_Cmd_Str, AT_Reply_Str, SET_CMD_TIMEOUT_MAX) == false)
{
#if ENABLE_BLE_DEBUG
while(1);
#endif
}
// /*設(shè)置設(shè)備UUIDAA*/
// snprintf(AT_Cmd_Str, BUF_SIZE_MAX, "AT+UUID=%s", SET_UUID_AA);
// snprintf(AT_Reply_Str, BUF_SIZE_MAX, "%s", "0003CDD0");
// /*發(fā)送設(shè)置*/
// if(Get_Result_State(AT_Cmd_Str, AT_Reply_Str, SET_CMD_TIMEOUT_MAX) == false)
// {
//#if ENABLE_BLE_DEBUG
// while(1);
//#endif
// }
// /*設(shè)置設(shè)備UUIDBB*/
// snprintf(AT_Cmd_Str, BUF_SIZE_MAX, "AT+UUID=%s", SET_UUID_BB);
// snprintf(AT_Reply_Str, BUF_SIZE_MAX, "%s", "0003CDD1");
// /*發(fā)送設(shè)置*/
// if(Get_Result_State(AT_Cmd_Str, AT_Reply_Str, SET_CMD_TIMEOUT_MAX) == false)
// {
//#if ENABLE_BLE_DEBUG
// while(1);
//#endif
// }
//
// /*設(shè)置設(shè)備UUIDCC*/
// snprintf(AT_Cmd_Str, BUF_SIZE_MAX, "AT+UUID=%s", SET_UUID_CC);
// snprintf(AT_Reply_Str, BUF_SIZE_MAX, "%s", "0003CDD2");
// /*發(fā)送設(shè)置*/
// if(Get_Result_State(AT_Cmd_Str, AT_Reply_Str, SET_CMD_TIMEOUT_MAX) == false)
// {
//#if ENABLE_BLE_DEBUG
// while(1);
//#endif
// }
// /*設(shè)置從站模式*/
// snprintf(AT_Cmd_Str, BUF_SIZE_MAX, "%s", SLAVE_MODE_CMD);
// snprintf(AT_Reply_Str, BUF_SIZE_MAX, "%s", "\r\n+MODE:Slave\r\nOK\r\n");
// /*發(fā)送設(shè)置*/
// if(Get_Result_State(AT_Cmd_Str, AT_Reply_Str, SET_CMD_TIMEOUT_MAX) == false)
// {
//#if ENABLE_BLE_DEBUG
// while(1);
//#endif
// }
/*清空緩沖區(qū)*/
HAL_Delay(10);
CQ_emptyData(uart_opt_handle->cb);
/*設(shè)置自身波特率*/
Set_Self_Baudrate(USE_BAUD_REATE_VALUE);
/*設(shè)置模塊重啟--Deprecated: Use The Set Mode To Reboot Device*/
// snprintf(AT_Cmd_Str, BUF_SIZE_MAX, "%s", DEV_REBOOT_CMD);
// snprintf(AT_Reply_Str, BUF_SIZE_MAX, "%s", "\r\n+RST:OK\r\nOK\r\n");
// /*發(fā)送設(shè)置*/
// if(Get_Result_State(AT_Cmd_Str, AT_Reply_Str, SET_CMD_TIMEOUT_MAX) == false)
// {
//#if ENABLE_BLE_DEBUG
// while(1);
//#endif
// }
/*退出命令模式*/
snprintf(AT_Cmd_Str, BUF_SIZE_MAX, "%s", "AT+ENTM\r\n");
snprintf(AT_Reply_Str, BUF_SIZE_MAX, "%s", "\r\n+ENTM:OK\r\nOK\r\n");
/*發(fā)送設(shè)置*/
if(Get_Result_State(AT_Cmd_Str, AT_Reply_Str, SET_CMD_TIMEOUT_MAX) == false)
{
#if ENABLE_BLE_DEBUG
while(1);
#endif
}
}
#else
/**
******************************************************************
* @brief 初始化BLE HC-08藍(lán)牙
* @param [in]None.
* @return None.
* @author aron566
* @version V1.0
* @date 2021-03-18
******************************************************************
*/
static void Ble_HC_08_Init(void)
{
/*調(diào)節(jié)至設(shè)備默認(rèn)波特率*/
Set_Self_Baudrate(DEFAULT_BAUD_RATE);
/*設(shè)置藍(lán)牙波特率*/
if(Set_Baudrate(USE_BAUD_REATE_VALUE) == true)
{
Set_Self_Baudrate(USE_BAUD_REATE_VALUE);
}
/*設(shè)置設(shè)備名稱*/
snprintf(AT_Cmd_Str, BUF_SIZE_MAX, "AT+NAME=%s%04X%04X", BLE_DEVICE_NAME, HAL_GetUIDw0(), HAL_GetUIDw1());
snprintf(AT_Reply_Str, BUF_SIZE_MAX, "%s", "OKsetNAME");
/*發(fā)送設(shè)置*/
if(Get_Result_State(AT_Cmd_Str, AT_Reply_Str, SET_CMD_TIMEOUT_MAX) == false)
{
#if ENABLE_BLE_DEBUG
while(1);
#endif
}
}
#endif
/** Public application code --------------------------------------------------*/
/*******************************************************************************
*
* Public code
*
********************************************************************************
*/
/**
******************************************************************
* @brief 藍(lán)牙喚醒
* @param [in]None
* @return None.
* @author aron566
* @version V1.0
* @date 2021-04-02
******************************************************************
*/
void Bluetooth_Port_Wakeup(void)
{
#if USE_BLE_103_DEV
HAL_GPIO_WritePin(BLE_WAKEUP_GPIO_Port, BLE_WAKEUP_Pin, GPIO_PIN_RESET);
HAL_Delay(1500);
HAL_GPIO_WritePin(BLE_WAKEUP_GPIO_Port, BLE_WAKEUP_Pin, GPIO_PIN_SET);
#else
#endif
/*清空緩沖區(qū)*/
CQ_emptyData(uart_opt_handle->cb);
}
/**
******************************************************************
* @brief 藍(lán)牙接口初始化
* @param [in]None
* @return None.
* @author aron566
* @version V1.0
* @date 2021-02-26
******************************************************************
*/
void Bluetooth_Port_Init(void)
{
#if USE_BLE_103_DEV
/*初始化WH-BLE_103設(shè)備*/
uart_opt_handle = Uart_Port_Get_Handle(UART_NUM_6);
if(uart_opt_handle == NULL)
{
printf("get uart opt handle faild.\n");
return;
}
Ble_103_Dev_Init();
#else
/*初始化HC-08設(shè)備*/
uart_opt_handle = Uart_Port_Get_Handle(UART_NUM_2);
if(uart_opt_handle == NULL)
{
printf("get uart opt handle faild.\n");
return;
}
Ble_HC_08_Init();
#endif
}
#ifdef __cplusplus ///<end extern c
}
#endif
/******************************** End of file *********************************/
/**
* @file Bluetooth_Port.h
*
* @date 2021-02-26
*
* @author aron566
*
* @brief 藍(lán)牙接口初始化
*
* @version V1.0
*/
#ifndef BLUETOOTH_PORT_H
#define BLUETOOTH_PORT_H
#ifdef __cplusplus ///<use C compiler
extern "C" {
#endif
/** Includes -----------------------------------------------------------------*/
#include <stdint.h> /**< need definition of uint8_t */
#include <stddef.h> /**< need definition of NULL */
#include <stdbool.h>/**< need definition of BOOL */
#include <stdio.h> /**< if need printf */
#include <stdlib.h>
#include <string.h>
#include <limits.h> /**< need variable max value */
/** Private includes ---------------------------------------------------------*/
/** Private defines ----------------------------------------------------------*/
/** Exported typedefines -----------------------------------------------------*/
/** Exported constants -------------------------------------------------------*/
/** Exported macros-----------------------------------------------------------*/
/** Exported variables -------------------------------------------------------*/
/** Exported functions prototypes --------------------------------------------*/
/*藍(lán)牙接口初始化*/
void Bluetooth_Port_Init(void);
/*藍(lán)牙喚醒*/
void Bluetooth_Port_Wakeup(void);
#ifdef __cplusplus ///<end extern c
}
#endif
#endif
/******************************** End of file *********************************/
使用方法
在驅(qū)動(dòng)中可以看到
Uart_Port_Get_Handle(UART_NUM_2);
這樣的接口,這是獲取串口操作的句柄尝盼,在這個(gè)句柄中帶有串口接收數(shù)據(jù)緩沖隊(duì)列吞滞,移植方法參考我的博客還有超時(shí)檢測(cè)的機(jī)制,所以需要提供當(dāng)前時(shí)間的接口
Timer_Port_Get_Current_Time(TIMER_SEC)
在實(shí)際測(cè)試使用中BLE-103即有人模塊沒(méi)有HC-08的數(shù)據(jù)傳輸快盾沫,咨詢過(guò)有人裁赠,據(jù)說(shuō)數(shù)據(jù)以20的整數(shù)倍進(jìn)行發(fā)送會(huì)好,實(shí)測(cè)并沒(méi)有赴精。HC-08的模塊在開(kāi)機(jī)的一瞬間電流較大佩捞,10mA左右递沪,單獨(dú)使用串口工具供電類(lèi)似于CH34x這種辅斟,可能直接會(huì)軟件掛掉(發(fā)送數(shù)據(jù),串口工具tx指示燈不閃爍)洗出,需要注意谭确。
void main(void)
{
/*初始化硬件*/
/*串口操作初始化*/
Uart_Port_Init();
/*初始化定時(shí)器*/
/*初始化藍(lán)牙*/
Bluetooth_Port_Init();
}