蓝牙4.0BLE协议栈中串口应用详解

蓝牙4.0 BLE协议栈中的串口应用,就像是开发板和电脑之间的一座桥梁,承载着数据交互的重要任务。下面我们将通过生动的比喻,结合代码解读、原理说明以及时序图和流程图,深入理解这部分内容。

串口:数据交互的信使

串口作为开发板和电脑交互的工具,就如同古代传递书信的信使。初始化串口的过程,就像是为信使规划好传递信件的路线和方式,设置波特率如同确定信使的行进速度,中断设置则像是为信使安排的紧急联络机制。而向发送缓冲区发送数据或从接收缓冲区读取数据,就好比将信件放入邮筒或者从邮筒中取出信件。

蓝牙4.0 BLE协议栈:信使的调度中心

在蓝牙4.0 BLE协议栈中,串口的使用有了独特的方式,就如同信使加入了一个专业的调度中心。协议栈提供的三个关键函数HalUARTOpen()、HalUARTRead()、HalUARTWrite(),分别承担着打开通道、读取信件内容、发送信件的职责。

串口收发实验:信使的工作演练

以SimpleBLEPeripheral示例工程为基础的串口收发实验,就像是信使的一场工作演练。

  • 代码解读

    • 在"SimpleBLEPeripheral.c"文件中添加的代码,首先定义了一个数组uartbuf用于存储接收到的数据,就像准备了一个专门的信件收纳袋。rxCb函数作为回调函数,当有数据接收事件发生时,就会被调用,类似于信使收到新信件时的响应机制。
    c 复制代码
    #include "hal_uart.h"
    unsigned char uartbuf[152] ;
    static void rxCb(uint8 port,uint8 event)
    {
    HalUARTRead(0, uartbuf,19) ;//从串口读取19个数据存到uartbuf数组,如同从邮筒取出信件放入收纳袋
    if(osal_memcmp(uartbuf,"BLE_stack_uart_test",19))//判断接收的数据是否是指定字符串
      {
      HalUARTWrite(0, uartbuf,19) ;//将接收到的数据再发送出去,如同将信件原封不动地转发
      osal_memset( uartbuf,0,19);//清空数组,为下一次接收做准备,如同清空收纳袋
      }
    }
    • SimpleBLEPeripheral_Init()函数中添加的代码,用于配置串口参数并打开串口。halUARTCfg_t结构体就像是调度中心的任务配置表,包含了串口初始化所需的各种参数,如是否已配置、波特率、流控等。
    c 复制代码
    halUARTCfg_t uartConfig;
    uartConfig.configured    = TRUE;
    uartConfig.baudRate     = HAL_UART_BR_115200;
    uartConfig.flowControl = FALSE;
    uartConfig.callBackFunc = rxCb ;
    HalUARTOpen (0, &uartConfig);//根据配置表打开串口通道,如同为信使开启工作路径
  • 回调函数揭秘 :回调函数rxCb就像是信使的一个特殊任务指令。当特定的事件(如数据接收)发生时,系统会通过函数指针调用这个回调函数,就好比调度中心在特定情况下向信使下达特殊任务。定义和使用回调函数的过程如下:

    • 定义回调函数rxCb,编写数据接收和处理的逻辑。
    • 在初始化时,将rxCb函数的指针传递给uartConfigcallBackFunc成员,完成回调函数的注册,就像将任务指令交给调度中心备案。
    • 当数据接收事件发生,系统通过callBackFunc调用rxCb函数,执行相应操作。

实例测试:信使工作的检验

将程序编译下载到CC2540开发板并进行实例测试,就像是对信使工作的一次实际检验。当发现接收栏没有显示数据时,就如同信使在传递信件过程中出现了问题。经过排查发现,是因为蓝牙4.0 BLE协议栈的条件编译,没有正确开启UART功能,就好比没有为信使打开正确的工作通道。通过在IAR开发环境中定义HAL_UART=TRUE宏,就像是为信使打通了道路,从而使数据能够正常收发。

