驱动文件
头文件
#ifndef F4_PROJECT_BLE_HC05_H
#define F4_PROJECT_BLE_HC05_H
#include "bsp.h"
#include "bsp_uart.h"
typedef enum {
hc05_resp_ok_status,
hc05_resp_timeout_status,
hc05_resp_fail_status
} hc05_resp_status;
void hc05_device_init(void);
extern void hc05_device_send(const char *cmd);
extern char *hc05_device_wait_resp(void);
extern void hc05_device_enter_at_mode(void);
extern void hc05_device_quit_at_mode(void);
extern uint16_t hc05_device_rec_remote_data(uint8_t *dst);
extern uint16_t hc05_device_send_remote_data(uint8_t *dst,uint16_t len);
void hc05_set_delay_cb(void (*delay_ms_call)(uint32_t));
hc05_resp_status hc05_set_cmd(const char *cmd);
char *hc05_query_cmd(const char *cmd);
void hc05_delay_ms(uint32_t ms);
hc05_resp_status hc05_check(uint8_t tryCnt);
hc05_resp_status hc05_read_version(char *dst);
hc05_resp_status hc05_read_work_stat(char *dst);
hc05_resp_status hc05_read_addr(char *dst);
hc05_resp_status hc05_read_name(char *dst);
hc05_resp_status hc05_read_role(char *dst);
hc05_resp_status hc05_read_pwd(char *dst);
hc05_resp_status hc05_read_uart_cnf(char *dst);
#endif
源文件
#include "ble_hc05.h"
static bool hc05_sub_str(char *dst, const char *src, char *prefix_str, char *suffix_str);
static void (*hc05_delay_call)(uint32_t) =NULL;
void hc05_set_delay_cb(void (*delay_ms_call)(uint32_t)) {
hc05_delay_call = delay_ms_call;
}
void hc05_delay_ms(uint32_t ms) {
if (hc05_delay_call) {
hc05_delay_call(ms);
}
}
hc05_resp_status hc05_set_cmd(const char *cmd) {
char *result = hc05_query_cmd(cmd);
if (strstr(result, "OK")) {
return hc05_resp_ok_status;
} else if (strstr(result, "FAIL")) {
return hc05_resp_fail_status;
}
return hc05_resp_timeout_status;
}
char *hc05_query_cmd(const char *cmd) {
hc05_device_enter_at_mode();
hc05_delay_ms(10);
hc05_device_send(cmd);
hc05_device_quit_at_mode();
return hc05_device_wait_resp();
}
hc05_resp_status hc05_check(uint8_t tryCnt) {
for (uint8_t i = 0; i < tryCnt; ++i) {
if (hc05_set_cmd("AT\r\n") == hc05_resp_ok_status) {
return hc05_resp_ok_status;
}
}
return hc05_resp_timeout_status;
}
hc05_resp_status hc05_read_version(char *dst) {
char *ptr = hc05_query_cmd("AT+VERSION?\r\n");
if (ptr) {
if (hc05_sub_str(dst, ptr, "VERSION:", "\r\n")) {
return hc05_resp_ok_status;
}
return hc05_resp_fail_status;
}
return hc05_resp_timeout_status;
}
hc05_resp_status hc05_read_work_stat(char *dst){
char *ptr = hc05_query_cmd("AT+STATE?\r\n");
if (ptr) {
if (hc05_sub_str(dst, ptr, "STATE:", "\r\n")) {
return hc05_resp_ok_status;
}
return hc05_resp_fail_status;
}
return hc05_resp_timeout_status;
}
hc05_resp_status hc05_read_addr(char *dst){
char *ptr = hc05_query_cmd("AT+ADDR?\r\n");
if (ptr) {
if (hc05_sub_str(dst, ptr, "ADDR:", "\r\n")) {
return hc05_resp_ok_status;
}
return hc05_resp_fail_status;
}
return hc05_resp_timeout_status;
}
hc05_resp_status hc05_read_name(char *dst){
char *ptr = hc05_query_cmd("AT+NAME?\r\n");
if (ptr) {
if (hc05_sub_str(dst, ptr, "NAME:", "\r\n")) {
return hc05_resp_ok_status;
}
return hc05_resp_fail_status;
}
return hc05_resp_timeout_status;
}
hc05_resp_status hc05_read_role(char *dst){
char *ptr = hc05_query_cmd("AT+ROLE?\r\n");
if (ptr) {
if (hc05_sub_str(dst, ptr, "ROLE:", "\r\n")) {
return hc05_resp_ok_status;
}
return hc05_resp_fail_status;
}
return hc05_resp_timeout_status;
}
hc05_resp_status hc05_read_pwd(char *dst){
char *ptr = hc05_query_cmd("AT+PSWD?\r\n");
if (ptr) {
if (hc05_sub_str(dst, ptr, "PSWD:", "\r\n")) {
return hc05_resp_ok_status;
}
return hc05_resp_fail_status;
}
return hc05_resp_timeout_status;
}
hc05_resp_status hc05_read_uart_cnf(char *dst){
char *ptr = hc05_query_cmd("AT+UART?\r\n");
if (ptr) {
if (hc05_sub_str(dst, ptr, "UART:", "\r\n")) {
return hc05_resp_ok_status;
}
return hc05_resp_fail_status;
}
return hc05_resp_timeout_status;
}
static bool hc05_sub_str(char *dst, const char *src, char *prefix_str, char *suffix_str) {
const char *ptr_src = src;
size_t sub_len;
if (!ptr_src) return true;
if (prefix_str != NULL) {
ptr_src = strstr(ptr_src, prefix_str);
if (!ptr_src) return false;
ptr_src += strlen(prefix_str);
}
if (suffix_str) {
char *endPtr = strstr(ptr_src, suffix_str);
if (!endPtr) return false;
sub_len = endPtr - ptr_src;
} else {
sub_len = strlen(ptr_src);
}
memcpy(dst, ptr_src, sub_len);
dst[sub_len] = '\0';
return true;
}
接口文件(对应硬件)
#include "ble_hc05.h"
#define HC05_AT_GPIO_PIN GPIO_PIN_9
#define HC05_AT_GPIO_PORT GPIOC
#define HC05_AT_GPIO_CLK_EN() __HAL_RCC_GPIOC_CLK_ENABLE()
#define hc05_uart_dev uart1_dev
static bool isCmdDatResp = false;
static void hc05_device_start_rec(void);
static uint8_t hc05_rx_buf[UART1_RX_BUF_LEN];
void hc05_device_init(void) {
hc05_set_delay_cb(HAL_Delay);
HC05_AT_GPIO_CLK_EN();
GPIO_InitTypeDef GPIO_Init;
GPIO_Init.Pin = HC05_AT_GPIO_PIN;
GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_Init.Pull = GPIO_PULLDOWN;
GPIO_Init.Speed = GPIO_SPEED_MEDIUM;
HAL_GPIO_Init(HC05_AT_GPIO_PORT, &GPIO_Init);
uart1_dev_init(115200);
hc05_device_start_rec();
hc05_device_quit_at_mode();
}
__weak void hc05_device_send(const char *cmd) {
HAL_UART_Transmit(&hc05_uart_dev.uart_handle, (uint8_t *) cmd, strlen(cmd), 20);
}
__weak char *hc05_device_wait_resp(void) {
for (int i = 0; i < 10; ++i) {
hc05_delay_ms(10);
uint32_t len = CacheBuffer_Read_Data(hc05_uart_dev.rx_cache_ptr, hc05_rx_buf);
if (len > 0) {
hc05_rx_buf[len] = '\0';
return (char *) hc05_rx_buf;
}
}
return NULL;
}
__weak uint16_t hc05_device_rec_remote_data(uint8_t *dst) {
hc05_device_quit_at_mode();
return CacheBuffer_Read_Data(hc05_uart_dev.rx_cache_ptr, dst);
}
uint16_t hc05_device_send_remote_data(uint8_t *dst,uint16_t len){
hc05_device_quit_at_mode();
HAL_UART_Transmit(&hc05_uart_dev.uart_handle, dst, len, 20);
return len;
}
__weak void hc05_device_enter_at_mode(void) {
HAL_GPIO_WritePin(HC05_AT_GPIO_PORT, HC05_AT_GPIO_PIN, GPIO_PIN_SET);
}
__weak void hc05_device_quit_at_mode(void) {
HAL_GPIO_WritePin(HC05_AT_GPIO_PORT, HC05_AT_GPIO_PIN, GPIO_PIN_RESET);
}
void HAL_UARTEx_RxEventCallback_HC05(uint16_t Size) {
CacheBuffer_Update_Data_Len(hc05_uart_dev.rx_cache_ptr, Size);
hc05_device_start_rec();
}
static void hc05_device_start_rec(void) {
HAL_UARTEx_ReceiveToIdle_DMA(&hc05_uart_dev.uart_handle,
hc05_uart_dev.rx_cache_ptr->List[hc05_uart_dev.rx_cache_ptr->InIndex].start,
CACHE_BUFFER_ONE_DATA_MAX_LEN);
}
串口驱动文件(针对stm32f4芯片,根据需要修改)
bsp_uart.h
#ifndef BSP_UART_H
#define BSP_UART_H
#include "bsp.h"
#include "cachebuffer.h"
#define UART_PRINTF_DEV uart2_dev.uart_handle
#define UART1_DEV_RX_CACHE_ENABLE 1
#define UART1_DEV_TX_CACHE_ENABLE 0
#define UART1_IT_ENABLE 1
#define UART1_RX_BUF_LEN 1024
#define UART1_TX_BUF_LEN 1024
#define UART2_DEV_RX_CACHE_ENABLE 0
#define UART2_DEV_TX_CACHE_ENABLE 0
#define UART2_IT_ENABLE 0
#define UART2_RX_BUF_LEN 1024
#define UART2_TX_BUF_LEN 1024
typedef struct {
CacheBuffer_t *rx_cache_ptr;
CacheBuffer_t *tx_cache_ptr;
UART_HandleTypeDef uart_handle;
} uart_dev_t;
extern uart_dev_t uart1_dev;
extern uart_dev_t uart2_dev;
void uart1_dev_init(uint32_t baud);
void uart2_dev_init(uint32_t baud);
#endif
bsp_uart.c
#include "bsp_uart.h"
static void uart_conf_init(UART_HandleTypeDef *uart_handle, uint32_t baud);
uart_dev_t uart1_dev = {.uart_handle.Instance=USART1};
#if UART1_DEV_RX_CACHE_ENABLE
static CacheBuffer_t uart1_rx_cache;
static uint8_t uart1_rx_buf[UART1_RX_BUF_LEN] = {0};
#endif
#if UART1_DEV_TX_CACHE_ENABLE
static CacheBuffer_t uart1_tx_cache;
static uint8_t uart1_tx_buf[UART1_TX_BUF_LEN] = {0};
#endif
int _write(int file, char *ptr, int len)
{
(void)file;
HAL_UART_Transmit(&UART_PRINTF_DEV, (const uint8_t *) ptr, len, 200);
return len;
}
void uart1_dev_init(uint32_t baud) {
#if UART1_DEV_RX_CACHE_ENABLE
uart1_dev.rx_cache_ptr = &uart1_rx_cache;
CacheBuffer_Init(uart1_dev.rx_cache_ptr, uart1_rx_buf, UART1_RX_BUF_LEN);
#endif
#if UART1_DEV_TX_CACHE_ENABLE
uart1_dev.tx_cache_ptr = &uart1_tx_cache;
CacheBuffer_Init(uart1_dev.tx_cache_ptr, uart1_tx_buf, UART1_TX_BUF_LEN);
#endif
uart_conf_init(&uart1_dev.uart_handle, baud);
}
uart_dev_t uart2_dev = {.uart_handle.Instance=USART2};
#if UART2_DEV_RX_CACHE_ENABLE
static CacheBuffer_t uart2_rx_cache;
static uint8_t uart2_rx_buf[UART2_RX_BUF_LEN] = {0};
#endif
#if UART2_DEV_TX_CACHE_ENABLE
static CacheBuffer_t uart2_tx_cache;
static uint8_t uart2_tx_buf[UART2_TX_BUF_LEN] = {0};
#endif
void uart2_dev_init(uint32_t baud) {
#if UART2_DEV_RX_CACHE_ENABLE
uart2_dev.rx_cache_ptr = &uart2_rx_cache;
CacheBuffer_Init(uart2_dev.rx_cache_ptr, uart2_rx_buf, UART2_RX_BUF_LEN);
#endif
#if UART2_DEV_TX_CACHE_ENABLE
uart2_dev.tx_cache_ptr = &uart2_tx_cache;
CacheBuffer_Init(uart2_dev.tx_cache_ptr, uart2_tx_buf, UART2_TX_BUF_LEN);
#endif
uart_conf_init(&uart2_dev.uart_handle, baud);
}
static void uart_conf_init(UART_HandleTypeDef *uart_handle, uint32_t baud) {
uart_handle->Init.BaudRate = baud;
uart_handle->Init.WordLength = UART_WORDLENGTH_8B;
uart_handle->Init.StopBits = UART_STOPBITS_1;
uart_handle->Init.Parity = UART_PARITY_NONE;
uart_handle->Init.Mode = UART_MODE_TX_RX;
uart_handle->Init.HwFlowCtl = UART_HWCONTROL_NONE;
uart_handle->Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(uart_handle) != HAL_OK) {
Error_Handler();
}
}
缓冲区文件(通用)
cachebuffer.h
#ifndef F4_DEMO_CACHEBUFFER_H
#define F4_DEMO_CACHEBUFFER_H
#include <stdbool.h>
#include "stdio.h"
#include "string.h"
#define CACHE_BUFFER_PARM_ASSERT(x)
#define CACHE_BUFFER_LIST_LEN 10
#define CACHE_BUFFER_ONE_DATA_MAX_LEN 256
#define CACHE_BUFFER_MEMCPY memcpy
typedef struct {
uint8_t *start;
uint8_t *end;
} CacheIndexPtr_t;
typedef struct {
uint32_t Count;
uint16_t InIndex: 8;
uint16_t OutIndex: 8;
uint8_t *pBuf;
uint32_t pBufCapacity;
CacheIndexPtr_t List[CACHE_BUFFER_LIST_LEN];
} CacheBuffer_t;
void CacheBuffer_Init(CacheBuffer_t *cacheBuffer, uint8_t *pool, int16_t size);
void CacheBuffer_Update_Data_Len(CacheBuffer_t *cacheBuffer, uint32_t len);
void CacheBuffer_Write_Data(CacheBuffer_t *cacheBuffer, uint8_t *pData, uint32_t len);
uint32_t CacheBuffer_Read_Data(CacheBuffer_t *cacheBuffer, uint8_t *dst);
#endif
cachebuffer.c
#include "cachebuffer.h"
void CacheBuffer_Init(CacheBuffer_t *cacheBuffer, uint8_t *pool, int16_t size) {
CACHE_BUFFER_PARM_ASSERT(cacheBuffer != NULL);
CACHE_BUFFER_PARM_ASSERT(pool != NULL);
cacheBuffer->pBufCapacity = size;
cacheBuffer->InIndex = 0;
cacheBuffer->OutIndex = 0;
cacheBuffer->Count = 0;
cacheBuffer->pBuf = pool;
cacheBuffer->List[cacheBuffer->InIndex].start = pool;
}
void CacheBuffer_Update_Data_Len(CacheBuffer_t *cacheBuffer, uint32_t len) {
cacheBuffer->Count += len;
cacheBuffer->List[cacheBuffer->InIndex].end = cacheBuffer->pBuf + cacheBuffer->Count - 1;
cacheBuffer->InIndex++;
if (cacheBuffer->InIndex == CACHE_BUFFER_LIST_LEN) {
cacheBuffer->InIndex = 0;
}
if (cacheBuffer->pBufCapacity - cacheBuffer->Count < CACHE_BUFFER_ONE_DATA_MAX_LEN) {
cacheBuffer->Count = 0;
cacheBuffer->List[cacheBuffer->InIndex].start = cacheBuffer->pBuf;
} else {
cacheBuffer->List[cacheBuffer->InIndex].start = cacheBuffer->pBuf + cacheBuffer->Count;
}
}
void CacheBuffer_Write_Data(CacheBuffer_t *cacheBuffer, uint8_t *pData, uint32_t len) {
if (cacheBuffer->pBufCapacity - cacheBuffer->Count < len) {
cacheBuffer->Count = 0;
cacheBuffer->List[cacheBuffer->InIndex].start = cacheBuffer->pBuf;
} else {
cacheBuffer->List[cacheBuffer->InIndex].start = cacheBuffer->pBuf + cacheBuffer->Count;
}
CACHE_BUFFER_MEMCPY(cacheBuffer->List[cacheBuffer->InIndex].start, pData, len);
cacheBuffer->Count += len;
cacheBuffer->List[cacheBuffer->InIndex].end = cacheBuffer->pBuf + cacheBuffer->Count - 1;
cacheBuffer->InIndex++;
if (cacheBuffer->InIndex == CACHE_BUFFER_LIST_LEN) {
cacheBuffer->InIndex = 0;
}
}
uint32_t CacheBuffer_Read_Data(CacheBuffer_t *cacheBuffer, uint8_t *dst) {
CacheIndexPtr_t *ptr;
uint32_t len = 0;
if (cacheBuffer->OutIndex != cacheBuffer->InIndex) {
ptr = &cacheBuffer->List[cacheBuffer->OutIndex];
len = ptr->end - ptr->start + 1;
CACHE_BUFFER_MEMCPY(dst, ptr->start, len);
cacheBuffer->OutIndex++;
if (cacheBuffer->OutIndex == CACHE_BUFFER_LIST_LEN) {
cacheBuffer->OutIndex = 0;
}
}
return len;
}