fr8018串口接收特定14字节数据包的解析有问题吗,求指教。加入不管单片机,这个串口是一直有数据发送过来,休眠状态下接收会影响唤醒和重启接收吗



  • #define BUFFER_SIZE 128 // 定义缓冲区大小
    #define FRAME_HEADER 0xFE
    #define FRAME_TAIL 0x55
    #define FRAME_LENGTH 14
    uint16_t distance_ble;
    uint8_t Usart0_recv_buffer[BUFFER_SIZE]; // 接收缓冲区
    uint8_t buffer_index = 0; // 缓冲区索引
    uint8_t frame_received = 0; // 帧接收完成标志
    attribute((section("ram_code"))) void uart1_isr_ram(void)
    {
    uint8_t int_id;
    uint8_t c;
    volatile struct uart_reg_t *uart_reg = (volatile struct uart_reg_t *)UART1_BASE;

    int_id = uart_reg->u3.iir.int_id;
    
    if(int_id == 0x04 || int_id == 0x0c )   /* 接收数据可用或字符超时指示 */
    {
        // 只有当有数据可读时才进行操作
        if (uart_reg->lsr & 0x01)  // 检查是否有数据
        {
            // 一次性读取所有可用字符
            while (uart_reg->lsr & 0x01)
            {
                c = uart_reg->u1.data;
                
                // 实现帧头检测和缓冲区管理
                if (buffer_index == 0) {
                    // 寻找帧头 - 只有找到帧头才开始存储数据
                    if (c == FRAME_HEADER) {
                        Usart0_recv_buffer[buffer_index++] = c;
                    }
                    continue; // 未找到帧头,丢弃数据
                }
                else {
                    // 已经找到帧头,继续存储数据
                    Usart0_recv_buffer[buffer_index++] = c;
                    
                    // 检查是否接收到了帧头(防止数据中包含帧头导致的同步错误)
                    if (c == FRAME_HEADER && buffer_index > 1) {
                        // 重新同步:当前字节是新的帧头
                        Usart0_recv_buffer[0] = c;
                        buffer_index = 1;
                        continue;
                    }
                    
                    // 检测完整帧:长度达到且帧尾正确
                    if (buffer_index == FRAME_LENGTH) {
                        if (Usart0_recv_buffer[1] == 0x0A) {  // 帧验证成功
                            // 完整帧接收完成
                            frame_received = 1;
                            
                            // 处理接收到的数据帧
                            if (buffer_index > 9) {
                                // 解析距离数据
                                float distance_raw =Usart0_recv_buffer[8] | Usart0_recv_buffer[9]<<8 ; 
                                distance_ble= (uint16_t)distance_raw;
                                // 打印调试信息
                                //printf("Data parsed:  distance=%.3f\n", distance_raw);                        
                            }
                        } 
                        // 无论帧是否有效,都重置缓冲区准备下一帧
                        buffer_index = 0;
                    }
                    
                    // 缓冲区溢出保护(超过预期帧长)
                    if (buffer_index > FRAME_LENGTH) {
                        // 寻找缓冲区中可能的下一个帧头
                        uint8_t i;
                        for (i = 1; i < buffer_index; i++) {
                            if (Usart0_recv_buffer[i] == FRAME_HEADER) {
                                // 找到新的帧头,移动数据
                                Usart0_recv_buffer[0] = Usart0_recv_buffer[i];
                                buffer_index = 1;
                                break;
                            }
                        }
                        // 如果没找到帧头,完全重置
                        if (i == buffer_index) {
                            buffer_index = 0;
                        }
                    }
                }
            }
        }
    }
    else if(int_id == 0x06)
    {
        volatile uint32_t line_status = uart_reg->lsr;
        // 可以在这里添加错误处理逻辑
        buffer_index = 0;  // 发生线路错误时重置缓冲区
    }
    

    }
    void demo_uart1(void)
    {
    // system_set_port_pull(GPIO_PD6, true);
    // system_set_port_mux(GPIO_PORT_D, GPIO_BIT_6, PORTD6_FUNC_UART0_RXD);
    // system_set_port_mux(GPIO_PORT_D, GPIO_BIT_7, PORTD7_FUNC_UART0_TXD);
    // uart_init(UART0, BAUD_RATE_115200);
    //co_printf("uart0 demo\r\n");

    system_set_port_pull(GPIO_PD4, true);
    system_set_port_mux(GPIO_PORT_D, GPIO_BIT_4, PORTD4_FUNC_UART1_RXD);
    system_set_port_mux(GPIO_PORT_D, GPIO_BIT_5, PORTD5_FUNC_UART1_TXD);
    uart_init(UART1, BAUD_RATE_115200);
    uart_param_t param =
    {
        .baud_rate = 115200,
        .data_bit_num = 8,
        .pari = 0,
        .stop_bit = 1,
    };
    uart_init1(UART1, param);
    
    
    //NVIC_EnableIRQ(UART0_IRQn);
    NVIC_EnableIRQ(UART1_IRQn);
    

    // co_printf("uart1 demo\r\n");
    }



  • 如果开休眠的话,需要在这里重新初始化一下硬件
    0_1760079672722_9bc91e96-0815-4c7e-931a-86fa9dfe3095-图片.png



  • 好的,我试试,请问这个串口是接收换成PD4,5也是要更改吧,顺便问下睡眠需要32K晶振吗



  • 根据你的来,因为睡眠的时候只保留RAM,外设寄存器的值进入睡眠就清除了

    不需要的