毕业设计做的Lin总线,关键代码贴出来。
计算校验和
unsigned char LINCalcChecksum(unsigned char *data) { unsigned int sum = 0; unsigned char i; for(i = 0; i < 4; i++) { sum += data[i]; if(sum&0xFF00) sum = (sum&0x00FF) + 1; } sum ^= 0x00FF; return (unsigned char)sum; }
unsigned char LINCalcParity(unsigned char id) { unsigned char 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; }
结构体
//FrameProgress代表从机接收帧的进度, // FrameProgress=0x00代表进度0, // FrameProgress=0x01代表进度1, // FrameProgress=0x02代表进度2, // FrameProgress=0x03代表进度3。 //每当有中断(sci)发生,先检测进度根据进度执行相应的代码段 //进度0:接收0x55,接收成功则设置进度为进度1 //进度1:接收ID ,接收成功则设置进度为进度2 //进度2:接收数据字节,接收成功设置为进度3 //进度3:设置执行标志位(ReceiveLinDataCompleted)为'执行'(True),主程序检测到执行标志位为'执行'则执行检查校验和解析数据字节执行相应的操作 unsigned char LinFrameByte=0x00; unsigned char FrameProgress=0x00; //LinDataProgress是接收Lin帧中的数据字节的进度 unsigned char LinDataProgress =0x00; Bool ReceiveLinDataCompleted = 0; struct LinMessageStruct { unsigned char LinData[5]; }; struct LinMessageStruct LinMessage;
void SCI发送(unsigned char data) { while(!SCI0SR1_TDRE); SCI0DRL = data; }
串口接收
unsigned char SCI接收(void) { while(!SCI0SR1_RDRF); return(SCI0DRL); }
初始化锁相环
void INIT_锁相环(void) { CLKSEL &= 0x7f; PLLCTL &= 0x8F; CRGINT &= 0xDF; #if(BUS_CLOCK == 40000000) SYNR = 0x44; #elif(BUS_CLOCK == 32000000) SYNR = 0x43; #elif(BUS_CLOCK == 24000000) SYNR = 0x42; #endif REFDV = 0x81; PLLCTL =PLLCTL|0x70; asm NOP; asm NOP; while(!(CRGFLG&0x08)); CLKSEL |= 0x80; }
Lin总线应用层代码
Lin总线应用层代码
Lin总线应用层代码
void main(void) { DisableInterrupts; INIT_SCI();//设置为输出 INIT_PLL();//初始化锁相环 DDRB=0xff;//使能PORTB DDRA=0XFF;//使能PORTA EnableInterrupts; for(;;) { //检查是否接收帧完成 if(ReceiveLinDataCompleted == 1) { //检查校验和 if(LinMessage.LinData[4]==LINCalcChecksum(LinMessage.LinData)) { if(LinMessage.LinData[0]==0x11) { PORTA_PA0=0;//灯亮 } } ReceiveLinDataCompleted =0; } } }
串口中断接收函数
#pragma CODE_SEG __NEAR_SEG NON_BANKED interrupt void Receivedata(void) { LinFrameByte = SCI_receive(); if(FrameProgress==0x00) { if(LinFrameByte !=0x55) { return; } if(LinFrameByte ==0x55) { FrameProgress=0x01; return; } } if(FrameProgress==0x01) { //暂时不用奇偶校验 if(ID==LinFrameByte) { FrameProgress=0x02; } return; } if(FrameProgress==0x02) { //接收数据 if(LinDataProgress==0x00) { LinMessage.LinData[0]=LinFrameByte; LinDataProgress=0x01; return; } if(LinDataProgress==0x01) { LinMessage.LinData[1]=LinFrameByte; LinDataProgress=0x02; return; } if(LinDataProgress==0x02) { LinMessage.LinData[2]=LinFrameByte; LinDataProgress=0x03; return; } if(LinDataProgress==0x03) { LinMessage.LinData[3]=LinFrameByte; LinDataProgress=0x04; return; } if(LinDataProgress==0x04) { LinMessage.LinData[4]=LinFrameByte; LinDataProgress=0x00; } //数据接收完成 ReceiveLinDataCompleted = 1; FrameProgress=0x00; return; } } #pragma CODE_SEG DEFAULT