历史上的今天
返回首页

历史上的今天

今天是:2024年12月07日(星期六)

2020年12月07日 | STM32 —— LIN

2020-12-07 来源:elecfans

/*

  LIN 总线的主要特性有

    单主机 多从机概念

    基于普通 UART/SCI 接口的低成本硬件实现 低成本软件或作为纯状态机

    从机节点不需要石英或陶瓷谐振器可以实现自同步

    保证信号传输的延迟时间

    低成本的单线设备

    速度高达 20kbit/s


  总线的通讯由单个主机控制 每个报文帧都用一个分隔信号起始 ,一个同步场和一个标识符场 .


  这些都由主机任务发送 从机任务则是发回数据场和校验场


       报文路由 报文的内容由识别符命名 识别符不指出报文的目的地 但解释数据的含义 最大的

  标识符数量是 64 其中 4 个保留用于专用的通讯 譬如软件升级或诊断


  多播 由于引入了报文滤波的概念 任何数目的节点都可以同时接收报文 并同时对此报文做出反应


  位速率

    最大的波特率是 20kbit/s 它是由单线传输媒体的 EMI 限制决定 最小的波特率是 1kbit/s 可以避免

  和实际设备的超时周期冲突,为使用低成本的 LIN 器件 建议使用下面的位速率


    建议的位速率

    低速      中速      高速

    2400 bit/s  9600 bit/s  19200 bit/s


  单主机 无仲裁

    只有包含主机任务的控制器节点可以传输报文头,一个从机任务对这个报文头作出响应,由于没有仲

  裁过程,如果多于一个从机回应,则将产生错误.这种情况下的错误界定可由用户按照应用要求指定.


  安全性

    错误检测

      监控 发送器比较总线 应当 的值和 现在 的值

      数据场的校验和以 256 为模并取反 将 MSB 的进位加到 LSB 上

      标识符场的双重奇偶校验保护


  连接

    LIN 网络节点的最大数量不仅由标识符的数量限制 见上面的信息路由 也由总线的物理特性限制

    建议 LIN 网络的节点数量不应超过 16 否则 节点增加将减少网络阻抗 会导致环境条件变差

    禁止无错误的通讯 每一个增加的节点都可以减少约 3 的网络阻抗 30k || 1k

    网络中总的 电 线 通讯导线 长度应少于或等于 40m

    主机节点的总线端电阻典型值是 1k 从机节点是 30k


  总线值

    总线有两个互补的逻辑值 显性 或 隐性 相应的位值和电压值

      表 2.2 逻辑和物理总线值

    逻辑值    位值  总线电压

    显性      0     地

    隐性      1     电池


  应答

      正确接收报文后的应答过程在 LIN 协议中没有定义 主机控制单元检查由主机任务初始化的报文

    和由它自己的从机任务接收的报文的一致性 如果不一致 例如 丢失从机响应 校验和不正确等等 主

    机任务可以改变报文的进度表

    如果从机检测到不一致 从机控制器将保存这个信息并将它用诊断信息的形式向主机控制单元请求

    诊断信息可按普通报文帧的形式进行发送


    每个报文帧都由一个同步间隔 SYNCH BREAK 起始 接着是同步场 SYNCH FIRLD 这个同

  步场在几倍的位定时长度中包含了 5 个下降沿 即 隐性 到 显性 的转换


  一个报文帧 是由一个主机节点发送的报文头和一个主机或从机节点发送的响应组成

  报文帧的报文头包括一个同步间隔场 SYNCH BREAK FIELD,一个同步场 SYNCH FIELD,和一个标识符场


    报文帧的响应 RESPONSE 则由 3 个到 9 个字节场组成 2 或 4 或 8 字节的数据场 DATA FIELD

  和一个校验和场 CHECKSUM FIELD


    字节场的格式 通常的 SCI 或 UART 串行数据格式 8N1 编码 每个字节场

  的长度是 10 个位定时 BIT TIME 起始位 START BIT 是一个 显性 位 它标志着字节场的开始

  接着是 8 个数据位 首先发送最低位 停止位 STOP BIT 是一个 隐性 位 它标志着字节场的结束


  报文头场 HEADER fields

  同步间隔 SYNCHRONISATION BREAK

    为了能清楚识别报文帧的开始 报文帧的第一个场是一个同步间隔 SYNCH BREAK 同步间隔场

  SYNCH BREAK FIELD 是由主机任务发送.它使所有的从机任务与总线时钟信号同步


    同步间隔场有两个不同的部分,第一个部分是由一个持续 T SYNBRK 或更长时间 即最小是

  T SYNBRK 不需要很严格 的显性总线电平 接着的第二部分是最少持续 T SYNDEL 时间的隐性电平

  作为同步界定符 第二个场允许用来检测下一个同步场 SYNCH FIELD 的起始位最大的间隔和界定

  符时间没有精确的定义 但必须符合整个报文头 T HEADER_MAX 的总体时间预算


  同步场 SYNCH FIELD

  同步场 SYNCH FIELD 包含了时钟的同步信息 同步场 SYNCH FIELD 的格式是 0x55 表

  现在 8 个位定时中有 5 个下降沿 即 隐性 跳变到 显性 的边沿 见图 3.4


  标识符场 IDENTIFIER FIELD

  标识符场 ID-FIELD 定义了报文的内容和长度 其中 内容是由 6 个标识符 IDENTIFIER 位和

  两个 ID 奇偶校验位 ID PARITY bit 表示 见图 3.5 标识符位的第 4 和第 5 位 ID4 和 ID5 定义了

  报文的数据场数量 N DATA 见表 3.2 这将把 64 个标识符分成 4 个小组 每组 16 个标识符 这些标识

  符分别有 2 4 和 8 个数据场


  响应场 RESPONSE field

  数据场 DATA FIELD 和  校验和场 CHECKSUM FIELD

  数据场通过报文帧传输 由多个 8 位数据的字节场组成 传输由 LSB 开始


  校验和场 CHECKSUM FIELD

  校验和场是数据场所有字节的和的反码和按 带进位加 ADDC 方式计算 每个进位

  都被加到本次结果的最低位 LSB 这就保证了数据字节的可靠性,所有数据字节的和的补码与校验和字节之加的和必须是 0xFF

*/



