BT04A蓝牙模块驱动程序

BT04A蓝牙模块驱动库 - 轻量级、跨平台的嵌入式蓝牙解决方案

BT04A模块简介

BT04A是一款基于蓝牙4.0协议的经典串口透传模块,以其稳定性高、成本低廉、使用简单等特点在嵌入式领域广受欢迎。该模块采用CSR主流蓝牙芯片,支持SPP蓝牙串口协议,能够为传统设备快速添加无线通信功能。

模块特性

  • 蓝牙版本: 蓝牙4.0,兼容蓝牙2.1/3.0设备

  • 工作模式: 支持主从模式一体,可通过AT命令切换

  • 传输距离: 空旷环境下可达10米以上

  • 接口类型: UART串口接口,支持1200-115200bps波特率

  • 供电电压: 3.3V DC,低功耗设计

  • 工作温度: -40℃ ~ +85℃,工业级稳定性

典型应用

  • 工业设备数据无线传输

  • 智能家居控制模块

  • 医疗仪器数据采集

  • 车载设备通信

  • 教学实验设备

驱动库概述

本驱动库为BT04A蓝牙模块提供了完整的嵌入式软件解决方案,采用硬件抽象层设计,支持多种MCU平台,提供简单易用的API接口。

主要特性

🔧 核心功能

  • 双模式支持: 同时支持主模式(Master)和从模式(Slave)工作

  • 灵活配置: 支持设备名称、PIN码、波特率等参数动态配置

  • AT命令集: 完整的AT命令控制接口,支持模块所有功能配置

🚀 性能优势

  • 轻量级设计: 代码体积小,资源占用低,适合资源受限的嵌入式环境

  • 超时重试: 内置超时检测和自动重试机制,提高通信可靠性

  • 异步处理: 非阻塞式设计,支持在实时操作系统中使用

🔌 硬件抽象

  • 平台无关: 通过回调函数机制实现与硬件平台的解耦

  • 引脚抽象: 统一的GPIO控制接口,支持多种MCU架构

  • 串口适配: 灵活的串口数据传输接口,易于集成到现有项目

快速开始

1. 初始化操作接口

// 定义操作回调函数
bt04a_ops_t ops = {
    .send_data = uart_send_data,
    .receive_data = uart_receive_data,
    .delay_ms = hal_delay_ms,
    .clear_rx_data = uart_clear_rx,
    .set_pin = gpio_set_pin,
    .read_pin = gpio_read_pin
};

// 初始化操作接口
bt04a_ops_init(&ops);

2. 配置模块参数

// 模块配置
bt04a_config_t config = {
    .device_name = "MyBT04A",
    .pin_code = "1234",
    .baudrate = BT04A_BAUD_9600,
    .mode = BT04A_MODE_SLAVE,
    .en_port = GPIOA,
    .en_pin = GPIO_PIN_0,
    .state_port = GPIOA,
    .state_pin = GPIO_PIN_1,
    .response_timeout_ms = 1000,
    .command_delay_ms = 100
};

// 初始化模块
bt04a_init(&config);

3. 数据收发示例

// 发送数据
uint8_t data[] = "Hello Bluetooth!";
bt04a_send_data(data, strlen(data));

// 接收数据
uint8_t buffer[256];
uint16_t len = bt04a_receive_data(buffer, sizeof(buffer));

// 格式化输出
bt04a_printf("Temperature: %.2f C\r\n", temperature);

API功能分类

初始化管理

  • bt04a_ops_init()- 初始化操作回调函数

  • bt04a_init()- 初始化蓝牙模块

  • bt04a_deinit()- 释放模块资源

配置管理

  • bt04a_set_name()- 设置设备名称

  • bt04a_set_pin()- 设置PIN码

  • bt04a_set_baudrate()- 设置通信波特率

  • bt04a_set_mode()- 设置主从模式

状态监控

  • bt04a_get_connection_state()- 获取连接状态

  • bt04a_is_connected()- 检查连接状态

  • bt04a_test_connection()- 测试模块连接

数据通信

  • bt04a_send_data()- 发送原始数据

  • bt04a_send_string()- 发送字符串

  • bt04a_printf()- 格式化发送

  • bt04a_receive_data()- 接收数据

  • bt04a_test_connection()- 测试模块连接

架构改进建议

本例使用的是静态全局变量的设计模式,优点是使用比较简单,缺点也很明显发,一次只能使用一个实例并且存在线程不安全的隐患等等。对于改进建议可以把函数改成传入句柄结构体的方式,把操作结构体和配置结构体合并。

源代码及其使用示例

驱动源文件

