加入星计划,您可以享受以下权益:

  • 创作内容快速变现
  • 行业影响力扩散
  • 作品版权保护
  • 300W+ 专业用户
  • 1.5W+ 优质创作者
  • 5000+ 长期合作伙伴
立即加入

S32K146的CAN驱动适配在汽车电子控制单元中的应用

05/16 08:49
1950
服务支持:
技术交流群

完成交易后在“购买成功”页面扫码入群,即可与技术大咖们分享疑惑和经验、收获成长和认同、领取优惠和红包等。

虚拟商品不可退

当前内容为数字版权作品,购买后不支持退换且无法转移使用。

加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论
放大
电路板图
  • 方案介绍
  • 推荐器件
  • 相关推荐
  • 电子产业图谱
申请入驻 产业图谱

我们基于之前适配好的系统和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 %xn",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总线数据了。

/*代码路径如下*/

https://gitee.com/andeyqi/rt-thread/tree/master/bsp/s32k14x

推荐器件

更多器件
器件型号 数量 器件厂商 器件描述 数据手册 ECAD模型 风险等级 参考价格 更多信息
AD9851BRSZ 1 Rochester Electronics LLC SPECIALTY ANALOG CIRCUIT, PDSO28, ULTRA SMALL, MO-150AH, SSOP-28
$38.84 查看
A3979SLPTR 1 Allegro MicroSystems LLC Stepper Motor Controller, 2.5A, BCDMOS, PDSO28, 1.2 MM HEIGHT, EXPOSED PAD, MO-153AET, TSSOP-28

ECAD模型

下载ECAD模型
暂无数据 查看
ADG819BRTZ-500RL7 1 Analog Devices Inc 0.5 &Omega; CMOS 1.8 V to 5.5 V 2:1 Mux/SPDT Switch with BBM Switching Action

ECAD模型

下载ECAD模型
$2.83 查看

相关推荐

电子产业图谱