[活动专区] 【杰发科技AC7802x测评】3. LIN功能测试以及代码分析

[复制链接]
 楼主| hehung 发表于 2023-6-2 16:11 | 显示全部楼层 |阅读模式
<
#申请原创#

前言

LIN是一种主要用于汽车的低速通信,目前主要用在汽车的车门,车窗,天窗等控制器的通信,这些一般对速度要求不高。并且LIN通信的硬件是基于串口硬件,可以极大的缩减开发成本。AC7802X中的UART集成了LIN功能,本文将对AC7802X的LIN功能做分析以及测试。

关于LIN协议,本文不做介绍。帧格式如下:

614926479a29c96f8f.png

1 硬件分析

首先查看用户手册,了解到AC7802x的LIN功能是非硬件LIN,是基于UART基础上实现的软件LIN,如下:

398716479a2a9342c1.png

下图介绍了如何使用LIN功能:

620576479a2ae56a2c.png

关于LIN接口,AC780X板子上面已经扩展出来了,PA7和PA8分别作为LIN总线的TX和RX接口,这两根线通过一个LIN收发器连接到了LIN总线。

998696479a2b75b6cf.png

427656479a2bea978c.png

调试LIN功能需要一个LIN调试设备,本文使用的是PEAK-LIN作为调试设备,监控单片机上LIN发送的数据。

2 软件分析

官方提供了LIN测试代码,本文测试了Lin_Base工程,该工程中,单片机上的LIN是作为主机工作的,会发送LIN帧头以及LIN响应,从机作为接收方,只需要接收主机的数据即可,本文的从机就是PRAK-LIN。

2.1 初始化代码

初始化代码主要是初始化UART功能以及相应的引脚,使能UART的LIN功能以及波特率,中断等信息,不做过多说明。

  1. void LIN_InitLin(uint8_t mode, uint8_t schTblIdx, uint16_t baudrate)
  2. {
  3.     UART_ConfigType uartConfig;

  4.     memset((void *)&uartConfig, 0, sizeof(UART_ConfigType));  

  5.     /*!初始化LIN的引脚功能
  6.     包括RX/TX及LIN的收发器引脚*/
  7.     GPIO_SetFunc(SWLIN_RX, RXPinFunc);
  8.     GPIO_SetFunc(SWLIN_TX, TXPinFunc);
  9.     GPIO_SetDir(SWLIN_SLP, GPIO_OUT);
  10.     GPIO_SetPinLevel(SWLIN_SLP, GPIO_LEVEL_HIGH);
  11.   
  12.     /*!初始化Uart_LIN及相关参数
  13.     包括波特率及其他配置*/
  14.     uartConfig.baudrate = baudrate;
  15.     uartConfig.dataBits = UART_WORD_LEN_8BIT;
  16.     uartConfig.stopBits = UART_STOP_1BIT;
  17.     uartConfig.parity = UART_PARI_NO;
  18.     uartConfig.fifoByteEn = DISABLE;
  19.     uartConfig.sampleCnt = UART_SMP_CNT0;
  20.     uartConfig.callBack = UartLIN_Handler;
  21.   
  22.     UART_Init(UART_LIN, &uartConfig);

  23.         /*!配置LIN需要使能的功能*/
  24.     UART_SetLIN(UART_LIN, UART_LINCR_LINEN_Msk | UART_LINCR_LBRKIE_Msk | UART_LINCR_LBRKDL_Msk);
  25.      
  26.     /*!配置LIN模块相关中断*/
  27.     UART_SetRXNEInterrupt(UART_LIN, DISABLE);
  28.     UART_SetTXEInterrupt(UART_LIN, DISABLE);
  29.     NVIC_ClearPendingIRQ(UART_LIN_IRQn);
  30.     NVIC_EnableIRQ(UART_LIN_IRQn);
  31. }



2.2 报文传输函数

如下,因为不是硬件LIN,所以LIN协议中的同步场和校验和场都需要软件来填写:

- `g_LinDataTx[0] = 0x55;`是同步场报文,固定为0x55
- `g_LinDataTx[1] = 0x50;`是标识符场,也就是报文的PID,前六位是ID,后两位是奇偶校验位,计算方式见下图,所以真实ID为0x10。

560196479a2fa94cb2.png

905736479a300a9faf.png