/**
  ******************************************************************************
  * @file    bt04a_driver.c
  * @author
  * @brief   BT04A蓝牙模块驱动源文件
  * @version V2.0.0
  * @date    2025
  ******************************************************************************
  * @attention
  *
  * 本文件实现BT04A蓝牙模块的完整驱动功能,包括:
  *
  * 基础功能实现:
  * - AT指令测试和模块检测
  * - 工作模式设置(主从模式)
  * - 设备名称和PIN码配置
  * - 波特率设置和验证
  * - 模块初始化和去初始化
  *
  * 连接管理实现:
  * - 连接状态检测和监控
  * - 配对过程管理
  * - 连接建立和断开处理
  *
  * AT命令处理实现:
  * - AT指令封装和发送
  * - 响应数据解析和验证
  * - 超时处理和错误重试
  * - 状态检测和反馈
  *
  * 硬件控制实现:
  * - 使能引脚控制
  * - 状态引脚读取
  * - 模块复位功能
  *
  * 主要特性:
  * - 支持主从模式工作
  * - 灵活的回调函数机制
  * - 完整的错误处理和重试
  * - 统一的API接口实现
  * - 高效的数据传输支持
  * - 与底层HAL库完全解耦
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include <stdint.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdbool.h>

#include "bt04a_driver.h"
#include "debug_log.h"

/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/

/** @defgroup BT04A_AT_Commands BT04A AT命令定义
  * @{
  */
#define BT04A_AT_TEST               "AT"                    /*!< AT测试命令 */
#define BT04A_AT_NAME               "AT+NAME"               /*!< 设置设备名称命令 */
#define BT04A_AT_PIN                "AT+PIN"                /*!< 设置PIN码命令 */
#define BT04A_AT_BAUD               "AT+BAUD"               /*!< 设置波特率命令 */
#define BT04A_AT_ROLE               "AT+ROLE"               /*!< 设置工作模式命令 */
#define BT04A_AT_VERSION            "AT+VERSION"            /*!< 查询版本信息命令 */
#define BT04A_AT_RESET              "AT+RESET"              /*!< 复位命令 */
#define BT04A_AT_ORGL               "AT+ORGL"               /*!< 恢复出厂设置命令 */
/**
  * @}
  */

/** @defgroup BT04A_AT_Responses BT04A AT响应定义
  * @{
  */
#define BT04A_RESPONSE_OK           "OK"                    /*!< 成功响应 */
#define BT04A_RESPONSE_ERROR        "ERROR"                 /*!< 错误响应 */
#define BT04A_RESPONSE_FAIL         "FAIL"                  /*!< 失败响应 */
/**
  * @}
  */

/** @defgroup BT04A_Debug_Config BT04A调试配置
  * @{
  */
#if !defined(LOG_INFO)
    #define LOG_INFO(...) ((void)0)
#endif

#if !defined(LOG_ERROR)
    #define LOG_ERROR(...) ((void)0)
#endif
/**
  * @}
  */

/* Private macro -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/

/** @defgroup BT04A_Private_Variables BT04A私有变量
  * @{
  */
static bt04a_ops_t g_bt04a_ops;                         /*!< BT04A操作回调函数结构体 */
static bt04a_config_t g_bt04a_config;                   /*!< BT04A配置结构体 */
static bool g_bt04a_initialized = false;                /*!< BT04A初始化标志 */
/**
  * @}
  */

/* Exported variables --------------------------------------------------------*/

/* Private function prototypes -----------------------------------------------*/
static bt04a_result_t bt04a_send_at_command(const char *cmd, char *response, uint16_t timeout_ms);
static bt04a_result_t bt04a_at_test(void);
static bt04a_result_t bt04a_set_role_internal(bt04a_mode_t mode);
static bt04a_result_t bt04a_set_baudrate_internal(bt04a_baudrate_t baudrate);
static bt04a_result_t bt04a_set_name_internal(const char *name);
static bt04a_result_t bt04a_set_pin_internal(const char *pin);
static bool bt04a_check_response(const char *response, const char *expected);
static void bt04a_hardware_enable(bool enable);
static bool bt04a_read_state_pin(void);

/* Exported functions --------------------------------------------------------*/

/** @defgroup BT04A_Exported_Functions BT04A导出函数
  * @{
  */

/** @defgroup BT04A_Init_Functions BT04A初始化函数
  * @{
  */

/**
  * @brief  初始化BT04A操作回调函数
  * @param  ops: 回调函数结构体指针
  * @retval BT04A_OK: 初始化成功, BT04A_ERROR: 初始化失败
  * @note   必须在使用BT04A其他功能前调用此函数配置底层操作接口
  */
bt04a_result_t bt04a_ops_init(bt04a_ops_t *ops)
{
    if (ops == NULL)
    {
        return BT04A_ERROR;
    }

    // 检查必要的回调函数是否存在
    if (ops->send_data == NULL || ops->receive_data == NULL || ops->delay_ms == NULL)
    {
        return BT04A_ERROR;
    }

    // 复制回调函数
    g_bt04a_ops.send_data = ops->send_data;
    g_bt04a_ops.receive_data = ops->receive_data;
    g_bt04a_ops.delay_ms = ops->delay_ms;
    g_bt04a_ops.clear_rx_data = ops->clear_rx_data;
    g_bt04a_ops.set_pin = ops->set_pin;
    g_bt04a_ops.read_pin = ops->read_pin;

    return BT04A_OK;
}

/**
  * @brief  初始化BT04A蓝牙模块
  * @param  config: 配置结构体指针
  * @retval BT04A_OK: 初始化成功, BT04A_ERROR: 初始化失败
  * @note   初始化BT04A模块并配置相关参数
  */