串口工作原理剖析:信使的工作机制

  • 串口初始化HalUARTOpen()函数就像是调度中心的总开关,根据不同的条件(如是否使用DMA、ISR等)调用不同的初始化函数,如HalUARTOpenDMA()。在HalUARTOpenDMA()函数中,对串口波特率的初始化就像是为信使设定行进速度,根据halUARTCfg_t结构体中baudRate的值,参考CC2540数据手册中的对应值,使用switch-case语句进行设置。同时,对DMA接收缓冲区的初始化,就像是为接收信件准备好仓库。

    c 复制代码
    static void HalUARTOpenDMA(halUARTCfg_t *config)
    {
    dmaCfg.uartCB = config->callBackFunc;
    if (config->baudRate == HAL_UART_BR_57600 ||
        config->baudRate == HAL_UART_BR_115200)
    {
        UxBAUD = 216;
    }
    else
    {
        UxBAUD = 59;
    }
    switch (config->baudRate)
    {
        case HAL_UART_BR_9600:
            UxGCR = 8;
            dmaCfg.txTick = 35;
            break;
        //其他波特率设置情况类似
    }
    dmaCfg.rxBuf[0] = *(volatile uint8 *)DMA_UDBUF;
    HAL_DMA_CLEAR_IRQ(HAL_DMA_CH_RX);
    HAL_DMA_ARM_IRQ(HAL_DMA_CH_RX);
    HAL_DMA_ARM_CH(HAL_DMA_CH_RX);
    osal_memset(dmaCfg.rxBuf, (DMA_PAD ^ 0xFF),HAL_UART_DMA_RX_MAX*2);
    }
  • 数据接收与发送 :在数据接收时,数据首先存放在DMA接收缓冲区,HalUARTRead()函数实际上调用HalUARTReadDMA()函数从DMA缓冲区读取数据,就像是从仓库中取出信件进行处理。发送数据时,HalUARTWrite()函数调用HalUARTWriteDMA()函数将数据写入DMA发送缓冲区,然后DMA自动将数据通过串口发送给PC机,就像是将信件放入邮车进行发送。

时序图和流程图展示

  • 串口收发时序图

串口调试助手 开发板 DMA接收缓冲区 DMA发送缓冲区 发送数据 存储数据 调用HalUARTRead()读取数据 调用HalUARTWrite()写入数据 发送数据 串口调试助手 开发板 DMA接收缓冲区 DMA发送缓冲区

相关推荐
babytiger6 天前
ble扫描相关的问题,蓝牙 MAC 是否可以确定厂商?
蓝牙·ble
dozenyaoyida18 天前
BLE传输WiFi列表的问题分析
网络·经验分享·物联网·wifi·中文乱码·json解析·ble
Darkershadow20 天前
蓝牙学习之发送 Mesh Provisioning Service advertising
学习·蓝牙·ble·mesh
Darkershadow1 个月前
蓝牙学习之Time Set
python·学习·蓝牙·ble·mesh
wotaifuzao1 个月前
Matter-PICS梳理(ble-thread)
认证·thread·ble·matter·pics
飞易通1 个月前
蓝牙WIFI模块推动两轮车仪表与智能头盔智能化发展
蓝牙模块·ble·wifi模块·低功耗蓝牙模块·wifi蓝牙组合模块
Industio_触觉智能1 个月前
触觉智能RK3576开发板OpenHarmony开源鸿蒙蓝牙BLE主机实现方案
蓝牙·openharmony·主机·ble·开源鸿蒙·rk3576·从机
wotaifuzao1 个月前
(九)一文吃透 BLE:从低功耗原理到协议栈与实战概念
物联网·硬件架构·蓝牙·低功耗·ble·设计原理
Darkershadow1 个月前
蓝牙学习之Provision(7)bind (1)
学习·蓝牙·ble·mesh
Darkershadow1 个月前
蓝牙学习之Provision(6)Provison Complete
学习·蓝牙·ble·mesh