UART控制器LIN功能模式(NUC029LAN阅读笔记)

2023-05-16

UART控制器LIN功能模式(NUC029LAN阅读笔记)

  • LIN总线帧格式
    • 字节域格式(LIN标准)
    • 帧头(Header)
      • 同步间隔域(Break Field)
      • 同步域(Sync Byte Field)
      • 受保护ID域(Protected Identifier Field)
    • 响应域(Response)
      • 数据域(Data1~N)
      • 校验和(Checksum)
  • LIN总线编程流程

LIN总线帧格式

一个LIN信息帧包含帧头(Header)和响应(Response)。
帧头(Header) 包含:间隔域(Break Field),同步域(Sync Field)和受保护的标识符域(Protected Indentifier Field);
响应(Response) 包含:数据域(Data1~N),校验和(Checksum)。
字节之间有字节间隔(InterByteSpace),在头信息和响应之间有一个响应间隔(ResponseSpace),这两个间隔的最小值为0。

下图是LIN功能模式的帧结构:
LIN的帧结构图

下图是LIN功能模式的帧格式:
LIN帧结构

字节域格式(LIN标准)

除起始域(Header)与响应间隔(ResponseSpace),其他部分都是以字节为单位传送,每个字节都有自己的格式,称之为字节域(ByteField)

在LIN 模式下,根据LIN的标准,每个字节域的开始都是由一个值为0的起始位(显性的),后面跟随8个位的数据(LSB 优先),最后以一个值为1的停止位(隐性的)结束。

字节域(Byte Field):1位起始位(Start Bit,显性,值为0)+ 8位数据位 + 1位停止位(Stop Bit,隐性,值为1),是一种标准UART 数据传输格式。

下图是LIN功能模式的字节域格式:
字节域格式(LIN标准)

帧头(Header)

同步间隔域(Break Field)

下图是LIN功能模式的同步间隔域格式:
同步间隔域格式

同步域(Sync Byte Field)

同步域(Sync Byte Field),是固定值(0x55),二进制是01010101,由于是先发送低位,也就是先发送1。

下图是LIN功能模式的同步域格式:
同步域格式

受保护ID域(Protected Identifier Field)

受保护ID域(Protected Identifier Field),前6位为帧ID(Frame ID),最高两位是奇偶校验。

帧ID(Frame ID),前6位为帧ID,范围在0x00~0x3F之间。帧ID标识了帧的类别。从机任务对于帧头作出的反应(接收/发送/忽略应答部分)都是依据帧ID判断的。如果帧ID传输错误,将会导致信号无法正确到达目的地。因此引入奇偶校验位。
奇偶校验(Parity Check),最高两位是奇偶校验,其中ID6 是ID0、ID1、ID2、ID4 的奇校验,ID7 是ID1、ID3、ID4、ID5 的偶校验。

校验公式如下,其中“⊕”代表“异或”运算,“¬”代表“取非”运算。
P0 = ID0 ⊕ID1 ⊕ID2 ⊕ID4
P1 = ¬ (ID1 ⊕ID3 ⊕ID4 ⊕ID5)
(由公式可以看出,PID不会出现全0或全1的情况,因此,如果从机节点收到了“0xFF”或“0x00”,可判断为传输错误。)

下图是LIN功能模式的ID域格式:
ID域格式

下列是NUC029xANSeriesBSP固件库中,ID域奇偶校验位求值函数的代码:

/*---------------------------------------------------------------------------------------------------------*/
/* Compute Parity Value                                                                                    */
/*---------------------------------------------------------------------------------------------------------*/
// 获取ID域的奇偶校验值(指定ID),返回ID域值
// 计算指定ID的奇偶校验位,并返回ID域值
uint8_t GetParityValue(uint32_t u32id)
{
    uint32_t u32Res = 0, ID[6], p_Bit[2] , mask = 0;

	// 将ID存入ID[0:5]
    for(mask = 0; mask < 6; mask++)
        ID[mask] = (u32id & (1 << mask)) >> mask;

	// 获取ID域奇偶检验位值
	// ID6(p_Bit[0])是ID0、ID1、ID2、ID4的奇校验
	// ID7(p_Bit[1])是ID1、ID3、ID4、ID5的偶校验
    p_Bit[0] = (ID[0] + ID[1] + ID[2] + ID[4]) % 2;
    p_Bit[1] = (!((ID[1] + ID[3] + ID[4] + ID[5]) % 2));

	// 得到ID域值u32Res(前6位是ID,高两位是奇偶校验位)
    u32Res = u32id + (p_Bit[0] << 6) + (p_Bit[1] << 7);
	//  返回ID域值
    return u32Res;
}

