~%?…;# *’☆&℃$︿★? 2025-11-27 18:17 采纳率: 0%
浏览 6

中科蓝讯AB2021A3串口问题

公司最近用AB2021A3芯片做彩屏测距仪,开发过程中,发现串口老是出现问题。

  • 设备逻辑是AB2021A3做主控板带按键,自己公司开发的测距模块使用串口通信收发距离数据。在开发过程中,发现程序内部没调用的代码,会影响串口的发送,示波器抓取了波形,tx电平没掉,但是没发出数据。把其他地方的代码注释掉(或者冗余代码,或者没用的代码都行)减小代码体量,或者在把指令写入寄存器之前,printf打印一下准备发送的数据,串口就能正常发送数据了。因为涉及到彩屏的显示,所以里面有很多其他的显示和测距计算函数部分。令我疑惑的是,为什么没调用的代码,会影响串口的发送。由于程序使用code::blocks编译,我对这个编译器不是很熟悉,所以不知道它的优化会不会对代码造成影响。

  • 另一个问题是,由于有时需要语音播报,我需要在只有一个IO脚的情况下,发送数据后,接收语音芯片完成播报的低电平。由于限制我只能不停的转换IO口的输入输出状态。在转换的过程中,串口tx引脚会掉电压,导致后续串口指令发不出去。于是我单独写了个测试main函数,里面只留下串口收发,然后将收到的数据播报出去,这个时候一切正常,串口电平不会往下掉。这让我想到是不是又是和代码大小有关,同样的,注释掉部分代码,也可以解决问题,但是我的代码一直都在改,所以我直接在while(1)里不停初始化串口,来保证我的串口电平不会掉。

  • 这个芯片的开发环境不像stm32那样可以debug,我只能通过串口打印,一步一步排查。一开始出现问题后,我第一反应是,会不会是栈溢出了,导致函数没法压栈。于是我找了RISC-V内核汇编函数查看sp和ra指针,并打印查看

    __asm__ volatile("mv %0, sp" : "=r"(sp_ptr));
    __asm__ volatile("mv %0, ra" : "=r"(ra_ptr));
    printf("%s: sp %lx\n", __func__, sp_ptr);
    printf("%s: ra %lx\n", __func__, ra_ptr);
    
  • 查看链接脚本文件,栈的位置和我打印输出的位置根本不一样,但是大小我大概可以估计得到,栈应该是没有溢出。因为这个芯片在运行,是将flash内的程序通过spi拷贝到ram内运行(其他芯片了解的不深,不知道是不是都是这样的)。但是对于这个问题,我没有具体的思路,直觉让我认为应该是内存出了问题,但是我不知道用什么方法排查。

  • 关于这款芯片,网上的资料可以说直接没有,芯片内部封装程度很高,基本都是库函数操作,想找寄存器手册,找不到。公司的芯片包里有sdk手册,但是手册写的很笼统,而且不全,另外一些文档的作用也微乎其微。

  • 现在设备看起来挺稳定,但其中的辛酸只有我知道,这个问题不解决,后续量产爆大雷,那就寄了,现实中我不知道能问谁,所以只能在网上问问各位,有没有遇到过类似问题的可以提供一些解决问题的思路,感谢各位不吝赐教。

  • 写回答

3条回答 默认 最新

  • 阿里嘎多学长 2025-11-27 18:21
    关注

    阿里嘎多学长整理AIGC生成,因移动端显示问题导致当前答案未能完全显示,请使用PC端查看更加详细的解答过程

    问题分析

    根据你的描述,问题主要是关于中科蓝讯AB2021A3串口通信的问题。具体来说,你的开发过程中,发现串口老是出现问题,特别是在程序内部没有调试的情况下。

    解决方案

    以下是一些可能的解决方案:

    1. 串口配置: 确保串口配置正确,包括波特率、数据位数、停止位数等。可以通过中科蓝讯AB2021A3的数据手册或官方文档来查找正确的配置。
    2. 串口缓冲区: 检查串口缓冲区是否有溢出或丢包的情况。可以通过增加缓冲区大小或优化缓冲区管理来解决这个问题。
    3. 串口中断: 检查串口中断是否正确处理。可以通过增加中断优先级或优化中断服务函数来解决这个问题。
    4. 程序逻辑: 检查程序逻辑是否正确,特别是在串口通信部分。可以通过增加调试语句或使用调试工具来检查程序逻辑。
    5. 硬件问题: 检查硬件是否有问题,特别是在串口接口部分。可以通过检查串口接口是否连接正确或是否有短路等问题。

    核心代码

    以下是一个简单的示例代码,展示了如何使用中科蓝讯AB2021A3的串口通信功能:

    #include <stdio.h>
    #include <stdint.h>
    #include <stdbool.h>
    
    // 串口配置
    #define BAUD_RATE 9600
    #define DATA_BITS 8
    #define STOP_BITS 1
    
    // 串口句柄
    uint32_t uart_handle;
    
    // 串口初始化函数
    void uart_init(void) {
        // 配置串口
        uart_config(BAUD_RATE, DATA_BITS, STOP_BITS);
        // 打开串口
        uart_open(&uart_handle);
    }
    
    // 串口发送函数
    void uart_send(uint8_t *data, uint32_t len) {
        // 发送数据
        uart_send_data(uart_handle, data, len);
    }
    
    // 串口接收函数
    uint8_t uart_recv(uint32_t len) {
        // 接收数据
        uint8_t data = uart_recv_data(uart_handle, len);
        return data;
    }
    

    注意:以上代码仅供参考,具体实现可能需要根据中科蓝讯AB2021A3的数据手册或官方文档来调整。

    评论

报告相同问题?

问题事件

  • 创建了问题 11月27日