- `g_LinDataTx[2]~g_LinDataTx[9]`是8位数据,导入的数据从0开始依次向上加
- 接下来是计算校验和,这里使用的是经典校验和,增强检验和需要加上PID段,计算方式是就爱那个8位数据依次加起来,如果大于了0xFF,则丢掉高位,保留低两位。
- 最后将校验和放到 `g_LinDataTx[2]`中
- 以上步骤就组成了一个完整的LIN报文。
- 最后使用 `UART_SendData(UART0, g_LinDataTx[j]);`依次将数据通过串口发送出去就完成了LIN报文的发送。

  1. void SendSimpleLinMessage(void)
  2. {
  3.     static uint16_t checksum = 0;
  4.     static uint8_t i = 0, a = 0;
  5.     static uint8_t j = 0;
  6.     a++;

  7.     UART_SendLINBreak(UART0);
  8.   
  9.     /*!LIN数据填充,包括同步场和校验场*/
  10.     g_LinDataTx[0] = 0x55;
  11.     g_LinDataTx[1] = 0x50;
  12.     g_LinDataTx[2] = a+1;
  13.     g_LinDataTx[3] = a+2;
  14.     g_LinDataTx[4] = a+3;
  15.     g_LinDataTx[5] = a+4;
  16.     g_LinDataTx[6] = a+5;
  17.     g_LinDataTx[7] = a+6;
  18.     g_LinDataTx[8] = a+7;
  19.     g_LinDataTx[9] = a+8;

  20.     /*!增强型校验和需要加上ID*/
  21.     checksum = g_LinDataTx[1];
  22.     for (i = 2; i < 10; i++)
  23.     {
  24.         checksum += g_LinDataTx[i];
  25.         if (checksum >= 0x100)
  26.         {
  27.             checksum -= 0xFF;
  28.         }
  29.     }
  30.     checksum ^= 0xFF;
  31.     /*!数据校验和*/
  32.     g_LinDataTx[10] = checksum;

  33.     /*!发送同步域,ID,数据域,校验和*/
  34.     for(j = 0;j < 11;j++)
  35.     {
  36.         UART_SendData(UART0, g_LinDataTx[j]);
  37.     }
  38.     checksum = 0;
  39. }



2.3 中断

本例中其实没有用中断,中断主要是用来处理数据接收以及传输错误,下面是示例代码,中断没有使用,如果要使用LIN数据接收的功能,需要使用中断UART_LSR0_DR_Msk。

  1. void UartLIN_Handler(void *device, uint32_t wpara, uint32_t lpara)
  2. {
  3.     /*!Receive break field*/
  4.     if (0 != (lpara & UART_LSR1_FBRK_Msk))
  5.     {
  6.                 /*!<write 1 to clear break status*/
  7.         UART_LIN->LSR1 |= UART_LSR1_FBRK_Msk;   
  8.     }
  9.     /*!Receive data*/
  10.     if (0 != (wpara & UART_LSR0_DR_Msk))
  11.     {

  12.     }
  13.     /*!Transmit data done*/
  14.     if (0 != (wpara & UART_LSR0_THRE_Msk))
  15.     {

  16.     }

  17. }



2.4 主函数

主函数逻辑如下:

- `LIN_InitLin(MASTER_MODE, 0, 19200);`是初始化LIN作为主模式,并且设置波特率为19200(LIN支持的最大波特率)
- `SendSimpleLinMessage()`发送数据

  1. int main(void)
  2. {
  3.   
  4.     InitDelay();
  5.     InitDebug();
  6.     /*!for master initlin*/
  7.     LIN_InitLin(MASTER_MODE, 0, 19200);

  8.     while(1)
  9.     {
  10.         SendSimpleLinMessage();
  11.         mdelay(500);
  12.     }
  13. }



3 实验结果

如下图,trace界面会收到单片机发送的LIN报文,每个500ms会收到一次数据,数据ID为0x10,数据长度为8,每次接受到的数据会一次增大一位,与之前的分析吻合。

994136479a32b404c5.png

总结

虽然AC7802X没有集成完全的硬件LIN,但是在UART的基础上增加了LIN相关寄存器,可以用于软件扩展LIN功能,也满足了大部分使用场景,可以用于这在LIN通信,而且操作相对简单,还是很不错的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

10

主题

66

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部