【校验和求值示例】
ID域对0x12的ID求校验位
xx01 0010 (0x12)
ID6 = (ID[0] + ID[1] + ID[2] + ID[4]) % 2; = 0
ID7 = (!((ID[1] + ID[3] + ID[4] + ID[5]) % 2)); = 1
得到ID域为
1001 0010 (0x92)




响应域(Response)

LIN协议中,一帧信息的响应域由数据域和校验码域两部分构成。

数据域(Data1~N)

每个数据域的开始都是由一个值为0的起始位 (显性的),后面跟随8个位的数据(LSB 优先),最后以一个值为1的停止位(隐性的)结束。

下图是LIN功能模式的数据域格式:
数据域格式

校验和(Checksum)

校验和(Checksum),是所有数据(可能包含ID域)带进位的8位和(即所有数据累加,大于等于256时,减去255)。

校验和计算方法:将校验对象的各字节作带进位二进制加法(每当结果大于等于256 时就减去255),并将所得最终的和逐位取反,以该结果作为要发送的校验和。

接收方根据校验和类型,对接收数据作相同的带进位二进制加法,最终的和不取反,并将该和与接收到的校验和作加法,如果结果为0xFF,则校验和无误。这在一定程度上保证了数据传输的正确性。

下图是LIN功能模式的校验和格式:
校验和格式

下列是NUC029xANSeriesBSP固件库中,校验和求值函数的代码:

/* CheckSum Method */					// 校验模式
#define MODE_CLASSIC    2			// 经典模式-不包含ID的校验位
#define MODE_ENHANCED   1			// 增强模式-包含ID的校验位

/*---------------------------------------------------------------------------------------------------------*/
/* Compute CheckSum Value , MODE_CLASSIC:(Not Include ID)    MODE_ENHANCED:(Include ID)                    */
/*---------------------------------------------------------------------------------------------------------*/
// 获取校验和的值(发送数组,选择校验模式)
// 计算检验和:所有数据累加,大于等于256时,减去255;并将所得最终的和逐位取反
uint32_t GetCheckSumValue(uint8_t *pu8Buf, uint32_t u32ModeSel)
{
    uint32_t i, CheckSum = 0;

		// 计算检验和
		// 所有数据累加,大于等于256时,减去255
		// pu8Buf=g_u8SendData,[0]为同步域[1]为ID域
		// 包含ID的校验位,从[1]位ID域开始求和
		// 不包含ID的检验位,从[2]位响应域开始求和
    for(i = u32ModeSel; i <= 9; i++)
    {
        CheckSum += pu8Buf[i];
        if(CheckSum >= 256)
            CheckSum -= 255;
    }
		// 并将所得最终的和逐位取反
    return (255 - CheckSum);
}

【校验和求值示例】
数据1域0x1:g_u8SendData[3] = 01
数据2域0x2:g_u8SendData[4] = 02
数据3域0x3:g_u8SendData[5] = 03
数据4域0x4:g_u8SendData[6] = 04
数据5域0x5:g_u8SendData[7] = 05
数据6域0x6:g_u8SendData[8] = 06
数据7域0x7:g_u8SendData[9] = 07
数据8域0x8:g_u8SendData[10] = 08
校验和含ID:g_u8SendData[11] = 49

求校验和(不含ID)
01+02+03+04+05+06+07+08=0x24
~0x24=0xDB
得g_u8SendData[11] = DB

求校验和(含ID)
92+01+02+03+04+05+06+07+08=1011 0110=0xB6
~0xB6=0100 1001=0x49
得g_u8SendData[11] = 49




