1.硬件环境
基于芯旺KF8A100FNG
2.LIN协议
LIN报文帧如下:
3.软件设计
3.1 接收break自动唤醒
在休眠模式下,USARTx 的所有时钟都会停止,此时波特率发生器处于无效状态,无法
进行正确的字符接收。自动唤醒功能允许在 RX/DT 线上活动时唤醒控制器。只有 USART
工作在异步模式下时才可以使用该功能。
3.2 自动波特率检测
在自动波特率检测(Auto-Baud Rate Detect,ABRD)模式下,BRG 不为 RXx 输入提供
时钟信号,而是由 RXx 为 BRG 定时。波特率发生器用于为接收的 0X55(
“U”的 ASCII 码)
定时,0X55 是 LIN 总线的同步字符。此字符的特殊之处在于它具有包括停止位边沿在内的
5 个上升沿。
将 BRCTLx 寄存器的 ABRDENx 位置 1 将启动自动波特率校验序列(图 13.3)。当发生
ABRDx 序列时,USART 状态机保持在空闲状态。在接收线的第一个上升沿(起始位之后),
EUBRGLx 使用 BRG 计数器时钟递增计数,如图 13.3 所示。在第 8 位周期的末尾将在 RXx
引脚上出现第5个上升沿。此时,对正确的BRG周期的累计值被留在EUBRGHx和EUBRGLx
寄存器中,ABRDENx 位被自动清 0 而 RCIF 中断标志被置 1。要清除 RCIFx 中断,需要读
取 RXSDRx 中的值。RXSDRx 的内容应该被丢弃。校准不使用 EUBRGHx 寄存器的模式时,
用户可通过查询 EUBRGHx 寄存器中的 0X00 验证 EUBRGLx 寄存器是否未溢出。
3.3 PID校验
/*****************************************************
*函数名:test_new_pag
*输入参数:无。
*返回:0——校验失败,数据内容有错误。非0——返回的是接收的单字节指令。
*函数功能:校验全局数组Rev_buf中的数据内容。首先对第一个字节进行奇偶校验,再对第二个数据和第三个数据进行反码校验。
* 如果校验通过则返回指令内容,校验失败,返回0;
*****************************************************/
unsigned char test_new_pag()
{
unsigned char temp, sum=1;
temp= Receive_Buffer[0]&0x3F;//取值,准备校验PID
PID =temp;
bit0=PID;
bit1=PID>>1;
bit2=PID>>2;
bit3=PID>>3;
bit4=PID>>4;
bit5=PID>>5;
bit6=bit0^bit1;
bit6^=bit2;
bit6^=bit4;
bit6&=0x01;
bit6<<=6;
bit7=bit1^bit3;
bit7^=bit4;
bit7^=bit5;
bit7&=0x01;
if(bit7)
bit7=0;
else
bit7=0x80;
PID|=bit6;
PID|=bit7;
if(PID!=Rev_buf[0])
return 0;
temp= Rev_buf[1] +Rev_buf[2];
if(temp!=0xFF)
return 0;
return sum;
}
3.4 CHECKSUM
/**
* @brief LIN 极性校验
* @param id LIN ID
* @retval 校验的结果
*/
uint8 LIN_CalcParity(uint8 id)
{
uint8 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;
}
/**
* @brief LIN 帧校验
* @param id LIN ID
* @param data 校验的数据
* @param length 数据的长度
* @retval 校验的结果
*/
uint8 LIN_Checksum(uint8 id, uint8 *Ldata, uint8 length)//, LIN_Frame_Class lin_frameclass)
{
uint8 i;
uint32 check_sum = 0;
if(1)//lin_frameclass == LIN_ENHANCED)
{
if(id == 0x3c || id == 0x3d) //使用增强型校验
{
check_sum = 0;
}
else
{
check_sum = LIN_CalcParity(id);
}
}
for (i = 0; i < length; i++)
{
check_sum += *(Ldata++);
//++
if (check_sum > 0xFF) //进位
{
check_sum -= 0xFF;
}
}
return (uint8 )(~check_sum); //取反
}
3.5 数据接收
Receive_Buffer[Receive_Buffer_Cnt++] = RXSDR1;