bt04a_result_t bt04a_init(const bt04a_config_t *config)
{
    if (config == NULL)
    {
        LOG_ERROR("BT04A配置参数为空\r\n");
        return BT04A_ERROR;
    }

    // 检查回调函数是否已初始化
    if (g_bt04a_ops.send_data == NULL)
    {
        LOG_ERROR("BT04A回调函数未初始化\r\n");
        return BT04A_ERROR;
    }

    LOG_INFO("BT04A初始化开始...\r\n");

    // 复制配置参数
    memcpy(&g_bt04a_config, config, sizeof(bt04a_config_t));

    // 硬件使能
    bt04a_hardware_enable(true);
    g_bt04a_ops.delay_ms(100);

    // 清除接收缓冲区
    if (g_bt04a_ops.clear_rx_data != NULL)
    {
        g_bt04a_ops.clear_rx_data();
    }

    // 测试AT命令
    LOG_INFO("1. 测试BT04A是否响应...\r\n");
    if (bt04a_at_test() != BT04A_OK)
    {
        LOG_ERROR("BT04A AT测试失败\r\n");
        return BT04A_ERROR;
    }

    // 设置工作模式
    LOG_INFO("2. 设置工作模式...\r\n");
    // 有些模块无法设置模式
//    if (bt04a_set_role_internal(config->mode) != BT04A_OK)
//    {
//        LOG_ERROR("BT04A工作模式设置失败\r\n");
//        return BT04A_ERROR;
//    }

    // 设置设备名称
    LOG_INFO("3. 设置设备名称...\r\n");
    if (bt04a_set_name_internal(config->device_name) != BT04A_OK)
    {
        LOG_ERROR("BT04A设备名称设置失败\r\n");
        return BT04A_ERROR;
    }

    // 设置PIN码
    LOG_INFO("4. 设置PIN码...\r\n");
    if (bt04a_set_pin_internal(config->pin_code) != BT04A_OK)
    {
        LOG_ERROR("BT04A PIN码设置失败\r\n");
        return BT04A_ERROR;
    }

    // 设置波特率
    LOG_INFO("5. 设置波特率...\r\n");
    if (bt04a_set_baudrate_internal(config->baudrate) != BT04A_OK)
    {
        LOG_ERROR("BT04A波特率设置失败\r\n");
        return BT04A_ERROR;
    }

    g_bt04a_initialized = true;
    LOG_INFO("BT04A初始化完成\r\n");

    return BT04A_OK;
}

/**
  * @brief  去初始化BT04A蓝牙模块
  * @param  无
  * @retval BT04A_OK: 去初始化成功
  * @note   关闭BT04A模块并清理资源
  */
bt04a_result_t bt04a_deinit(void)
{
    // 硬件禁用
    bt04a_hardware_enable(false);

    // 清除初始化标志
    g_bt04a_initialized = false;

    // 清零配置
    memset(&g_bt04a_config, 0, sizeof(bt04a_config_t));

    LOG_INFO("BT04A去初始化完成\r\n");

    return BT04A_OK;
}

/**
  * @}
  */

/** @defgroup BT04A_Config_Functions BT04A配置函数
  * @{
  */

/**
  * @brief  设置BT04A设备名称
  * @param  name: 设备名称字符串
  * @retval BT04A_OK: 设置成功, BT04A_ERROR: 设置失败
  * @note   设置BT04A的蓝牙设备名称
  */
bt04a_result_t bt04a_set_name(const char *name)
{
    if (!g_bt04a_initialized || name == NULL)
    {
        return BT04A_ERROR;
    }

    if (strlen(name) >= BT04A_MAX_NAME_LEN)
    {
        return BT04A_ERROR;
    }

    bt04a_result_t result = bt04a_set_name_internal(name);
    if (result == BT04A_OK)
    {
        strcpy(g_bt04a_config.device_name, name);
    }

    return result;
}

/**
  * @brief  设置BT04A PIN码
  * @param  pin: PIN码字符串
  * @retval BT04A_OK: 设置成功, BT04A_ERROR: 设置失败
  * @note   设置BT04A的配对PIN码
  */
bt04a_result_t bt04a_set_pin(const char *pin)
{
    if (!g_bt04a_initialized || pin == NULL)
    {
        return BT04A_ERROR;
    }

    if (strlen(pin) >= BT04A_MAX_PIN_LEN)
    {
        return BT04A_ERROR;
    }

    bt04a_result_t result = bt04a_set_pin_internal(pin);
    if (result == BT04A_OK)
    {
        strcpy(g_bt04a_config.pin_code, pin);
    }

    return result;
}

/**
  * @brief  设置BT04A波特率
  * @param  baudrate: 波特率枚举值
  * @retval BT04A_OK: 设置成功, BT04A_ERROR: 设置失败
  * @note   设置BT04A的通信波特率
  */
bt04a_result_t bt04a_set_baudrate(bt04a_baudrate_t baudrate)
{
    if (!g_bt04a_initialized)
    {
        return BT04A_ERROR;
    }

    bt04a_result_t result = bt04a_set_baudrate_internal(baudrate);
    if (result == BT04A_OK)
    {
        g_bt04a_config.baudrate = baudrate;
    }

    return result;
}

/**
  * @brief  设置BT04A工作模式
  * @param  mode: 工作模式枚举值
  * @retval BT04A_OK: 设置成功, BT04A_ERROR: 设置失败
  * @note   设置BT04A的主从工作模式
  */