LIN总线编程流程

LIN总线发送(TX)编程流程如下:

  1. 设置 UA_FUN_SEL[1:0] 为 01 来使能 LIN 总线模式。
  2. 设置 UA_LIN_BKFL(UA_ALT_CSR[3:0])寄存器来选择 break 域长度。(break 域的长度为UA_LIN_BKFL+2)
  3. 将THR(UA_THR[7:0])设置为0x55,来请求发送同步域。
  4. 通过写受保护的标识值到UA_THR中,来请求标识域传输。
  5. 设置 LIN_TX_EN(UA_ALT_CSR[7]) 位来开始传输(当break操作完成后,LIN_TX_EN(UA_ALT_CSR[7])将会被自动清除)。
  6. 当THR寄存器中最后一个字节中的STOP位发送到总线上后,硬件将会设置UA_FSR寄存器中的TE_FLAG位为1。
  7. 填N个字节的数据和校验码到THR(UA_THR[7:0]),然后重复步骤5和步骤6来发送数据。

下列是NUC029xANSeriesBSP固件库中,LIN总线主机发送LIN帧头、响应域的代码:

/*---------------------------------------------------------------------------------------------------------*/
/* Global variables                                                                                        */
/*---------------------------------------------------------------------------------------------------------*/
// 发送数组[]={同步域,ID域,数据位,校验和}
uint8_t g_u8SendData[12] = {0};				// 发送数组
volatile int32_t g_i32pointer = 0;		// 发送数组下标

/*---------------------------------------------------------------------------------------------------------*/
/*  Master send header and response                                                                        */
/*---------------------------------------------------------------------------------------------------------*/
// LIN主机测试(指定ID,选择模式)
// 发送LIN帧头、发送响应域
void LIN_MasterTest(uint32_t u32id, uint32_t u32ModeSel)
{
		// 发送数组
    uint32_t testPattern[8] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8};

    /*Send ID=0x35 Header and Response TestPatten*/
		// 发送LIN帧头(指定ID域u32id)
		// 发送响应域(检验模式)
    LIN_SendHeader(u32id);
    LIN_SendResponse(u32ModeSel, &testPattern[0]);
}

/*---------------------------------------------------------------------------------------------------------*/
/*  Send LIN Header Field                                                                                  */
/*---------------------------------------------------------------------------------------------------------*/
// 发送LIN帧头(指定ID域)
// 设定LIN模式Break域长度\
// 发送同步域0x55\
// 发送ID域(通过GetParityValue获取指定ID的ID域)
void LIN_SendHeader(uint32_t u32id)
{
    g_i32pointer = 0 ;		// g_u8SendData发送数组

    /* Set LIN operation mode, Tx mode and break field length is 13 bits */
		// Uart1设置LIN TX Break模式使能,设定13位break域
    UART_SelectLINMode(UART1, UART_ALT_CSR_LIN_TX_EN_Msk, 11);

		// 同步域0x55存入发送数组
		// 获取u32id的ID域的值存入发送数组
		// 通过UART1将发送数组发送出去,两个八位字节
    g_u8SendData[g_i32pointer++] = 0x55 ;                   // SYNC Field
    g_u8SendData[g_i32pointer++] = GetParityValue(u32id);   // ID+Parity Field
    UART_Write(UART1, g_u8SendData, 2);
}

/*---------------------------------------------------------------------------------------------------------*/
/*  Send LIN Response Field                                                                                */
/*---------------------------------------------------------------------------------------------------------*/
// 发送响应域(选择校验模式,发送数组)
// 将数据位、校验和存入发送数组,通过UART1发送
void LIN_SendResponse(int32_t checkSumOption, uint32_t *pu32TxBuf)
{
    int32_t i32;
		
		// 将pu32TxBuf存入发送数组g_u8SendData
    for(i32 = 0; i32 < 8; i32++)
        g_u8SendData[g_i32pointer++] = pu32TxBuf[i32] ;

		// 将GetCheckSumValue获取的校验值存入发送数组
    g_u8SendData[g_i32pointer++] = GetCheckSumValue(g_u8SendData, checkSumOption) ; //CheckSum Field

		// 通过UART1从发送数组[2]开始发送9位响应域(数据位+检验和)
    UART_Write(UART1, g_u8SendData + 2, 9);
}


