迪文科技论坛

 找回密码
 立即注册
搜索
查看: 542|回复: 6

【分享】T5L组合RTX51 Tiny的带缓冲CAN收发

[复制链接]

12

主题

20

回帖

181

积分

注册会员

Rank: 2

积分
181
发表于 2022-5-27 13:06:56 | 显示全部楼层 |阅读模式
本帖最后由 yxydoctor 于 2022-5-27 13:24 编辑

RTX51 Tiny是面向51核编程的一款RTOS,因为51核很成熟也很固定,所以移植该RTOS没有难度,基本算白捡。
T5L提供了高达206MHz的51主频,虽然算力测试跟32位机比还差点,但在现场数据采集,通讯,显示这块倒是强项。
结合RTX51 Tiny和T5L的C51编程,给出一种CAN接口通讯的简单收发流程,仅供参考。

一 RTX51 Tiny移植注意事项
1 - OS时钟滴答设为1ms,移植模板为10ms是因为标准51主频12M,Timer0滴答只有1MHz
2 - 关闭任务轮询设置(关闭时间片),即何时退出任务需要用户人工自行设定。这样做的好处是规避不同任务同时访问
    同一软件代码或同一硬件外设。
3 - 关闭休眠模式,因为T5L没有休眠模式,传统51的休眠寄存器已挪作它用了。

二 CAN通讯流程简介
1 - CAN中断函数仅负责置标志位,或者置OS信号量;中断函数里面不要尝试读写CAN报文;
2 - CAN接收任务:由中断函数进行触发,达到快速响应的目的;
3 - CAN发送任务:以1ms间隔查询发送报文队列,按需发送单帧或多帧;因为1ms延迟对发送影响不大,所以采用查询方式。

三 CAN中断函数
/***********************************************************************************************
功    能:CAN中断函数
说    明:包括发送,接收,故障中断
***********************************************************************************************/
void can_isr() interrupt 9
{
        // 远程帧
        if((CAN_IR&0xC0) == 0xC0)
        {
                CAN_IR &= 0x3F;                                                                        // 清空远程帧标记位
        }
        // 标准帧
        else if((CAN_IR&0xC0) == 0x40)
        {
                CAN_IR &= 0xBF;                                                                        // 清空数据帧标记位        
                CAN0.CommFailCount=0;                                                         // 置接收完成标记        
                isr_send_signal(JOB_CANRX);                                                // RTX51通知事件(rx完成)               
        }
        // 发送成功
        if((CAN_IR&0x20) == 0x20)
        {
                CAN_IR &= 0xDF;                                                                        // 清空发送帧标记位
                if(tx_message_id < 32 && CAN0.Tx_Count[tx_message_id] > 0)
                        CAN0.Tx_Count[tx_message_id] --;                        
                tx_message_id = CAN_TX_IDLE;
                isr_send_signal(JOB_CANTX);                                                // RTX51通知事件(tx完成)
        }
        if((CAN_IR&0x10) == 0x10)
        {
                CAN_IR &= 0xEF;                                                                        // 清空接收溢出标记位
        }
        if((CAN_IR&0x08) == 0x08)
        {
                CAN_IR &= 0xF7;                                                                        // 清空错误标记位
                CAN_ET &= 0xE0;                                                                        // 清空错误标记        
        }
        if((CAN_IR&0x04) == 0x04)
        {
                CAN_IR &= 0xFB;                                                                        // 清空仲裁失败标记位
                CAN_CR |= 0x04;                                                                        // 重新启动发送        
        }
}
本例程只涉及到标准帧+数据帧的读写。发送,接收成功后,都要给对应的解析任务提供一个OS信号量作为触发条件。

四 CAN接收任务
/***********************************************************************************************
功    能:读CAN接收报文函数
说    明:放在任务中读,避免在中断中访问DGUS变量,实测<30us
***********************************************************************************************/
void can_rxMessage(void)
{
        uint8_t         IDE_RTE,DLC,i,mo,d[16];        
        uint16_t         id;
        
        // 1-读出0xFF:0068 -0xFF:006B的CAN相关数据
        read_dgus4byte(0xFF0068, d, 4);        
        
        // 2-判断数据格式是否正确
        IDE_RTE = d[0] >> 6; if(IDE_RTE) return;                        // 扩展帧bit7(IDE)或远程帧bit6(RTE)
        DLC = d[0] & 0x0F;                                                                         // 帧数据长度bit3..0(DLC)                        
        
        // 3-判断邮箱编号        
        id = d[4]<<3; id |= (d[5]>>5);                                                // 报文id号
        mo=250;        
        for(i=0;i<32;i++){
                if(DLC != CAN0.Id){mo=i; break;}        
        }        
        
        // 4-拷贝数据,设接收标志
        if(CAN0.Rx_Count[mo] < CAN_BUF_LEN){
                if(mo < 32 && DLC == CAN0.Size[mo]){               
                        memcpy(CAN0.Rx_Data[mo][CAN0.Rx_Count[mo]], &d[8],8);        
                        CAN0.Rx_Count[mo] ++;
                }
        }
}
上述代码由接收任务调用,由中断函数触发,为单报文解析读取函数。报文判断合格后,打入缓冲区。