bt04a_result_t bt04a_set_mode(bt04a_mode_t mode)
{
    if (!g_bt04a_initialized)
    {
        return BT04A_ERROR;
    }

    bt04a_result_t result = bt04a_set_role_internal(mode);
    if (result == BT04A_OK)
    {
        g_bt04a_config.mode = mode;
    }

    return result;
}

/**
  * @brief  获取BT04A当前配置
  * @param  config: 配置结构体指针
  * @retval BT04A_OK: 获取成功, BT04A_ERROR: 获取失败
  * @note   获取BT04A的当前配置参数
  */
bt04a_result_t bt04a_get_config(bt04a_config_t *config)
{
    if (!g_bt04a_initialized || config == NULL)
    {
        return BT04A_ERROR;
    }

    memcpy(config, &g_bt04a_config, sizeof(bt04a_config_t));

    return BT04A_OK;
}

/**
  * @}
  */

/** @defgroup BT04A_Control_Functions BT04A控制函数
  * @{
  */

/**
  * @brief  进入AT命令模式
  * @param  无
  * @retval BT04A_OK: 进入成功, BT04A_ERROR: 进入失败
  * @note   使BT04A进入AT命令配置模式
  */
bt04a_result_t bt04a_enter_at_mode(void)
{
    if (!g_bt04a_initialized)
    {
        return BT04A_ERROR;
    }

    // BT04A默认就在AT模式,只需要测试连接
    return bt04a_at_test();
}

/**
  * @brief  退出AT命令模式
  * @param  无
  * @retval BT04A_OK: 退出成功
  * @note   使BT04A退出AT命令模式进入数据传输模式
  */
bt04a_result_t bt04a_exit_at_mode(void)
{
    if (!g_bt04a_initialized)
    {
        return BT04A_ERROR;
    }

    // BT04A在没有连接时自动处于AT模式,连接后自动进入数据模式
    return BT04A_OK;
}

/**
  * @brief  复位BT04A模块
  * @param  无
  * @retval BT04A_OK: 复位成功, BT04A_ERROR: 复位失败
  * @note   软件复位BT04A模块
  */
bt04a_result_t bt04a_reset(void)
{
    if (!g_bt04a_initialized)
    {
        return BT04A_ERROR;
    }

    char response[64];
    bt04a_result_t result = bt04a_send_at_command(BT04A_AT_RESET, response, g_bt04a_config.response_timeout_ms);

    if (result == BT04A_OK)
    {
        // 复位后需要等待模块重新启动
        g_bt04a_ops.delay_ms(1000);
        LOG_INFO("BT04A复位完成\r\n");
    }

    return result;
}

/**
  * @brief  使能/禁用BT04A模块
  * @param  enable: true-使能, false-禁用
  * @retval BT04A_OK: 操作成功, BT04A_ERROR: 操作失败
  * @note   通过硬件引脚控制BT04A模块的使能状态
  */
bt04a_result_t bt04a_enable(bool enable)
{
    if (!g_bt04a_initialized)
    {
        return BT04A_ERROR;
    }

    bt04a_hardware_enable(enable);

    if (enable)
    {
        g_bt04a_ops.delay_ms(100);  // 使能后等待模块启动
        LOG_INFO("BT04A模块已使能\r\n");
    }
    else
    {
        LOG_INFO("BT04A模块已禁用\r\n");
    }

    return BT04A_OK;
}

/**
  * @}
  */

/** @defgroup BT04A_Status_Functions BT04A状态函数
  * @{
  */

/**
  * @brief  获取BT04A连接状态
  * @param  无
  * @retval bt04a_state_t: 连接状态枚举值
  * @note   通过状态引脚读取BT04A的连接状态
  */
bt04a_state_t bt04a_get_connection_state(void)
{
    if (!g_bt04a_initialized)
    {
        return BT04A_STATE_UNKNOWN;
    }

    // 通过状态引脚读取连接状态
    if (bt04a_read_state_pin())
    {
        return BT04A_STATE_CONNECTED;
    }
    else
    {
        return BT04A_STATE_DISCONNECTED;
    }
}

/**
  * @brief  测试BT04A连接
  * @param  无
  * @retval BT04A_OK: 连接正常, BT04A_ERROR: 连接异常
  * @note   通过AT命令测试BT04A模块的连接状态
  */
bt04a_result_t bt04a_test_connection(void)
{
    if (!g_bt04a_initialized)
    {
        return BT04A_ERROR;
    }

    return bt04a_at_test();
}

/**
  * @brief  检查BT04A是否已连接
  * @param  无
  * @retval true: 已连接, false: 未连接
  * @note   检查BT04A是否与其他设备建立了蓝牙连接
  */
bool bt04a_is_connected(void)
{
    return (bt04a_get_connection_state() == BT04A_STATE_CONNECTED);
}

/**
  * @}
  */

/** @defgroup BT04A_Data_Functions BT04A数据函数
  * @{
  */

/**
  * @brief  发送数据
  * @param  data: 数据缓冲区指针
  * @param  len: 数据长度
  * @retval BT04A_OK: 发送成功, BT04A_ERROR: 发送失败
  * @note   通过BT04A发送数据
  */
