【S32K3 RTD LLD篇2】K344 FlexCAN 外部loopback

写本篇文章的用意,没有别的意思,单纯表达对RTD400自带CAN代码的不满,因为RTD400自带的CAN代码是loopback,而且还是一个internal loopback。所以本文也作为CAN模块的切入点,使用外部loopback,功能是发送一帧标准帧的CAN数据之后,进入接收状态,收到什么数据,回什么数据出来。本文代码就是基于现有的RTD400的internal loopback例子,添加引脚,对CAN模块做配置,然后添加循环收发功能,测试板子是官方的S32K3X4EVB-T172,并且借助PEAK的PCAN-USB Pro去做测试。

一,代码实现与配置

本文主要讲解如何在S32K344上实现具体的功能,关于CAN的理论知识,建议详细阅读K344RM,写的非常的好,足以掌握K344 FlexCAN的特性了。

1.1 S32DS3.5导入CAN工程

File-》S32DS Project from example
选择下图中的FlexCAN代码,并且给工程取一个你自己认为最闪亮的名字。
在这里插入图片描述

图1

然后就可以导入例程中对应的FlexCAN工程了,双击FlexCAN_example_CT.mex进入到对应的CT工具界面,可以先生成下代码,回来编译下,然后下载了直接体验loopback功能,这个main函数写的也是相当的任性,不过有总比没有好,总归还是提供了点参考。

1.2 添加CAN使用的引脚

为了实现和外部CAN节点的交互,还是需要配置相关的引脚的,查看S32K3X4EVB-T172原理图,发现对应的CAN外部收发器情况如下图,并且CAN0_TX=PTA7, CAN0_RX=PTA6.

在这里插入图片描述

图2

这里一定要特别注意下自己的板子上的CAN收发器的型号,如果是TJA1153,那个是加密的HS-CAN收发器,需要先解密再去做通讯,如果是TJA1443,没问题,可以直接用,我这边连外部的收发器控制引脚都没有控制,直接借助于外部上下拉去实现了。如果实际使用中没有这样的上下拉电路,还是需要去配置对应的控制引脚,在代码中给定相应的电平。
打开CT工具,选择Pins,然后把package改成172脚的封装,并且在peripheral signals里面选择CAN0,添加两个脚为PTA6,PTA7.
在这里插入图片描述

图3

这里要注意,会发现右边的problems有报错,然后鼠标选中问题,右击,选中add sdk components “pins”to xxx project.
在这里插入图片描述

图 4

1.3 添加外设模块

下面开始添加本文章需要的外设模块,CT切到peripherals,在Drivers里面添加Siul2_Port.
打开Siul2_Port,在PortConfigSet中添加两个CAN的引脚,主要要选对mscr号。
在这里插入图片描述

图5

在这里插入图片描述

图6

点击FlexCAN模块,配置如下:
在这里插入图片描述

图7

主要修改FlexCAN operation modes为normal mode or user mode.
然后还要检查下FlexCAN protocol clock,这里是24000000,因为不是自动获取,而是手动填入,一定要和clock界面配置的CAN0的时钟源一致,否则会通讯出问题。

1.4 时钟检查

CT工具打开时钟界面clock,检查FLEXCAN0的时钟如下,正好是24Mhz,所以没有问题
在这里插入图片描述

图 8

到目前为止,所有的配置都成功了,点击update code生成代码。

1.5 加入代码

正如上面所说,本文的目的是实现外部循环,首先发一帧数据出去,然后接受外部的CAN总线节点发来的数据并且循环出去,main.c代码添加如下:

#include "Mcal.h"
#include "Clock_Ip.h"
#include "FlexCAN_Ip.h"
#include "IntCtrl_Ip.h"
#include "Siul2_Port_Ip.h"

#define MSG_ID 20u
#define RX_MB_IDX 1U
#define TX_MB_IDX 0U
volatile int exit_code = 0;
/* User includes */
uint8 dummyData[8] = {1,2,3,4,5,6,7,8};
/*!
  \brief The main function for the project.
  \details The startup initialization sequence is the following:
 * - startup asm routine
 * - main()
*/
extern void CAN0_ORED_0_31_MB_IRQHandler(void);