#include "lin.h"

#include "lin_queue.h"

#include "lin_handle.h"

#include "target.h"

 

#define LIN_CHANNEL         UART4

#define RCC_LIN_APB         RCC_APB1PeriphClockCmd

#define RCC_LIN_CLK         RCC_APB1Periph_UART4

#define LIN_BOAURATE        19200

#define LIN_IRQ             UART4_IRQn

#define LIN_INT_FUNC        UART4_IRQHandler

 

#define LIN_PORT            GPIOC

#define LIN_TX_PIN          GPIO_Pin_10

#define LIN_RX_PIN          GPIO_Pin_11

#define LIN_TX_CONFIG()     GPIOConfig(LIN_PORT, LIN_TX_PIN, GPIO_Mode_AF_PP)

#define LIN_RX_CONFIG()     GPIOConfig(LIN_PORT, LIN_RX_PIN, GPIO_Mode_IN_FLOATING)

 

#define LIN_CS_PORT         GPIOC

#define LIN_CS_PIN          GPIO_Pin_12

#define LIN_CS_CONFIG()     GPIOConfig(LIN_CS_PORT, LIN_CS_PIN, GPIO_Mode_Out_PP)

#define LIN_CS_ENABLE()     GPIO_SetBits(LIN_CS_PORT, LIN_CS_PIN)

 

static void lin_gpio_init(void)

{

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

 

  LIN_TX_CONFIG();

  LIN_RX_CONFIG();

  LIN_CS_CONFIG();

  LIN_CS_ENABLE();

}

 

static void lin_nvic_init(void)

{

  NVIC_InitTypeDef NVIC_InitStructure;

 

  NVIC_InitStructure.NVIC_IRQChannel = LIN_IRQ;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

}

 

static void lin_uart_init(void)

{

  USART_InitTypeDef USART_InitStructure;

 

  RCC_LIN_APB(RCC_LIN_CLK, ENABLE);

 

  USART_InitStructure.USART_BaudRate = LIN_BOAURATE;

  USART_InitStructure.USART_WordLength = USART_WordLength_8b;

  USART_InitStructure.USART_StopBits = USART_StopBits_1;

  USART_InitStructure.USART_Parity = USART_Parity_No ;

  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

  USART_Init(LIN_CHANNEL, &USART_InitStructure);

 

  USART_LINBreakDetectLengthConfig(LIN_CHANNEL, USART_LINBreakDetectLength_11b);

  USART_LINCmd(LIN_CHANNEL, ENABLE);

  USART_Cmd(LIN_CHANNEL, ENABLE);

 

  USART_ITConfig(LIN_CHANNEL, USART_IT_RXNE, ENABLE);

  USART_ITConfig(LIN_CHANNEL, USART_IT_TXE, DISABLE);

  USART_ITConfig(LIN_CHANNEL, USART_IT_LBD, ENABLE);

}

 

