完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
真没想到距离写第一篇S32K144入门笔记(1) 从零开始进行开发环境搭建已经过去了半年。
当时是项目紧逼,20天之前要把这个片子的大部分外设跑起来,做好BOOT+APP架构,在十一之前出一个demo。 只能每天调完一个外设,本来计划是给每个外设都写一篇总结的。 后来demo完成就转手给其他同事了,然后进了其他项目,一转眼就是半年。 这半年里,S32K已经推到了多个项目里使用,形成S32K + ADAS(海思3566/赛灵思zynq/zux)的架构,但是都是在上层的业务做修改,底下的一些外设接口基本没怎么变过,所以没怎么遇到大问题,就没再回来这个项目做修改。唯一遇到的问题就是lin的,这个后面开单独一节来写。 最近正好面临工作交接,再次把项目过一遍,整理一些文档,留给后面的同事。 这件事证明了:自己一定要抽时间来做总结,单纯地不停赶项目,会给自己很充实的错觉。一定要思考,才能沉淀。 跑偏了,拉回,汽车电子设备,先写can。 1. 开发环境
S32K144的资料很少,我们直接从SDK里拉个demo来分析把。 2.1 demo 用的是Pal层的demo程序,调用的是can_pal这个组件。 2.2 硬件引脚 要注意就是,调can,这个开发板必须使用12V供电,否则can phy那边起不来。 quickStart文档上标识了要使用的接口: 注意就是J107的跳线帽,需要使用12V电源供电,并切换。切换到1-2脚连接。 先看原理图 芯片上脚是: PTE4 和 PTE5. 然后过一个电平转换,这块我们不用管。 然后到can phy,输出 实际接线如下,注意跳线帽 2.3 demo程序分析 这个demo程序实现比较简单,和can相关流程就是,
CAN_Init(&can_pal1_instance, &can_pal1_Config0);
can_buff_config_t buffCfg = {
分析几个重要的接口吧,无非是过滤、发送、接收。 2.4.1 配置过滤ID - CAN_ConfigRxBuff CAN_ConfigRxBuff调用了FLEXCAN_DRV_ConfigRxMb,进而调用FLEXCAN_SetRxMsgBuff。 这个是通过配置flexcan_mb_id来实现过滤。 volatile uint32_t *flexcan_mb = FLEXCAN_GetMsgBuffRegion(base, msgBuffIdx);volatile uint32_t *flexcan_mb_id = &flexcan_mb[1]; 再找FLEXCAN_GetMsgBuffRegion,返回的第N个message buffer的地址。 然后给flexcan_mb_id 赋值,看代码是赋给了message buffer的4字节偏移的位置。 再向下的机制就没再深究。 2.4.2 Can发送 - CAN_Send CAN_Send是can发送接口, 调用完可以用 while(CAN_GetTransferStatus(INST_CAN_PAL1, TX_BUFF_IDX) == STATUS_BUSY); 来判断是否发送完成。 但是这种情况下,如果板子没接can线,就会一直卡在这里,所以可以用CAN_SendBlocking(INST_CAN_PAL1, TX_BUFF_IDX, &sendMsg,1);加一个超时机制。 看实际情况来使用吧。 2.4.3 Can接收 - CAN_Receive 与发送同理,有一个CAN_ReceiveBlocking超时机制的接口,这样做起来会比较灵活。 CAN_Receive(&can_pal1_instance, RX_MAILBOX, &recvMsg); 中接收buffer地址recvMsg会配给mb_message。 然后通过EDMA_DRV_ConfigSingleBlockTransfer接口,配置source地址和dest地址做一次搬运。 源数据都是放在RAMn地址上的。 3. 实际使用遇到的问题 基于这个demo来做了我们自己的工程,记录几个实际遇到的问题把。 3.1 基于demo测试,can收不到数据 因为加了过滤机制,只能收ID 为0x2的报文。 所以只能收到RX_MSG_ID的数据。 3.2 基于demo测试,can发不出数据 demo设计就是按键会发送一个can报文,但是实测在按键中断里,调用Can_send 无法发出can数据。 单步跟踪到FLEXCAN_StartSendData接口里面的 if (state->mbs[mb_idx].state != FLEXCAN_MB_IDLE){ return STATUS_BUSY;} status返回的是STATUS_BUSY,但是接收能收到。 解决方法: 在配置界面里把can_fd勾掉。 payload_size 改成8。 接收到数据: 3.3 数据发送混乱,第一次有帧号,后面就没了,can盒接收数据一会远程帧一会数据帧
后面就进不来了。 再往上跟踪 FLEXCAN_StartSendData() 里的 cs.msgIdType = tx_info->msg_id_type; 赋值的 这个msg_id_type是从 CAN_Send里的 flexcan_data_info_t dataInfo = { .msg_id_type = (flexcan_msgbuff_id_type_t) s_hwObjConfigs[instance][buffIdx]->idType, 赋值的 2. 有时候消息会变成远程帧出去。 是数据帧还是远程帧,是由 CAN_Send里的dataInfo的is_remote决定的。 .is_remote = s_hwObjConfigs[instance][buffIdx]->isRemote, 单步调试,这个值只有第一次的时候为0,后面(第二次跑到这里)怎么就变成了43? 这个s_hwObjConfigs数组是从哪里来的? 3. 综合上述两个bug。 都是在Can_Send这个接口里出的问题。 都是读取s_hwObjConfigs这个配置出错的。 为啥呢? 来找这个s_hwObjConfigs是在哪里配的? void ConfigCan0Buffer(){can_buff_config_t buffConfig = { .enableFD = false, .enableBRS = false, .fdPadding = 0x00, .idType = CAN_MSG_ID_STD, .isRemote = false}; CAN_ConfigTxBuff(INST_CAN_PAL1, TX_BUFF_IDX, &buffConfig); CAN_ConfigRxBuff(INST_CAN_PAL1, RX_BUFF_IDX, &buffConfig, 0x55);} 问题找到了,这个参数是指针传的,每次发送都要读取。 不能把buffConfig 写到函数内部,运行完了就释放了。 要写成全局变量。 3.4 实现中断接收 网上下载了一个NXP的demo, 使用 CAN_InstallEventCallback(INST_CAN_PAL1, can0_Callback, NULL); 注册中断回调就好。 在中断中可以做一些存储策略,比如用自己的环形队列。 3.5 其他资料 在组件上右键有Doxygen documentation,里面也有一些说明和例子,可以参考。 |
|
|
|
只有小组成员才能发言,加入小组>>
3262 浏览 9 评论
2943 浏览 16 评论
3442 浏览 1 评论
8950 浏览 16 评论
4036 浏览 18 评论
1078浏览 3评论
558浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
551浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2286浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1846浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-8 20:29 , Processed in 1.098993 second(s), Total 78, Slave 58 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号