学习FDCAN控制器上的TxFIFO

近日在调试FDCAN protocal, 发送数据总是不成功,报TxFIFO溢出的错误,后查阅资料检查代码,发现是TxFIFO的配置问题,以下是解决问题的参考文档,转载过来记录以便以后查看。

一.TxFIFO设为1所带来的问题
在STM32F103,STM32F407上面的CAN控制器,到了STM32H743上升级成FDCAN控制器。浏览了正点原子,安富莱,野火的STM32H7教程,都没有介绍FDCAN如何使用。关于FDCAN相关的教程,广州硬石电子科技做得比较好。但是,硬石科技的FDCAN例程在实际项目上直接使用的话,会有一些问题等着你发现。
硬石科技将FDCAN控制器的TxFIFO设置为1,相当于取消FIFO的功能。
以下图片摘自硬石科技的H743教程:

1.1 示例代码

LED5_Handler()会被FreeRTOS系统每隔1S调用一次。实际上,代码的目的是发送5条CAN报文,CAN_ID分别是0x181,0x182,0x183,0x184,0x185。

通过CAN分析仪看到的结果是: "每隔1S时间,STM32H743只是发送了CAN_ID为0x181的CAN报文,并不是5条CAN报文。"

导致这个结果的原因是TxFIFO被设为1。

解决办法:

根据HAL库的源码可以看到,Tx Fifo Queue Elmts Nbr的范围是: 0 ~ 32.

代码不用修改,直接观察CAN分析仪的情况。

从上图可以看到,CAN分析仪每隔1S时间,收到CAN_ID为0x181,0x182,0x183,0x184,0x185的5条CAN报文。
问题解决了,代码的目的达到了。

原文地址:学习FDCAN控制器上的TxFIFO - STM32/STM8单片机论坛 - ST MCU意法半导体官方技术支持论坛 - 21ic电子技术开发论坛

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当使用ESP32的UART串口进行数据传输时,如果环形缓冲区已满(即缓冲区中的数据数量达到了其容量),那么就会触发UART的“已满事件”。 在ESP32的代码中,可以通过设置UART的中断处理函数来处理“已满事件”。当环形缓冲区已满时,中断处理函数会被调用,您可以在其中执行相应的操作,例如清空缓冲区或者停止数据发送等。 下面是一个示例代码,用于处理UART的“已满事件”: ```c #define UART_BUF_SIZE 128 uint8_t uart_buffer[UART_BUF_SIZE]; uint8_t uart_head = 0; uint8_t uart_tail = 0; void uart_isr_handler(void* arg) { uint32_t uart_intr_status = READ_PERI_REG(UART_INT_ST(UART_NUM)); if (uart_intr_status & UART_TXFIFO_EMPTY_INT_ST) { // UART TX FIFO empty, send more data if (uart_head != uart_tail) { WRITE_PERI_REG(UART_FIFO(UART_NUM), uart_buffer[uart_tail]); uart_tail = (uart_tail + 1) % UART_BUF_SIZE; } else { // UART TX FIFO empty, but no more data, disable TX interrupt CLEAR_PERI_REG_MASK(UART_INT_ENA(UART_NUM), UART_TXFIFO_EMPTY_INT_ENA); } } else if (uart_intr_status & UART_TXFIFO_FULL_INT_ST) { // UART TX FIFO full, stop data sending CLEAR_PERI_REG_MASK(UART_INT_ENA(UART_NUM), UART_TXFIFO_EMPTY_INT_ENA); SET_PERI_REG_MASK(UART_INT_ENA(UART_NUM), UART_TXFIFO_EMPTY_INT_ENA); } } void uart_init() { // set UART interrupt handler esp_intr_alloc(ETS_UART_INTR_SOURCE, ESP_INTR_FLAG_IRAM, uart_isr_handler, NULL, NULL); // enable UART TX interrupt SET_PERI_REG_MASK(UART_INT_ENA(UART_NUM), UART_TXFIFO_EMPTY_INT_ENA); } void uart_send_data(uint8_t* data, uint32_t length) { // copy data to UART buffer for (int i = 0; i < length; i++) { uart_buffer[uart_head] = data[i]; uart_head = (uart_head + 1) % UART_BUF_SIZE; } // enable UART TX interrupt SET_PERI_REG_MASK(UART_INT_ENA(UART_NUM), UART_TXFIFO_EMPTY_INT_ENA); } ``` 在上面的代码中,我们使用一个环形缓冲区来存储待发送的数据。当调用`uart_send_data`函数时,将数据复制到缓冲区中,并启用UART TX中断。在中断处理函数中,如果UART TX FIFO为空,则发送缓冲区中的下一个数据。如果UART TX FIFO已满,则停止数据发送。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值