LIN 总结接收(RX)编程流程如下:

  1. 设置 UA_FUN_SEL[1:0] 为 01 来使能 LIN 总线模式。
  2. 设置 LIN_RX_EN(UA_ALT_CSR[6]) 来使能 LIN RX模式。
  3. 等待标志 LIN_RX_BREAK_IF(UA_ISR[7]) 来检测RX是否接收到 break 域。
  4. 等待标志RDA_IF(UA_ISR[0])并且从RBR(UA_RBR[7:0])寄存器读回数据。




参考:

  • 《TRM_NUC029_Series_SC_Rev1.04.pdf》
  • 《 LIN协议中的帧结构与同步域(0x55)》杭州山不高

声明:[笔记整理] 内容整理自网络,版权归原作者所有,若有侵权请联系删除。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

UART控制器LIN功能模式(NUC029LAN阅读笔记) 的相关文章

  • c语言入门基础

    C语言的结构 1 Hello world 简单来说 xff0c 一个C程序就是由若干头文件和函数组成 include 包含头文件 主函数 int main printf Hello World return 0 include 就是一条预处
  • 单片机串行口介绍

    介绍 串行口是单片机与外界进行信息交换的工具 xff0c 8051单片机的通信方式有两种 xff1a 并行通信 数据的各位同时发送或接收 串行通信 数据一位一位次序发送或接收 串行通信的方式 异步通信 用一个起始位0表示字符的开始 xff0
  • 51单片机中断机制(定时器)

    单片机中断简介 52单片机一共有6个中断源 xff0c 它们的符号 xff0c 名称以及各产生的条件分别如下 xff1a INT0 外部中断0 xff0c 由P3 2端口线引入 xff0c 低电平或下降沿引起 INT1 外部中断1 xff0
  • 什么叫51单片机最小系统

    单片机最小系统 或者称为最小应用系统 是指用最少的元件组成的单片机可以工作的系统 对51系列单片机来说 最小系统一般应该包括 单片机 晶振电路 复位电路 下面给出一个51单片机的最小系统电路图 说明 复位电路 由电容串联电阻构成 由图并结合
  • 嵌入式系统C编程之错误处理

    一 错误概念 1 1 错误分类 从严重性而言 xff0c 程序错误可分为致命性和非致命性两类 对于致命性错误 xff0c 无法执行恢复动作 xff0c 最多只能在用户屏幕上打印出错消息或将其写入日志文件 xff0c 然后终止程序 而对于非致
  • 补光灯的单片机开发设计

    说到摄影灯 xff0c 相信每个人都一定听说过闪光灯和补光灯 那它们是怎么由来的呢 又是怎么达到了你想要的效果呢 不论是闪光灯还是补光灯 xff0c 它们都有一个共同点 xff0c 那就是由NY8A051D单片机开发而来 xff0c 单片机
  • 单片机C语言如何产生随机数

    单片机C语言如何产生随机数 随机数在单片机的应用中也是很多的 xff0c 当然产生随机数的方法有很多 xff0c 当中有一个就是利用单片机定时器 xff0c 取出未知的定时器THX和TLX的值 xff0c 再加以运算得到一个规定范围内的随机
  • 使用mac终端编译运行c程序

    使用mac终端编译运行c程序 本文介绍如何利用mac自带文本编辑软件编写c代码 xff0c 并在mac自带终端内用命令行编译运行c程序 1 在mac上安装c编译环境 打开mac自带的终端 在终端命令行里输入xcode select inst
  • HtmlParser 一个不错的网站爬虫工具

    有时候我们需要在网上获取自己需要的内容时 xff0c 而且需求量达到一定程度时 xff0c 就要通过代码来实现重复的操作 当用Java来帮我们解决这个问题时 xff0c 我们又如何通过Java来过滤掉多余的内容 xff0c 剩余自己想要的信
  • 因为jsoup,再见了我的htmlparser

    jsoup 一款Java 的HTML解析器 xff0c 可直接解析某个URL地址 HTML文本内容 它提供了一套非常省力的API xff0c 可通过DOM xff0c CSS以及类似于jQuery的操作方法来取出和操作数据 这里是jsoup
  • Python 当前时间是那一年第几周的周几

    isocalendar 函数 返回 xff08 XX年 xff0c 一年中的第几周 xff0c 这一天是周几 xff09 gt gt gt from datetime import datetime gt gt gt datetime no
  • 对Socket CAN的理解(1)——【CAN总线原理】

    转载请注明出处 xff1a http blog csdn net Righthek 谢谢 xff01 由于Socket CAN涉及到CAN总线协议 套接字 Linux网络设备驱动等 因此 xff0c 为了能够全面地了解Socket CAN的
  • 对Socket CAN的理解(2)——【Socket的原理及使用】

    转载请注明出处 xff1a http blog csdn net Righthek 谢谢 xff01 为了能够对Socket CAN的深入理解 xff0c 我们需要了解Socket的机制 Socket的中文翻译为 插座 xff0c 在计算机
  • 【智能家居篇】wifi网络结构(上)

    转载请注明出处 xff1a http blog csdn net Righthek 谢谢 xff01 WIFI是什么 xff0c 相信大家都知道 xff0c 这里就不作说明了 我们需要做的是深入了解其工作原理 xff0c 包括软硬件 网络结
  • 【智能家居篇】wifi网络结构(下)

    转载请注明出处 xff1a http blog csdn net Righthek 谢谢 xff01 由于WIFI网络具有移动性 xff0c 同时WIFI以无线电波作为传输媒介 xff0c 这种媒介本质上是开放的 xff0c 且容易被拦截
  • 【智能家居篇】wifi网络接入原理(上)——扫描Scanning

    转载请注明出处 xff1a http blog csdn net Righthek 谢谢 xff01 对于低头党来说 xff0c 在使用WIFI功能时 xff0c 经常性的操作是打开手机上的WIFI设备 xff0c 搜索到心目中的热点 xf
  • 【智能家居篇】wifi网络接入原理(下)——关联Association

    转载请注明出处 xff1a http blog csdn net Righthek 谢谢 xff01 认证完成后 xff0c 下一步就是关联 xff08 Association xff09 工作站与基站进行关联 xff0c 以便获得网络的完
  • 【智能家居篇】wifi驱动的理解(3)——usb接口在wifi模块中的角色

    转载请注明出处 xff1a http blog csdn net Righthek 谢谢 xff01 上一篇文章已经提到USB接口在wifi模块中的最重要两个函数是usb read port 和usb write port 那它们是怎么和w
  • 【智能家居篇】wifi驱动的理解(4)——usb接口在wifi模块中的角色

    转载请注明出处 xff1a http blog csdn net Righthek 谢谢 xff01 还有1天就到2017年了 xff0c 回顾整个2016年至此 xff0c 都没发表过一篇技术文章 做软件开发已有5 6年 xff0c 作为
  • mx51 TVOUT分析

    1397 static int init enable tve setup char options 1398 1399 g enable tve 61 true 1400 1401 return 1 1402 1403 setup 34