bt04a_result_t bt04a_send_data(const uint8_t *data, uint16_t len)
{
    if (!g_bt04a_initialized || data == NULL || len == 0)
    {
        return BT04A_ERROR;
    }

    g_bt04a_ops.send_data(data, len);

    return BT04A_OK;
}

/**
  * @brief  发送字符串
  * @param  string: 字符串指针
  * @retval BT04A_OK: 发送成功, BT04A_ERROR: 发送失败
  * @note   通过BT04A发送字符串数据
  */
bt04a_result_t bt04a_send_string(const char *string)
{
    if (!g_bt04a_initialized || string == NULL)
    {
        return BT04A_ERROR;
    }

    uint16_t len = strlen(string);
    return bt04a_send_data((const uint8_t *)string, len);
}

/**
  * @brief  通过BT04A蓝牙模块发送格式化字符串
  * @param  format: 格式化字符串
  * @param  ...: 可变参数列表
  * @retval 发送的字符数,失败返回-1
  * @note   类似printf函数,将格式化后的字符串通过蓝牙发送
  */
int bt04a_printf(const char *format, ...)
{
    char buffer[256];  // 定义缓冲区,根据需要调整大小
    va_list args;
    int len;

    if (!g_bt04a_initialized || format == NULL)
    {
        return -1;
    }

    // 格式化字符串
    va_start(args, format);
    len = vsnprintf(buffer, sizeof(buffer), format, args);
    va_end(args);

    // 检查格式化是否成功
    if (len < 0 || len >= sizeof(buffer))
    {
        return -1;
    }

    // 通过BT04A发送字符串
    if (bt04a_send_string(buffer) == BT04A_OK)
    {
        return len;
    }
    else
    {
        return -1;
    }
}

/**
  * @brief  接收数据
  * @param  buffer: 接收缓冲区指针
  * @param  max_len: 缓冲区最大长度
  * @retval 实际接收的数据长度
  * @note   从BT04A接收数据
  */
uint16_t bt04a_receive_data(uint8_t *buffer, uint16_t max_len)
{
    if (!g_bt04a_initialized || buffer == NULL || max_len == 0)
    {
        return 0;
    }

    return g_bt04a_ops.receive_data(buffer, max_len);
}

/**
  * @brief  清除接收缓冲区
  * @param  无
  * @retval 无
  * @note   清除BT04A的接收缓冲区
  */
void bt04a_clear_buffer(void)
{
    if (g_bt04a_initialized && g_bt04a_ops.clear_rx_data != NULL)
    {
        g_bt04a_ops.clear_rx_data();
    }
}

/**
  * @}
  */

/**
  * @}
  */

/* Private functions ---------------------------------------------------------*/

/**
  * @brief  发送AT命令并等待响应
  * @param  cmd: AT命令字符串
  * @param  response: 响应缓冲区
  * @param  timeout_ms: 超时时间(毫秒)
  * @retval BT04A_OK: 命令执行成功, BT04A_ERROR: 命令执行失败, BT04A_TIMEOUT: 超时
  * @note   发送AT命令到BT04A并等待响应
  */
static bt04a_result_t bt04a_send_at_command(const char *cmd, char *response, uint16_t timeout_ms)
{
    if (cmd == NULL)
    {
        return BT04A_ERROR;
    }

    // 清除接收缓冲区
    if (g_bt04a_ops.clear_rx_data != NULL)
    {
        g_bt04a_ops.clear_rx_data();
    }

    // 发送AT命令
    char at_cmd[64];
    snprintf(at_cmd, sizeof(at_cmd), "%s\r\n", cmd);
    g_bt04a_ops.send_data((const uint8_t *)at_cmd, strlen(at_cmd));

    // 等待响应
    uint32_t start_time = 0;
    uint16_t received_len = 0;
    uint8_t g_bt04a_rx_buffer[BT04A_BUFFER_SIZE] = {0};

    while (start_time < timeout_ms)
    {
        received_len = g_bt04a_ops.receive_data(g_bt04a_rx_buffer, BT04A_BUFFER_SIZE - 1);

        if (received_len > 0)
        {
            g_bt04a_rx_buffer[received_len] = '\0';

            if (response != NULL)
            {
                strcpy(response, (char *)g_bt04a_rx_buffer);
            }

            // 检查响应
            if (bt04a_check_response((char *)g_bt04a_rx_buffer, BT04A_RESPONSE_OK))
            {
                return BT04A_OK;
            }
            else if (bt04a_check_response((char *)g_bt04a_rx_buffer, BT04A_RESPONSE_ERROR) ||
                     bt04a_check_response((char *)g_bt04a_rx_buffer, BT04A_RESPONSE_FAIL))
            {
                return BT04A_ERROR;
            }
        }

        g_bt04a_ops.delay_ms(10);
        start_time += 10;
    }

    return BT04A_TIMEOUT;
}

/**
  * @brief  AT测试命令
  * @param  无
  * @retval BT04A_OK: 测试成功, BT04A_ERROR: 测试失败
  * @note   发送AT测试命令检查模块响应
  */
