【WCH蓝牙系列芯片】-基于CH592开发板—BLE_UART程序中,不连接状态下串口数据接收

------------------------------------------------------------------------------------------------------------------------------------

  在BLE_UART的程序中,是串口和蓝牙之间透传数据,在连接的时候,通过BLE调试助手连接广播的蓝牙信号,然后在程序中通过app_uart_process()一直放在主循环中,一直在判读串口接收的中断标志位,如果有接收的中断标志位,就会启动tmos任务处理串口到蓝牙的发送事件。

image

image

 

  但是,有的时候,想要在蓝牙还没有连接之前,就想要通过串口发送自己的数据,等数据接收后,进行一系列处理数据之后,再开启蓝牙连接的操作。在这样的情况下,就是需要区分当前状态是否在蓝牙建立连接的状态。

  如果是已经在蓝牙建立连接的状态,就走原来的BLE_UART的tmos_set_event(Peripheral_TaskID, UART_TO_BLE_SEND_EVT)事件任务。

  如果当前状态是处于蓝牙断开连接的状态,就得需要通过超时判断机制识别一整包数据的结束,再一次性读取并打印。

  在串口中断 UART3_IRQHandler 中,每次收到数据后重置超时TMOS任务事件,确保只有在指定时间内无新数据时,才认为一包数据结束:

image

  在app_uart_process()函数中,通过if(peripheralConnList.connHandle != GAP_CONNHANDLE_INIT) 检查当前是否已经存在连接,建立连接之后,在执行UART_TO_BLE_SEND_EVT事件任务,进行蓝牙接收数据。

image

  在添加void print_received_data(void)程序,读取接收串口中的数据长度,将数据从FIFO中读取出来。并且打印接收的每一个串口数据。

// 打印 接收到的数据
void print_received_data(void){
    data_length = app_drv_fifo_length(&app_uart_rx_fifo);      // 获取 FIFO 中的数据长度
    PRINT("FIFO_LEN:%d\r\n", data_length);
    if (data_length > 0)      // 如果接收到的数据长度大于0字节
    {
        read_data_length = data_length;
        // 从 FIFO 中读取数据
        app_drv_fifo_read(&app_uart_rx_fifo, buffer, &read_data_length);
        // 打印接收到的数据长度
        PRINT("-------Received %u bytes: ", read_data_length);
        // 打印接收到的每个字节的数据
        for (uint16_t i = 0; i < read_data_length; i++) {
            PRINT("%02X ", buffer[i]);
            // 将接收到的数据添加到环形缓冲区
             enqueue(&uart_queue, buffer[i]);
        }
        PRINT("\r\n");
    }
}

  然后处理串口数据包超时事件的任务接收。将接收串口数据打印的函数,放在UART_PACKET_TIMEOUT_EVT事件中。

image

  通过串口来观察整个现象,在蓝牙无连接的情况下,除了打印串口数据,也会通过接收串口之后,发送到串口端,其中还利用环形缓冲区操作,每次从环形缓冲区读取并发送串口数据

image

 

  在蓝牙连接的情况下的打印

image

 

 

  在这部分程序中,讲解其中应用到环形缓冲区的方法:

 

// 定义一个环形队列结构体
typedef struct {
    uint8_t *buffer; // 环形缓冲区
    uint16_t head;   // 队列头指针
    uint16_t tail;   // 队列尾指针
    uint16_t size;   // 队列大小
} CircularQueue;

// 初始化环形队列函数
void init_circular_queue(CircularQueue *queue, uint8_t *buffer, uint16_t size) {
    queue->buffer = buffer; // 将传入的缓冲区地址赋值给队列的 buffer 成员
    queue->head = 0;        // 初始化头指针为 0
    queue->tail = 0;        // 初始化尾指针为 0
    queue->size = size;     // 将传入的缓冲区大小赋值给队列的 size 成员
}

// 入队操作函数
void enqueue(CircularQueue *queue, uint8_t data) {
    // 检查队列是否已满
    // 当尾指针加 1 后等于头指针时,队列满
    if ((queue->tail + 1) % queue->size != queue->head)
    {
        queue->buffer[queue->tail] = data; // 将数据存入尾指针指向的位置
        queue->tail = (queue->tail + 1) % queue->size; // 尾指针后移一位
    } else {
        PRINT("Queue is full!\n"); // 队列满,打印提示信息
    }
}

// 出队操作函数
uint8_t dequeue(CircularQueue *queue) {
    // 检查队列是否为空
    // 当头指针等于尾指针时,队列空
    if (queue->head != queue->tail)
    {
        uint8_t data = queue->buffer[queue->head]; // 获取头指针指向的数据
        queue->head = (queue->head + 1) % queue->size; // 头指针后移一位
        return data; // 返回读取到的数据
    } else {
        PRINT("Queue is empty!\n"); // 队列空,打印提示信息
        return 0; // 返回 0(这里的 0 可能需要根据实际情况调整,作为错误值)
    }
}

// 定义缓冲区大小
#define BUFFER_SIZE BLE_BUFF_MAX_LEN - 4 - 3
// 定义缓冲区
uint8_t uart_buffer[BUFFER_SIZE];
// 定义环形队列
CircularQueue uart_queue;

  在初始化中,添加初始化环形队列

image

  在接收读取串口数据的时候,将数据进行入队列的操作,将数据添加到环形缓冲区中,

image

 

// 定时器中断或主循环中调用此函数
void send_data_via_uart()
{
    // 检查环形缓冲区是否为空
    if (uart_queue.head != uart_queue.tail)
    {
        // 计算当前缓冲区中的数据量
        uint16_t data_count = (uart_queue.tail - uart_queue.head + uart_queue.size) % uart_queue.size;
        // 打印环形缓冲区中的数据长度
       PRINT("--------Circular Queue Data Length---------: %d\r\n", data_count); 
        // 定义一个临时缓冲区用于存储要发送的数据
        uint8_t temp_buffer[data_count];
        uint16_t bytes_to_send = data_count;
        // 从环形缓冲区读取数据到临时缓冲区
        for (uint16_t i = 0; i < bytes_to_send; i++) {
            temp_buffer[i] = dequeue(&uart_queue);
        }
        // 打印从环形缓冲区读取的数据
        PRINT("Data from Circular Queue: ");
        for (uint16_t i = 0; i < bytes_to_send; i++) {
            PRINT("%02X ", temp_buffer[i]);
        }
        PRINT("\r\n");
        // 通过串口发送数据
        UART3_SendString(temp_buffer, bytes_to_send);
    }
}

然后写一个send_data_via_uart()函数,在发送数据的任务事件中,调用这个函数。

image

 

 

通过网盘分享的文件:5-基于CH592开发板—BLE_UART程序中,不连接状态下串口数据接收
链接: https://pan.baidu.com/s/1TVF4x75LHlxSVesiQwmcjQ 提取码: 6agf
--来自百度网盘超级会员v5的分享

 

 

posted on 2025-07-31 14:49  凡仕  阅读(68)  评论(0)    收藏  举报