void LINInit(void)

{

  lin_gpio_init();

  lin_nvic_init();

  lin_uart_init();

}

 

void LINSendChar(uint8_t ch)

{

  USART_SendData(LIN_CHANNEL, ch);

  while(!USART_GetFlagStatus(LIN_CHANNEL, USART_FLAG_TXE));

}

 

void LINSendBreak(void)

{

  USART_SendBreak(LIN_CHANNEL);

}

 

#define BIT(A,B)       ((A >> B) & 0x01)

 

uint8_t LINCalID(uint8_t id)

{

  uint8_t parity, p0, p1;

 

  parity = id;

  p0 = (BIT(parity, 0) ^ BIT(parity, 1) ^ BIT(parity, 2) ^ BIT(parity, 4)) << 6;

  p1 = (!(BIT(parity, 1) ^ BIT(parity, 3) ^ BIT(parity, 4) ^ BIT(parity, 5))) << 7;

 

  parity |= (p0 | p1);

 

  return parity;

}

 

uint8_t LINCalChecksum(uint8_t id, uint8_t *data)

{

  uint32_t sum = id;

  uint8_t i;

 

  for(i = 0; i < 8; i++)

  {

    sum += data[i];

    if(sum & 0xFF00)

    {

      sum = (sum & 0x00FF) + 1;

    }

  }

 

  sum ^= 0x00FF;

 

  return (uint8_t)sum;

}

 

//========================================================================================================

void LIN_INT_FUNC(void)

{

  uint8_t ret;

 

  if(USART_GetITStatus(LIN_CHANNEL, USART_IT_RXNE))

  {

    USART_ClearITPendingBit(LIN_CHANNEL, USART_IT_RXNE);

    ret = USART_ReceiveData(LIN_CHANNEL);

    //LINQueuePush(&lin_recv, ret);

  }

 

  if(USART_GetITStatus(LIN_CHANNEL, USART_IT_LBD))

  {

    USART_ClearITPendingBit(LIN_CHANNEL, USART_IT_LBD); // 检测到同步间隔场

    //LinStatusSet(SYNCH);

  }

 

  if(USART_GetFlagStatus(LIN_CHANNEL, USART_FLAG_ORE) == SET) // 溢出

  {

    USART_ClearFlag(LIN_CHANNEL, USART_FLAG_ORE);

    USART_ReceiveData(LIN_CHANNEL);

  }

}


推荐阅读

史海拾趣

E-tec Interconnect Ltd公司的发展小趣事

在电子行业快速发展的背景下,E-tec始终保持对技术创新的关注。他们投入大量资金进行研发,不断推出新产品和新技术。例如,他们成功开发了一种新型的微型连接器,该连接器具有体积小、传输速度快、抗干扰能力强等优点,受到了市场的热烈欢迎。此外,E-tec还注重产品升级和换代,确保产品始终保持在行业前列。

Alpha Wire公司的发展小趣事

为了满足全球客户的需求,E-tec开始在全球范围内进行布局。他们在亚洲、欧洲和北美等地设立了生产基地和研发中心,实现了全球范围内的生产和销售。同时,E-tec还注重供应链的整合和优化,与多家原材料供应商建立了长期稳定的合作关系,确保原材料的稳定供应和成本控制。

Allen Avionics Inc公司的发展小趣事

随着技术的不断成熟和产品质量的不断提升,E-tec开始积极拓展市场。他们与多家国际知名的电子设备制造商建立了合作关系,产品逐渐进入全球供应链。为了进一步提升产品质量和竞争力,E-tec通过了ISO 9001质量管理体系认证,以及多项行业内的品质认证,如UL、CE等。这些认证不仅提升了公司的品牌形象,也增强了客户对公司的信任。

DMEL Inc公司的发展小趣事

为了提升产品质量和用户体验,DMEL Inc不断加大对生产过程的管控力度。公司引进了先进的生产设备和管理系统,建立了严格的质量检测体系。同时,DMEL Inc还加强了与供应商的合作,确保原材料的质量和供应的稳定性。这些措施的实施,使得DMEL Inc的产品质量得到了显著提升,赢得了消费者的信赖和好评。

