硬汉嵌入式论坛

 找回密码
 立即注册
查看: 937|回复: 6
收起左侧

[CAN/FDCAN] UART数据转CAN问题

[复制链接]

5

主题

11

回帖

26

积分

新手上路

积分
26
发表于 2024-12-24 18:56:50 | 显示全部楼层 |阅读模式
UART缓冲区1800字节左右,波特率921600,用的空闲中断+DMA接收

void UART5_IRQHandler(void)
{
  if(__HAL_UART_GET_FLAG(&huart5, UART_FLAG_IDLE) != RESET){                                                        // 串口空闲中断
        __HAL_UART_CLEAR_IDLEFLAG(&huart5);                                                                                                        // 清除空闲中断标志位
        HAL_UART_DMAStop(&huart5);                                                                                                                        // 停止接收 DMA
        UART05_RX_LENGTH = UART05_IDLE_MAX_RECEIVE - __HAL_DMA_GET_COUNTER(&hdma_uart5_rx); // 计算接收到的数据长度
        HAL_UART_Receive_DMA(&huart5, (uint8_t*)UART05_IDLE_BUFF, UART05_IDLE_MAX_RECEIVE); // 重新打开DMA
        UART5_APPrxFramDone = 1;
  }
  HAL_UART_IRQHandler(&huart5);                                                                                                        // 重新打开中断
}
现在需要将UART接收到的数据通过CAN转发出去,CAN用的标准CAN,波特率1M
CAN配置为:

        hfdcan1.Instance = FDCAN1;                     /* 配置FDCAN1 */            
        hfdcan1.Init.FrameFormat = FDCAN_FRAME_CLASSIC; /* 配置使用FDCAN可变波特率 */  
        hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;         /* 配置使用正常模式 */
        hfdcan1.Init.AutoRetransmission = DISABLE;     /* 使能自动重发 */
        hfdcan1.Init.TransmitPause = DISABLE;          /* 配置禁止传输暂停特性 */
        hfdcan1.Init.ProtocolException = ENABLE;       /* 协议异常处理使能 */
        hfdcan1.Init.NominalPrescaler = 0x02;          
        hfdcan1.Init.NominalSyncJumpWidth = 0x04;
        hfdcan1.Init.NominalTimeSeg1 = 0x05;           
        hfdcan1.Init.NominalTimeSeg2 = 0x04;
CAN发送函数为:   

   void can1_SendPacket(uint8_t *_DataBuf,uint16_t _BufferSize)
{
        uint8_t dataBuf[8];       
        FDCAN_TxHeaderTypeDef TxHeader = {0};

        /* 第1步:配置发送参数 ===================================================================*/
        TxHeader.Identifier = 0x001;                                  /* 设置接收帧消息的ID */
        TxHeader.IdType = FDCAN_STANDARD_ID;                          /* 标准ID */
        TxHeader.TxFrameType = FDCAN_DATA_FRAME;                     /* 数据帧 */
        TxHeader.DataLength = FDCAN_DLC_BYTES_8;                       /* 发送数据长度 */
        TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;     /* 设置错误状态指示 */
        TxHeader.BitRateSwitch = FDCAN_BRS_OFF;              /* 关闭可变波特率 */
        TxHeader.FDFormat = FDCAN_FD_CAN;                    /* FDCAN格式 */
        TxHeader.TxEventFifoControl = FDCAN_STORE_TX_EVENTS; /* 用于发送事件FIFO控制, 不存储 */
        TxHeader.MessageMarker = 1;                          /* 用于复制到TX EVENT FIFO的消息Maker来识别消息状态,范围0到0xFF */
    /* 第2步:添加数据到TX FIFO, 连续添加三组 ================================================*/
        for(uint16_t i = 0; i < _BufferSize; i+=8)
        {
                uint16_t bytesToSend = _BufferSize - i;
        if (bytesToSend < 8)
        {
            memset(dataBuf, 0, sizeof(dataBuf)); // 用0填充剩余的部分
            memcpy(dataBuf, _DataBuf + i, bytesToSend); // 复制剩余的数据
        }
        else
        {
            memcpy(dataBuf, _DataBuf + i, sizeof(dataBuf)); // 复制8字节数据
        }       
                HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxHeader, dataBuf); /* 根据需要,可以修改_DataBuf数值 */
        }
}
现在的问题是,CAN转发的数据总是出现覆盖,第一帧数据没发完,第二帧数据又来了,想请问下这个怎么解决啊

回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117546
QQ
发表于 2024-12-25 07:04:32 | 显示全部楼层
现在的主要问题是转换速度慢些,比如10ms传输一次,正常不

看下是你的转换程序有问题没,没问题的基础上再优化下传输速度
回复

使用道具 举报

5

主题

11

回帖

26

积分

新手上路

积分
26
 楼主| 发表于 2024-12-25 09:40:02 | 显示全部楼层
eric2013 发表于 2024-12-25 07:04
现在的主要问题是转换速度慢些,比如10ms传输一次,正常不

看下是你的转换程序有问题没,没问题的基础上 ...

        if(UART5_APPrxFramDone == 1)
        {                       
                can1_SendPacket(UART05_IDLE_BUFF, UART05_RX_LENGTH);
                UART5_APPrxFramDone = 0;
        }
串口中断中有个标志位,在main的while(1)中一直检测标志位
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117546
QQ
发表于 2024-12-26 07:40:58 | 显示全部楼层
软汉 发表于 2024-12-25 09:40
if(UART5_APPrxFramDone == 1)
        {                        
                can1_SendPacket(UART05_IDLE_BUFF, UART05_RX_LENGTH);

转换速度慢些,比如10ms传输一次,正常不,是不是不出错了
回复

使用道具 举报

5

主题

11

回帖

26

积分

新手上路

积分
26
 楼主| 发表于 2024-12-26 14:10:39 | 显示全部楼层
本帖最后由 软汉 于 2024-12-26 16:39 编辑
eric2013 发表于 2024-12-26 07:40
转换速度慢些,比如10ms传输一次,正常不,是不是不出错了

嗯嗯,谢谢
回复

使用道具 举报

5

主题

11

回帖

26

积分

新手上路

积分
26
 楼主| 发表于 2024-12-26 15:07:46 | 显示全部楼层
本帖最后由 软汉 于 2024-12-26 18:06 编辑

eric2013 发表于 2024-12-26 07:40
转换速度慢些,比如10ms传输一次,正常不,是不是不出错了

HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxHeader, temp);
bsp_DelayUS(150);  //每包之间的间隔,最低150US
我在每次传输这里加了个延时,最低到150us,低于150每帧数据就会丢包
按150us传输一次,每次8字节算,1872字节,总计花费35.1ms,那我每50ms传输一整帧数据就不会出现问题
能这样算吗
但是这个50ms传输一帧总数据还是不能满足我的要求,大佬,有啥办法能在提提速嘛

额,我现在can的波特率是1M,以后肯定用不了1M,最多能到150k,那这样转换速度又是一个大问题
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117546
QQ
发表于 2024-12-27 07:12:21 | 显示全部楼层
软汉 发表于 2024-12-26 15:07
eric2013 发表于 2024-12-26 07:40
转换速度慢些,比如10ms传输一次,正常不,是不是不出错了
HAL_FDCAN_ ...

CAN的发送改进下,参考这个里面的例子
不要用delay,监测到发送完成了再发送新的,看下这个例子发送完成处理方法
https://forum.anfulai.cn/forum.php?mod=viewthread&tid=86980

V7-087



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-14 01:26 , Processed in 0.042779 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表