关闭

Lin总线应用层代码

标签: Lin
800人阅读 评论(0) 收藏 举报
分类:

毕业设计做的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



0
1

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:17811次
    • 积分:688
    • 等级:
    • 排名:千里之外
    • 原创:50篇
    • 转载:23篇
    • 译文:0篇
    • 评论:1条
    文章分类
    最新评论