德尔创(Dersonic)公司的发展小趣事

德尔创(Dersonic)公司成立于XXXX年,由一群电子工程领域的专家共同创立。成立之初,公司面临着资金紧张、市场竞争激烈等挑战。然而,他们凭借对电子技术的深刻理解和对市场的敏锐洞察,决定专注于研发和生产高品质的电子元器件。通过不断的研发和创新,德尔创成功推出了其首款具有竞争力的产品,并在市场上获得了初步认可。

FORYARD公司的发展小趣事

随着业务的不断扩展,FORYARD意识到全球化布局的重要性。1995年,公司决定在中国设立研发中心和生产基地,以利用当地丰富的人才资源和成本优势。这一战略决策极大地提升了FORYARD的产能和研发效率,同时也使其能够更好地服务全球客户。此后,FORYARD还陆续在欧洲、亚洲等地建立了多个分支机构,形成了覆盖全球的研发、生产和销售网络。通过全球化布局,FORYARD不仅增强了自身的市场竞争力,还促进了全球电子产业的交流与合作。

问答坊 | AI 解惑

快乐知识:CPU是如何制作成的?

如果按价格/重量来计算,CPU要比黄金还贵得多。几乎所有的人都知道CPU主要是以硅为为原料制成的。而硅是地球上多得无法计数的元素了(如果我高中的化学知识没有记错硅应该是排名第二的)是什么魔力使这种最不值钱的东西变成炙手可热的宝物的呢?是 ...…

查看全部问答>

LED条屏

T系列多功能LED条屏,内置龙珠科技自主知识产权操作系统,在完全脱离电脑的情况下可独立运行、更改。该系列产品具有技术领先、功能强大、操作便捷、显示灵活、信息量大、寿命长、外壳独家设计、开模精巧大方等特点。 市场独有即插即用PS2电脑键盘 ...…

查看全部问答>

我打算在龙芯cpu里面嵌入独立显卡、4G内存、80G固态硬盘等,谁有兴趣!

本人打算在龙芯cpu里面嵌入独立显卡(gforce 9600G这个级别以上)、4G内存、80G固态硬盘等,把南桥、北桥也嵌在芯片里面,这样就能省去主板,只留出部分借口用于扩展必要的其他外设,比如光驱,网卡等。谁能帮我实现。 还有大家评评看这样的计算机 ...…

查看全部问答>

请教2440的IO模拟全串口实现串口功能

我想通过2440的GPH1来模拟DTR信号,GPH0利用其管脚的CTS功能,我们设备需要5根线的串口来实现与设备通信,请问你们用过吗?这个驱动在2440BSP的Serial中哪里来添加啊,请教各位?…

查看全部问答>

网络硬盘

请问使用什么的网络硬盘比较好呢?…

查看全部问答>

vs2005无法连接WINCE

vs2005无法连接WINCE,这里面好像缺少什么没加载,请问该怎么办,目标板是Mini2440…

查看全部问答>

关于PDA串口编程的问题

我是一个新手,希望大家帮帮我!!! 我用EVC编写了一个串口程序,但不知道为什么当PDA上的程序接到数之后并没有显示就退出了,这个问题已经困绕我很长时间了! 还有我用的是EVC 3.0编写的,为什么在EVC4.0上不能运行? 急~~~~~~~~~`…

查看全部问答>

一个串口转换器的疑惑

我需要由RS232接口转换成RS485接口,再转换回RS232接口。只查到有RS232转RS485串口转换器,却查不到RS232转RS485的串口转换器!是不是用两个RS232转RS485串口转换器,就可以解决啊?初来乍到,敬请指教!…

查看全部问答>

ModelSim 6.6a-SE安装流程及说明

ModelSim 6.6a-SE安装流程及说明 建议先看完后再装,不知道你们安装的时候会不会遇到问题。(没有问题的朋友和我说声,我看看是不是我电脑系统的问题,谢谢) 打开文件,双击modelsim-win32-6.6-se.exe文件,如图1,开始安装旅程 图1 ...…

查看全部问答>

流明学习笔记之十二用UIP点亮LED

这几天我一直没在流明方面冒泡哈,原因很多,工作忙,晚上有人找修电脑地,还有人找干活地,一直没倒出功夫来哈,就算倒出功夫来也是一头雾水,为什么UIP条目不少啊,你看看一行两行,差不多上千行了,但我这几天学习过来学习过去发现一个可以实现 ...…

查看全部问答>