static bt04a_result_t bt04a_at_test(void)
{
    char response[64];
    return bt04a_send_at_command(BT04A_AT_TEST, response, g_bt04a_config.response_timeout_ms);
}

/**
  * @brief  设置工作模式内部函数
  * @param  mode: 工作模式
  * @retval BT04A_OK: 设置成功, BT04A_ERROR: 设置失败
  * @note   内部函数,设置BT04A的工作模式
  */
static bt04a_result_t bt04a_set_role_internal(bt04a_mode_t mode)
{
    char cmd[32];
    char response[64];

    snprintf(cmd, sizeof(cmd), "%s%d", BT04A_AT_ROLE, (int)mode);

    bt04a_result_t result = bt04a_send_at_command(cmd, response, g_bt04a_config.response_timeout_ms);

    if (result == BT04A_OK)
    {
        g_bt04a_ops.delay_ms(g_bt04a_config.command_delay_ms);
    }

    return result;
}

/**
  * @brief  设置波特率内部函数
  * @param  baudrate: 波特率
  * @retval BT04A_OK: 设置成功, BT04A_ERROR: 设置失败
  * @note   内部函数,设置BT04A的波特率
  */
static bt04a_result_t bt04a_set_baudrate_internal(bt04a_baudrate_t baudrate)
{
    char cmd[32];
    char response[64];
    int baud_code;

    // 将波特率转换为BT04A的编码
    switch (baudrate)
    {
        case BT04A_BAUD_1200:
            baud_code = 1;
            break;
        case BT04A_BAUD_2400:
            baud_code = 2;
            break;
        case BT04A_BAUD_4800:
            baud_code = 3;
            break;
        case BT04A_BAUD_9600:
            baud_code = 4;
            break;
        case BT04A_BAUD_19200:
            baud_code = 5;
            break;
        case BT04A_BAUD_38400:
            baud_code = 6;
            break;
        case BT04A_BAUD_57600:
            baud_code = 7;
            break;
        case BT04A_BAUD_115200:
            baud_code = 8;
            break;
        default:
            return BT04A_ERROR;
    }

    snprintf(cmd, sizeof(cmd), "%s%d", BT04A_AT_BAUD, baud_code);

    bt04a_result_t result = bt04a_send_at_command(cmd, response, g_bt04a_config.response_timeout_ms);

    if (result == BT04A_OK)
    {
        g_bt04a_ops.delay_ms(g_bt04a_config.command_delay_ms);
    }

    return result;
}

/**
  * @brief  设置设备名称内部函数
  * @param  name: 设备名称
  * @retval BT04A_OK: 设置成功, BT04A_ERROR: 设置失败
  * @note   内部函数,设置BT04A的设备名称
  */
static bt04a_result_t bt04a_set_name_internal(const char *name)
{
    char cmd[64];
    char response[64];

    snprintf(cmd, sizeof(cmd), "%s%s", BT04A_AT_NAME, name);

    bt04a_result_t result = bt04a_send_at_command(cmd, response, g_bt04a_config.response_timeout_ms);

    if (result == BT04A_OK)
    {
        g_bt04a_ops.delay_ms(g_bt04a_config.command_delay_ms);
    }

    return result;
}

/**
  * @brief  设置PIN码内部函数
  * @param  pin: PIN码
  * @retval BT04A_OK: 设置成功, BT04A_ERROR: 设置失败
  * @note   内部函数,设置BT04A的PIN码
  */
static bt04a_result_t bt04a_set_pin_internal(const char *pin)
{
    char cmd[32];
    char response[64];

    snprintf(cmd, sizeof(cmd), "%s%s", BT04A_AT_PIN, pin);

    bt04a_result_t result = bt04a_send_at_command(cmd, response, g_bt04a_config.response_timeout_ms);

    if (result == BT04A_OK)
    {
        g_bt04a_ops.delay_ms(g_bt04a_config.command_delay_ms);
    }

    return result;
}

/**
  * @brief  检查AT命令响应
  * @param  response: 响应字符串
  * @param  expected: 期望的响应
  * @retval true: 响应匹配, false: 响应不匹配
  * @note   检查AT命令的响应是否符合预期
  */
static bool bt04a_check_response(const char *response, const char *expected)
{
    if (response == NULL || expected == NULL)
    {
        return false;
    }

    return (strstr(response, expected) != NULL);
}

/**
  * @brief  硬件使能控制
  * @param  enable: true-使能, false-禁用
  * @retval 无
  * @note   通过硬件引脚控制BT04A模块的使能状态
  */
static void bt04a_hardware_enable(bool enable)
{
    if (g_bt04a_ops.set_pin != NULL && g_bt04a_config.en_port != NULL)
    {
        g_bt04a_ops.set_pin(g_bt04a_config.en_port, g_bt04a_config.en_pin, enable);
    }
}

/**
  * @brief  读取状态引脚
  * @param  无
  * @retval true: 高电平, false: 低电平
  * @note   读取BT04A模块的状态引脚电平
  */
static bool bt04a_read_state_pin(void)
{
    if (g_bt04a_ops.read_pin != NULL && g_bt04a_config.state_port != NULL)
    {
        return g_bt04a_ops.read_pin(g_bt04a_config.state_port, g_bt04a_config.state_pin);
    }

    return false;
}

驱动头文件

