功能需求
RT117X 系列 MCU 在汽车和工业类产品中有广泛应用,有很多客户对 LIN 通讯有需求, RT1176 有 12 路独立的 LPUART 接口,最大支持的波特率能支持到 20M ,而且每一路都支持 Break 发送和中断接收,可以用来配合定时器实现 LIN 的主机和从机通讯。但是目前 RT117X 的 EVK 板没有放置 LIN 的收发器, SDK 也没有相关 LIN 的示例代码和 LIN 协议栈支持,所以本示例目的是移植 KW36 工程中的 LIN 2.1 版本的代码到 RT1176 EVK 板子上,在硬件上通过跳线将 LIN Master 主节点和 Slave 从节点的 LPUART TX/RX 线连接到 FRDM-KW36 板载的 LIN 收发器 TJA1027 上,分别实现 LIN 2.1 版本协议栈在 Master 和 Slave 节点的通讯功能验证,同时还需支持 Auto Baud Rate 自动波特率调整。为客户做二次开发或者移植用户自己的 LINstack 提供底层驱动,提高开发效率。
代码包软件
RT1176 LIN Master 节点代码: RT1170_LIN_Porting_Demo_Master.7z
RT1176 LIN Slave 节点代码 ( 支持自动波特率 😞
RT1170_LIN_Porting_Demo_Slave_with_Auto_Baud_Rate.7z
配置 FRDM-KW36 板载 LIN 收发器的代码 : KW36_LIN_PHY_Board_Init.7z
硬件 Setup
MIMXRT1170-EVK : 2pcs ,分别用作 LIN Master 节点和 Slave 节点。
FRDM-KW36 : 2pcs , 分别用作 Master 节点的收发器,和 Slave 节点的收发器
下图是系统连接,2块RT1170 EVK板分别和2块FRDM-KW36板通过Arduino接口连接在一起,然后将两块KW36之间的LIN收发器通过 J13 连接在一起,需要使用外部12V adapter为FRDM-KW36供电,否则板上的LIN收发器无法工作。特别强调的是,如果需要使能自动波特率检测的话,还需要将Slave节点RT1176 Arduino接口的J9-Pin2引脚连接到RT1176 Arduino接口的J9-Pin12引脚,作为Timer 脉冲捕捉的输入,即可完成系统硬件的setup。
软件Setup:
在以上硬件连接完成后,按照如下步骤下载对应软件:
- Step1: 下载KW36_LIN_PHY_Board_Init.7z代码到两块FRDM-KW36板子上;
该代码中主要实现两个功能:第1个拉高板子的PTC5引脚,唤醒LIN收发器TJA1027。第2个将PTA18引脚配置成disable高阻状态。如果该引脚作为GPIO输出或者LPUART TX功能,会导致LIN slave回应数据出错(bit位丢失或者错误)。究其原因猜测应该是短路导致,当这个引脚作为GPIO输出或者LPUART TX功能,内部会有上拉,当RX1176 TX引脚输出Low时,由于电路上没有串联电阻(板子上使用的0Ω),会导致引脚上出现大电流。尤其是第2个点,花费了很多时间去查这个问题,从波形去看,是有数据输出的,但只是数据不对,很具有迷惑性。当然如果客户是自己打的板子,板子上已经有LIN收发器就不需要这一步,直接跳到Step2即可。
- Step2: 下载RT1170_LIN_Porting_Demo_Master.7z代码到作为Master节点的IMRT1176-EVK板;
- Step3: 下载RT1170_LIN_Porting_Demo_Slave_with_Auto_Baud_Rate.7z代码到作为Slave节点的IMRT1176-EVK板,如果需要使能自动波特率调整,需要配置宏linUserConfigSlave.autobaudEnable = true; 代码中默认是打开的。
实验结果
打开两个IMRT1176-EVK板串口,波特率配置115200,单击RT1176 Master节点上的按键SW7,便可以启动Master节点开始发送数据,通讯波形和串口打印信息如下两张图所示。
代码移植的几个难点
1. LIN通讯协议栈的调度流程的理解,包括Wakeup段,Break段,Sync段,PID段,Data段的状态切换和跳转,每个段的超时监测和错误处理,其核心思想有两个:一个在于LIN的RX引脚要不断去monitor TX引脚的状态,然后去切换状态机,具体调度的流程在后文会详细介绍,这里不展开。第二个是准确获取在每个段的定时器时间,尤其是超时超过一个overflow周期的情况,需要对timerGetTimeIntervalCallback0函数有理解。
2. 自动波特率调整功能的支持,该功能的原理是测量SYNC段的8个脉冲的脉宽,如果每个脉宽差异在2%范围内,再根据脉冲宽度去判断对应的波特率。在原来KW36的代码中是使用TPM的Overflow中断来作为计时,Edge中断来触发,而RT1176没有TPM,只能使用Qtimer (Qtimer功能上要更强于TPM),但是不巧的是Qtimer不支持Overflow中断(参见芯片ERRATA 050194),所以只能使用compare中断来实现类似的功能,而原有的计时定时计算都是基于overflow的,因此就需要对定时器部分的代码做大范围的更改。
应用中考虑到timerGetTimeIntervalCallback0函数在自动波特率调整时和超时监测处理时的一致性,最好使用同一个Timer的同一个channel,这就需要这个Timer既支持普通的定时中断模式,又支持input capture功能。对于TPM来说,是无法实现的因为两次在寄存器配置上时互斥的, 参见下图。幸运的是Qtimer支持这个feature,只是需要根据SDK代码做些配置
前面提到,需要QTimer支持input capture功能, 触发信号是LPUART_RX引脚的信号,需要硬件loop到Qtimer支持的硬件引脚上,对于KW36来说,只需要把这两个物理引脚连接在一起即可,但对RT1176来说, 只有这一步还不行,还需要对XBAR进行配置,将Qtimer的TIMER 1的触发引脚(合计有4个物理引脚)Link到QTIMER对应的Channel上,因为RT1176有4个QTimer,每个Qtimer有4个通道,标称的Qtimer trigger pin有4个,那具体哪个pin触发哪个QTimer的哪个通道,是需要配置的。如果客户没有使用过XBAR配置起来有难度,还好MCUXpresso config tool支持配置,可以简便的完成配置。示例代码和触发关系如下,如果实际硬件使用的物理引脚有区别,需要对应修改。
RT的XBAR功能非常强大,或许可以不使用外部的物理连线,直接将Qtimer的出发引脚的信号直接在内部Loop到LPUART_RX引脚,这样就更加灵活,此处只提供一个思路,不再进一步延伸。
IOMUXC_GPR->GPR15 = ((IOMUXC_GPR->GPR15 & (~(IOMUXC_GPR_GPR15_QTIMER4_TRM1_INPUT_SEL_MASK | IOMUXC_GPR_GPR15_QTIMER4_TRM2_INPUT_SEL_MASK)))/*Mask bits to zero which are setting*/ | IOMUXC_GPR_GPR15_QTIMER4_TRM1_INPUT_SEL(0x00U) /*QTIMER4 TMR1 input select: 0x00U*/ | IOMUXC_GPR_GPR15_QTIMER4_TRM2_INPUT_SEL(0x00U) /*QTIMER4 TMR2 input select: 0x00U*/ );
4. 在状态机切换和超时以及错误处理过程中,经常会看到两种模式Sleep模式和Idle模式,区别是什么呢?
LIN_LPUART_GoToSleepMode: 函数会关闭 Break 中断, RX 接收中断,帧错误中断,保留 RX 边沿 中断 ; LIN_LPUART_GotoIdleState 函数会打开 Break 中断, RX 接收中断,帧错误中断,关闭 RX 边沿中 断 ;
实际通讯波形
Master 作为 Subscribe 角色时,发送 Header ,由 Slave 发送 Respone
Master 作为 PUBLIC 角色时,同时发送 Header ,以及 Respone
按照调度表依次发送 LI0_lin_configuration_RAM 数组定义的 PID 数据
static uint8_t LI0_lin_configuration_RAM[LI0_LIN_SIZE_OF_CFG]= {0x00, 0x30, 0x33, 0x36, 0x2D, 0x3C, 0x3D ,0xFF};
Qtimer 准确读取 wake up 信号的脉冲宽度
Slave 使能 Auto baud rate 后读取到的每个脉冲宽度数据
免责声明:
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND *ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED *WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, *INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUTNOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, ORPROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY,WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE)
View full article