五 CAN发送任务
/***********************************************************************************************
功    能:CAN报文发送函数
说    明:tx成功/超时后再退出           
***********************************************************************************************/
void can_txMessage(uint8_t mo, uint8_t index)
{
        uint8_t state, d[16]={0};        
        
        // 1-准备发送数据
        d[0] = CAN0.Size[mo];                                                                // 数据帧+标准格式:[7] IDE ,[6]RTR, [3:0]—DLC,帧数据长度
        d[4] = CAN0.Id[mo]>>3;                                                                // 报文id号
        d[5] = (CAN0.Id[mo]  & 0x07)<<5;
        
        memcpy(&d[8], CAN0.Tx_Data[mo][index],8);
        write_dgus4byte(0xFF0064, d, 4);
        
        // 2-启动发送        
        tx_message_id = mo;
        CAN_CR |= 0x04;        
        
        // 3-发送完毕/超时判断
        state = os_wait2 (K_SIG | K_TMO, 5);
        
        // 超时判断:5ms超时,视为总线故障(比如断缆),取消发送
        if(state == TMO_EVENT){
                CAN0.Tx_Count[tx_message_id] = 0;                        
                tx_message_id = CAN_TX_IDLE;        
        }        
}
发送任务的发送成功与否放在最后判断,分为两种情况:
1-正常发送:因为CAN速度很快,所以发送时间很短;该条件由中断触发;
2-未发送成功:比如总线断缆,此时等待5ms也退出。
这样的话对于每一帧发送,无论成功与否,都会给个结论,如果5ms发送不成功,则取消该邮箱的所有发送任务。

六 小结
1 - 借助于RTX51 Tiny,可以简化T5L单片机的CAN收发流程。
2 - 时间开销主要是CAN寄存器或DGUS地址读写时间,实测<10us,而等待发送成功或超时检测时间不占用CPU。
3 - 收发缓冲区大小取决于xdata容量。比如设置32个邮箱,缓冲区深度为10时的测试代码,xdata=6K,可以放心使用。
4 - 使用RTOS后切记一点,用户代码中不要对EA进行控制,不要对Timer0寄存器进行控制。迪文官方推荐的进入中断关EA策略,其实是不可取的。

七 测试
借助于zlg的USBCAN模块和CAN Test软件做报文收发测试,不断提高发送频率,单次发送报文数量。效果很好。


回复

使用道具 举报

2

主题

667

回帖

1万

积分

论坛元老

Rank: 8Rank: 8

积分
10225
发表于 2022-5-27 13:19:07 | 显示全部楼层
感谢您的分享
回复

使用道具 举报

发表于 2022-5-27 13:20:00 | 显示全部楼层
顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶
回复

使用道具 举报

22

主题

41

回帖

423

积分

中级会员

Rank: 3Rank: 3

积分
423
发表于 2022-8-4 11:00:04 | 显示全部楼层
哥 移植注意事项能不能具体一点呢
回复

使用道具 举报

7

主题

19

回帖

392

积分

中级会员

Rank: 3Rank: 3

积分
392
发表于 2023-2-12 21:45:35 | 显示全部楼层
这个移植RTX51-tiny至T5L,您是怎么移植的,需要该什么吗,比如SFR
回复

使用道具 举报

2

主题

29

回帖

497

积分

中级会员

Rank: 3Rank: 3

积分
497
发表于 2023-3-13 19:45:10 | 显示全部楼层
大神 请教一下,我开启了2个任务task1,task2,它一直运行task1,无法切换task2 ,大概是什么问题?
回复

使用道具 举报

0

主题

764

回帖

4205

积分

论坛元老

Rank: 8Rank: 8

积分
4205
发表于 2023-7-12 14:28:12 | 显示全部楼层
源码可以发出来看看
回复

使用道具 举报

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

本版积分规则

QQ|Archiver|手机版|小黑屋|迪文科技论坛 ( 京ICP备05033781号-1 )

GMT+8, 2024-5-13 10:26 , Processed in 0.086822 second(s), 21 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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