/**
  ******************************************************************************
  * @file    bt04a_driver.h
  * @author  
  * @brief   BT04A蓝牙模块驱动头文件
  * @version V2.0.0
  * @date    2025
  ******************************************************************************
  * @attention
  *
  * 本文件提供BT04A蓝牙模块的完整驱动接口,支持以下功能:
  * 
  * 基础功能:
  * - 蓝牙模块初始化与配置
  * - AT命令模式控制
  * - 设备名称和PIN码设置
  * - 波特率配置
  * - 工作模式设置(主从模式)
  * 
  * 连接管理:
  * - 连接状态检测
  * - 配对管理
  * - 连接建立与断开
  * 
  * 硬件控制:
  * - 使能引脚控制
  * - 状态引脚检测
  * - 模块复位功能
  * 
  * 主要特性:
  * - 支持主从模式工作
  * - 灵活的回调函数机制
  * - 完整的错误处理
  * - 统一的API接口设计
  * - 与底层HAL库解耦
  *
  ******************************************************************************
  */

#ifndef _BT04A_DRIVER_H
#define _BT04A_DRIVER_H

/* Includes ------------------------------------------------------------------*/
#include <stdint.h>
#include <stdbool.h>

/* Exported types ------------------------------------------------------------*/

/**
 * @brief BT04A操作回调函数结构体
 * @note  用于配置BT04A模块的底层操作接口
 */
typedef struct
{
    void (*send_data)(const uint8_t *p_data, uint16_t size);        /*!< 数据发送函数指针 */
    uint16_t (*receive_data)(uint8_t *p_data, uint16_t size);       /*!< 数据接收函数指针 */
    void (*delay_ms)(uint32_t ms);                                  /*!< 毫秒延时函数指针 */
    void (*clear_rx_data)(void);                                    /*!< 清除接收数据函数指针 */
    void (*set_pin)(void *port, uint16_t pin, bool state);          /*!< GPIO引脚设置函数指针 */
    bool (*read_pin)(void *port, uint16_t pin);                     /*!< GPIO引脚读取函数指针 */
} bt04a_ops_t;

/**
 * @brief BT04A操作结果枚举类型
 * @note  用于表示BT04A各种操作的执行结果
 */
typedef enum
{
    BT04A_OK = 0,       /*!< 操作成功 */
    BT04A_ERROR = 1,    /*!< 操作失败 */
    BT04A_TIMEOUT = 2,  /*!< 操作超时 */
    BT04A_BUSY = 3,     /*!< 模块忙碌 */
} bt04a_result_t;

/**
 * @brief BT04A工作模式枚举
 */
typedef enum
{
    BT04A_MODE_SLAVE = 0,   /*!< 从机模式 */
    BT04A_MODE_MASTER = 1,  /*!< 主机模式 */
} bt04a_mode_t;

/**
 * @brief BT04A波特率枚举
 */
typedef enum
{
    BT04A_BAUD_1200 = 1200,     /*!< 1200bps */
    BT04A_BAUD_2400 = 2400,     /*!< 2400bps */
    BT04A_BAUD_4800 = 4800,     /*!< 4800bps */
    BT04A_BAUD_9600 = 9600,     /*!< 9600bps */
    BT04A_BAUD_19200 = 19200,   /*!< 19200bps */
    BT04A_BAUD_38400 = 38400,   /*!< 38400bps */
    BT04A_BAUD_57600 = 57600,   /*!< 57600bps */
    BT04A_BAUD_115200 = 115200, /*!< 115200bps */
} bt04a_baudrate_t;

/**
 * @brief BT04A连接状态枚举
 */
typedef enum
{
    BT04A_STATE_DISCONNECTED = 0,   /*!< 未连接 */
    BT04A_STATE_CONNECTED = 1,      /*!< 已连接 */
    BT04A_STATE_UNKNOWN = 2,        /*!< 状态未知 */
} bt04a_state_t;

/**
 * @brief BT04A配置结构体
 */
typedef struct
{
    char device_name[32];           /*!< 设备名称 */
    char pin_code[16];              /*!< PIN码 */
    bt04a_baudrate_t baudrate;      /*!< 波特率 */
    bt04a_mode_t mode;              /*!< 工作模式 */
    
    /* 硬件控制引脚配置 */
    void *en_port;                  /*!< 使能引脚端口 */
    uint16_t en_pin;                /*!< 使能引脚号 */
    void *state_port;               /*!< 状态引脚端口 */
    uint16_t state_pin;             /*!< 状态引脚号 */
    
    /* 超时配置 */
    uint16_t response_timeout_ms;   /*!< AT命令响应超时时间(ms) */
    uint16_t command_delay_ms;      /*!< AT命令间隔延时(ms) */
} bt04a_config_t;

/* Exported constants --------------------------------------------------------*/

/** @defgroup BT04A_Default_Config BT04A默认配置参数
  * @{
  */
#define BT04A_DEFAULT_NAME          "BT04A"     /*!< 默认设备名称 */
#define BT04A_DEFAULT_PIN           "1234"      /*!< 默认PIN码 */
#define BT04A_DEFAULT_BAUDRATE      BT04A_BAUD_9600     /*!< 默认波特率 */
#define BT04A_DEFAULT_MODE          BT04A_MODE_SLAVE    /*!< 默认工作模式 */
#define BT04A_DEFAULT_TIMEOUT       1000        /*!< 默认超时时间(ms) */
#define BT04A_DEFAULT_DELAY         100         /*!< 默认命令延时(ms) */
/**
  * @}
  */