随机推荐

  • 2D图形加速引擎(GE2D)

    转载请注明出处 xff1a http blog csdn net Righthek 谢谢 xff01 英文原文 NUC970 Series Technical Reference Manual Chapter 5 28 一 概述 32位2D
  • Redis 安装

    安装 下载 解压 编译Redis wget http download redis io releases redis 6 0 6 tar gz tar xzf redis 6 0 6 tar gz cd redis 6 0 6 make
  • linux下 tcpdump实现原理

    linux下抓包实现原理 一 tcpdump 对于本机中进程的系统行为调用跟踪 xff0c strace是一个很好的工具 xff0c 而在网络问题的调试中 xff0c tcpdump应该说是一个必不可少的工具 xff0c 和大部分linux
  • eigen求特征值和特征向量

    Eigen Matrix2d matrix 22 matrix 22 lt lt 2 3 2 1 cout lt lt 34 matrix 61 n 34 lt lt matrix 22 lt lt endl Eigen SelfAdjoi
  • sophus库的一些使用

    首先是cmakelists cmake minimum required VERSION 2 8 project useSophus 为使用 sophus xff0c 您需要使用find package命令找到它 find package
  • OpenCV中ORB特征点检测和匹配简单用法

    cmakelists span class hljs keyword cmake minimum required span VERSION span class hljs number 3 7 span span class hljs k
  • LKflow

    cmakelists span class hljs keyword cmake minimum required span VERSION span class hljs number 3 7 span span class hljs k
  • 关于关于高博3d2d程序报错的改动

    想直接改动 xff0c 在 还是g2o初始化一些 那篇 xff0c 这篇比较啰嗦 xff0c 主要是记录自己思考的步骤 首先说明主题 xff1a 没文化真可怕 好了 xff0c 说干货 之前高博的代码 只要涉及g2o的部分 xff0c 一律
  • C++类内成员初始化

    所有标准为C11标准 xff0c 旧的就不看了 首先说一条指导规则 xff1a 通常情况下 xff0c 不应该在类内部初始化成员 xff01 xff01 无论是否为静态 是否为常量 是否为int等 xff01 xff01 统统不建议在类内初
  • RANSAC算法理解

    最早应该是十四讲上见过 xff0c 在第九章的project中src中的visual odometry cpp中 xff0c 最核心的求解3d 2d的变换中 xff1a span class hljs label 整个核心就是用这个cv s
  • 装双系统的一些记录

    小米电脑F2进入BIOS设置 xff0c F12选取启动项 启动U盘制作 ROS安装
  • ROS使用注意事项

    看到一篇总结 xff0c 感觉很有用 摘抄下来 转自 xff1a https www cnblogs com pk28 p 7625838 html
  • Python time模块 时间戳转换

    时间戳转换 时间戳获取 import time time time 时间戳转时间字符串 时间戳 gt 时间数组 gt 格式化时间字符串 时间字符串转时间戳 格式时间字符串 gt 时间数组 gt 时间数组 时间戳转换时间字符串 time st
  • 图漾深度摄像头基本使用方法

    搞到一款图漾的3d相机 xff08 型号为FM810 C xff09 有好久了 xff0c 一直也只是编译了sample代码跑起来看看样子 xff0c 并没有着手看SDK以及开发的事 近几日对照SDK以及其中的SimpleView Fetc
  • Xilinx FPGA的约束设计和时序分析总结 (转)

    在进行FPGA的设计时 xff0c 经常会需要在综合 实现的阶段添加约束 xff0c 以便能够控制综合 实现过程 xff0c 使设计满足我们需要的运行速度 引脚位置等要求 通常的做法是设计编写约束文件并导入到综合实现工具 xff0c 在进行
  • STM32学习笔记-串口

    所用的STM32主要有3个串口 xff0c 3个串口的物理位置如图中所示 串口的驱动编写流程 待续
  • 工业以太网EtherCat学习

    一 简单介绍 EtherCAT是由德国Beckhoff公司提出的实时以太网解决方案 xff0c 它是国际现场总线标准的组成部分 在现场总线级的高速I O控制和高速运动控制方面有突出的表现 EtherCAT使用标准的以太网卡作为主站 xff0
  • AVstream驱动学习

    Step 1 Learn about Windows architecture and drivers AVStream AVStream is a Microsoft provided multimedia class driver th
  • 制作一个舵机云台【内附资料下载链接】

    1 运动功能说明 舵机云台下方的舵机可以提供一个左右摆动的动作 xff0c 同时上方横置的关节模组可以提供一个上下摆动的动作 在这两部分的配合下 xff0c 云台的执行端端 xff08 即 xff1a 关节模组的U型支架 xff09 可以灵
  • UART控制器LIN功能模式(NUC029LAN阅读笔记)

    UART控制器LIN功能模式 xff08 NUC029LAN阅读笔记 xff09 LIN总线帧格式字节域格式 xff08 LIN标准 xff09 帧头 xff08 Header xff09 同步间隔域 xff08 Break Field x