TA的每日心情 | 奋斗 2024-12-12 14:13 |
---|
签到天数: 212 天 连续签到: 1 天 [LV.7]常住居民III
|
本帖最后由 andeyqi 于 2024-1-16 20:54 编辑
我们基于之前适配好的系统和PIN驱动的基础上继续适配S32K146的CAN 驱动,有了CAN 驱动我们就可以通过PCAN 模拟车辆内部的CAN 总线数据,接收发送CAN消息至车辆的CAN 总线,完成和其他ECU的信息交互。
CAN 收发器使用的TJA1043,该IC 只需要按照时序控制对应的PIN脚即可让其进入 normal 模式,对应代码如下:
- void can1_control_init(void)
- {
- rt_base_t mcu_can1_en;
- rt_base_t mcu_can1_wake;
- rt_base_t mcu_can1_stby;
- /* init can controler pin */
- mcu_can1_en = rt_pin_get(MCU_CAN1_EN);
- mcu_can1_wake = rt_pin_get(MCU_CAN1_WAKE);
- mcu_can1_stby = rt_pin_get(MCU_CAN1_STBY);
- rt_pin_mode(mcu_can1_en,PIN_MODE_OUTPUT);
- rt_pin_mode(mcu_can1_wake,PIN_MODE_OUTPUT);
- rt_pin_mode(mcu_can1_stby,PIN_MODE_OUTPUT);
- /* init tja1043 */
- rt_pin_write(mcu_can1_wake,PIN_HIGH);
- rt_pin_write(mcu_can1_stby,PIN_LOW);
- rt_pin_write(mcu_can1_en,PIN_LOW);
- rt_thread_mdelay(1);
- rt_pin_write(mcu_can1_stby,PIN_HIGH);
- rt_pin_write(mcu_can1_en,PIN_HIGH);
- rt_thread_mdelay(1);
- rt_pin_write(mcu_can1_wake,PIN_LOW);
- }
复制代码 使用 S32K SDK 中的CAN驱动接口对CAN进行初始化,配置CAN 的波特率为500Kb,及CAN 参数,配置CAN 首发mailbox 资源配置,配置CAN 接收过滤器配置,即可完成CAN 模块的驱动配置对应代码如下:
- void can1_init(void)
- {
- status_t ret = STATUS_SUCCESS;
- flexcan_id_table_t id_filter_table[40];
- uint16_t i = 0;
- for(i =0; i < 40;i++)
- {
- id_filter_table[i].isRemoteFrame = false;
- id_filter_table[i].isExtendedFrame =false;
- id_filter_table[i].id = 0x400 + (0x10*i);
- }
- ret = FLEXCAN_DRV_Init(INST_FLEXCAN_CONFIG_1,&flexcanState0,&flexcanInitConfig0);
- if(ret != STATUS_SUCCESS)
- {
- rt_kprintf("can1 init failed.\n");
- }
- FLEXCAN_DRV_SetRxMaskType(INST_FLEXCAN_CONFIG_1,FLEXCAN_RX_MASK_INDIVIDUAL);
- FLEXCAN_DRV_ConfigRxFifo(INST_FLEXCAN_CONFIG_1, FLEXCAN_RX_FIFO_ID_FORMAT_A, id_filter_table);
- for(i = 0;i < 16; i++)
- {
- ret = FLEXCAN_DRV_SetRxIndividualMask(INST_FLEXCAN_CONFIG_1, FLEXCAN_MSG_ID_STD, i, 0x7ff);
- if( ret != STATUS_SUCCESS )
- {
- rt_kprintf( "can1 set rx filter failed %x.\n",ret);
- }
- }
- }
复制代码
驱动配置完之后,我们创建一收一发线程用于处理CAN 接收发送的数据,对应代码如下:
- #define THREAD_PRIORITY 25
- #define THREAD_STACK_SIZE 1024
- #define THREAD_TIMESLICE 5
- void cantx_entry(void *parameter)
- {
- can1_control_init();
- can1_init();
- flexcan_data_info_t msg =
- {
- .data_length = 8,
- .msg_id_type = FLEXCAN_MSG_ID_STD,
- .enable_brs = false,
- .fd_enable = false,
- .fd_padding = 0U,
- .is_remote = false
- };
- static uint8_t buff[8] = {0x55,0xaa,0x55,0xaa,0xaa,0xbb,0xcc,0xdd};
- while(1)
- {
- FLEXCAN_DRV_Send(INST_FLEXCAN_CONFIG_1,16,&msg,0x100,buff);
- rt_thread_mdelay(100);
- }
- }
- void canrx_entry(void *parameter)
- {
- static flexcan_msgbuff_t data;
- status_t ret = STATUS_SUCCESS;
- while(1)
- {
- ret = FLEXCAN_DRV_RxFifo(INST_FLEXCAN_CONFIG_1,&data);
- if(ret == STATUS_SUCCESS)
- {
- rt_kprintf("id = %x :%x %x %x %x %x %x %x %x\n",data.msgId,\
- data.data[0],data.data[1],data.data[2],data.data[3],\
- data.data[4],data.data[5],data.data[6],data.data[7]);
- }
- rt_thread_mdelay(10);
- }
- }
- int can_sample(void)
- {
- rt_thread_t tid = RT_NULL;
- tid = rt_thread_create("cantx",
- cantx_entry, RT_NULL,
- THREAD_STACK_SIZE,
- THREAD_PRIORITY,
- THREAD_TIMESLICE);
- if (tid != RT_NULL)
- rt_thread_startup(tid);
- tid = rt_thread_create("canrx",
- canrx_entry, RT_NULL,
- THREAD_STACK_SIZE,
- THREAD_PRIORITY,
- THREAD_TIMESLICE);
- if (tid != RT_NULL)
- rt_thread_startup(tid);
- return 0;
- }
- MSH_CMD_EXPORT_ALIAS(can_sample, can ,can sample);
复制代码 对应玩上述驱动,我们通过usb can 模拟发送0x400 消息携带车速及车窗状态信息,通过串口输出运行如下,可以看到can 通信的发送接收都工作,已经能模拟采集车辆的CAN总线数据了。
/*代码路径如下*/
|
|