/** @defgroup BT04A_Buffer_Size BT04A缓冲区大小定义
  * @{
  */
#define BT04A_MAX_NAME_LEN          32          /*!< 最大设备名称长度 */
#define BT04A_MAX_PIN_LEN           16          /*!< 最大PIN码长度 */
#define BT04A_BUFFER_SIZE           256         /*!< 数据缓冲区大小 */
#define BT04A_MAX_LENGTH			BT04A_BUFFER_SIZE
/**
  * @}
  */

/* Exported functions --------------------------------------------------------*/

/** @defgroup BT04A_Init_Functions BT04A初始化函数
  * @{
  */
bt04a_result_t bt04a_ops_init(bt04a_ops_t *ops);
bt04a_result_t bt04a_init(const bt04a_config_t *config);
bt04a_result_t bt04a_deinit(void);
/**
  * @}
  */

/** @defgroup BT04A_Config_Functions BT04A配置函数
  * @{
  */
bt04a_result_t bt04a_set_name(const char *name);
bt04a_result_t bt04a_set_pin(const char *pin);
bt04a_result_t bt04a_set_baudrate(bt04a_baudrate_t baudrate);
bt04a_result_t bt04a_set_mode(bt04a_mode_t mode);
bt04a_result_t bt04a_get_config(bt04a_config_t *config);
/**
  * @}
  */

/** @defgroup BT04A_Control_Functions BT04A控制函数
  * @{
  */
bt04a_result_t bt04a_enter_at_mode(void);
bt04a_result_t bt04a_exit_at_mode(void);
bt04a_result_t bt04a_reset(void);
bt04a_result_t bt04a_enable(bool enable);
/**
  * @}
  */

/** @defgroup BT04A_Status_Functions BT04A状态函数
  * @{
  */
bt04a_state_t bt04a_get_connection_state(void);
bt04a_result_t bt04a_test_connection(void);
bool bt04a_is_connected(void);
/**
  * @}
  */

/** @defgroup BT04A_Data_Functions BT04A数据函数
  * @{
  */
bt04a_result_t bt04a_send_data(const uint8_t *data, uint16_t len);
bt04a_result_t bt04a_send_string(const char *string);
int bt04a_printf(const char *format, ...);
uint16_t bt04a_receive_data(uint8_t *buffer, uint16_t max_len);
void bt04a_clear_buffer(void);
/**
  * @}
  */

#endif /* _BT04A_DRIVER_H */

初始化实例

这里发送数据是单片机串口的发送,接收是单片机串口的接收

#include "uart_driver.h"
#include "debug_log.h"
#include "tim_driver.h"
#include "bt04a_port.h"
#include "bt04a_driver.h"
#include <string.h>


static void bt04a_port_send_data(const uint8_t *p_data, uint16_t size)
{
    uart1_putdatas(p_data, size);
}

static uint16_t bt04a_port_receive_data(uint8_t *p_data, uint16_t size)
{
    return uart1_read_data(p_data, size);
}

static void bt04a_port_clear_buffer(void)
{
    uart_buffer_clear(pg_uart1_handle);
}

bool bt04a_port_init(void)
{
    bool error = false;

    uart1_init(); // 初始化UART1的DMA接收

    // 初始化BT04A蓝牙模块回调函数
    bt04a_ops_t bt04a_ops =
    {
        .send_data = bt04a_port_send_data,
        .receive_data = bt04a_port_receive_data,
        .delay_ms = mdelay,
        .clear_rx_data = bt04a_port_clear_buffer,
        .set_pin = NULL,
        .read_pin = NULL
    };

    // 初始化BT04A操作回调函数
    if (bt04a_ops_init(&bt04a_ops) != BT04A_OK)
    {
        LOG_ERROR("BT04A callback init failed");
    }

    // 配置BT04A蓝牙模块参数
    bt04a_config_t bt04a_config =
    {
        .baudrate = BT04A_BAUD_9600,
        .mode = BT04A_MODE_SLAVE,
        .en_port = NULL,       // 如果不使用使能引脚可设为NULL
        .en_pin = 0,
        .state_port = NULL,    // 如果不使用状态引脚可设为NULL
        .state_pin = 0,
        .response_timeout_ms = BT04A_DEFAULT_TIMEOUT,
        .command_delay_ms = BT04A_DEFAULT_DELAY
    };

    // 复制设备名称和PIN码
    strcpy(bt04a_config.device_name, BT04A_DEFAULT_NAME);
    strcpy(bt04a_config.pin_code, BT04A_DEFAULT_PIN);

    // 初始化BT04A模块
    if (bt04a_init(&bt04a_config) == BT04A_OK)
    {
        LOG_INFO("BT04A module init success");
        error = false;
    }
    else
    {
        LOG_ERROR("BT04A module init failed");
        error = true;
    }

    bt04a_clear_buffer();

    return !error;  // 成功时返回true,失败时返回false
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值