int main(void)
{
    /* Write your code here */
    Clock_Ip_Init(&Clock_Ip_aClockConfig[0]);

    Siul2_Port_Ip_Init(NUM_OF_CONFIGURED_PINS_PortContainer_0_BOARD_InitPeripherals, g_pin_mux_InitConfigArr_PortContainer_0_BOARD_InitPeripherals);

    IntCtrl_Ip_EnableIrq(FlexCAN0_1_IRQn);
    IntCtrl_Ip_InstallHandler(FlexCAN0_1_IRQn, CAN0_ORED_0_31_MB_IRQHandler, NULL_PTR);

    Flexcan_Ip_DataInfoType rx_info = {
            .msg_id_type = FLEXCAN_MSG_ID_STD,
            .data_length = 8u,
            .is_polling = TRUE,
            .is_remote = FALSE
    };
    Flexcan_Ip_MsgBuffType rxData;
       FlexCAN_Ip_Init(INST_FLEXCAN_0, &FlexCAN_State0, &FlexCAN_Config0);
       FlexCAN_Ip_SetStartMode(INST_FLEXCAN_0);
       FlexCAN_Ip_ConfigRxMb(INST_FLEXCAN_0, RX_MB_IDX, &rx_info, MSG_ID);
       rx_info.is_polling = FALSE;
       FlexCAN_Ip_Send(INST_FLEXCAN_0, TX_MB_IDX, &rx_info, MSG_ID, (uint8 *)&dummyData);
	    // Polling
	    while(FlexCAN_Ip_GetTransferStatus(INST_FLEXCAN_0, TX_MB_IDX) != FLEXCAN_STATUS_SUCCESS)
	    {
	    	FlexCAN_Ip_MainFunctionWrite(INST_FLEXCAN_0, TX_MB_IDX);
	    }

    for(;;)
    {

            FlexCAN_Ip_Receive(INST_FLEXCAN_0, RX_MB_IDX, &rxData, TRUE);
            while(FlexCAN_Ip_GetTransferStatus(INST_FLEXCAN_0, RX_MB_IDX) != FLEXCAN_STATUS_SUCCESS)
            {
            	FlexCAN_Ip_MainFunctionRead(INST_FLEXCAN_0, RX_MB_IDX);
            }

    	   // dummyData[7] = tx_cnt++;
    	   // FlexCAN_Ip_Send(INST_FLEXCAN_0, TX_MB_IDX, &rx_info, MSG_ID, (uint8 *)&dummyData);
            FlexCAN_Ip_Send(INST_FLEXCAN_0, TX_MB_IDX, &rx_info, MSG_ID, (uint8 *)&rxData.data);
    	    // Polling
    	    while(FlexCAN_Ip_GetTransferStatus(INST_FLEXCAN_0, TX_MB_IDX) != FLEXCAN_STATUS_SUCCESS)
    	    {
    	    	FlexCAN_Ip_MainFunctionWrite(INST_FLEXCAN_0, TX_MB_IDX);
    	    }

    }
    FlexCAN_Ip_SetStopMode(INST_FLEXCAN_0);
    FlexCAN_Ip_Deinit(INST_FLEXCAN_0);
    return 0;
}

编译工程,并且下载到S32K344板子中去。

二,测试结果

测试使用PEAKCAN PCAN-USB PRO,结合PCAN-View实现。注意CAN分析仪和板子的接线一定要接对了,主要涉及3根线:CAN_H,CAN_L,GND
在这里插入图片描述

图9

本文的实物连接情况如上。打开PCAN-view,需要配置下CAN连接波特率,CAN类型。
在这里插入图片描述

图 10

按下板子上的复位按键,可以看到PCAN-View能接收到CAN数据:
在这里插入图片描述

图11

然后在发送窗口,多次改变发送数据发送,能看到接受窗口也是能接收到回环数据。
在这里插入图片描述

图12

由此可见,代码最初的外部回环功能完全实现了。

三,坑位标点排雷

3.1 Siul2_Port报错

这一个坑点,也就在RTD4.0.0上遇到,RTD3.0.0上没有这个问题,所以小编一度想放弃4.0.0去搞3.0.0,实际上也这么干了,但是后面不服气,还是自己尝试出了解决方法。报错情况如下:
在这里插入图片描述

图13

解决方案:因为报错提到container,所以回到pins那边,把Function group的名字重新添加了一个新的:PortContainer_0_BOARD_InitPeripherals
删掉了老的名字,当然这个时候你添加的pin引脚需要重新添加下,添加之后,你的port报错就不存在了。
在这里插入图片描述

图14

3.2 S32K3X4EVB-T172板载的CAN收发器

不同版本的EVB的CAN收发器不一样,老的板子的是TJA1153 Secure HS-CAN Transiver,新的板子是TJA1443,如果是老的,那么需要先刷下收发器固件,具体可以参考这个文章:

https://community.nxp.com/t5/S32K-Knowledge-Base/Example-S32K344-FlexCAN-Ip-TX-RX-EnhanceRXFIFO-test-S32DS3-4/ta-p/1536225

  • 18
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值