⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 基于51单片机的LIN主节点的设计
💻 C
字号:
#include"reg52.h"
#include "display.h"
#include"lin_send.h"
#include "lin_send.c"

/* Private typedef -----------------------------------------------------------*/
typedef enum   //LIN主节点状态	   
{
  Idle,	 //初始态  
  SendBreak,	 //发送同步间隔态   
  VerifBreak, //等待同步间隔发送完没有	   
  SendSynch,	//发送同步场态	 
  VerifSynch,	 //等待同步场发送完没有	   
  SendPID,	  //发送ID场态	 
  SendData,	//发送数据态   
} LIN_MASTER_state;

typedef enum   //LIN主节点接收状态	   
{
  Init,	//初始态  
   WaitDate,// 等待数据态   
  Date_display	//接收数据显示	 
} LIN_SLAVE_state;		

#define uchar unsigned char
#define uint unsigned int

char idata lindata[3][8]={{0x5A,0x3B,0x29,0x23,0x1E,0x3A,0x4B,0x2F},
                          {0x12,0x23,0x34,0x45,0x56,0x1A,0x4E,0x3F},
						  {0x38,0x40,0x19,0x53,0x32,0x5C,0x28,0x1E}};//要发送的三组数据	  		

l_u8 i = 0; /* Data Number that MASTER send */
l_u8 j = 0; /* Data Number that SLAVE receive */
l_u8 n = 0;
//u8 PID = 0x1E; /* PID of this frame */
l_u8 SPID = 0xF0; //发送数据ID场    
l_u8 RPID=0x32;	//接收数据ID场	 
l_u8 data_PID;
l_u8 bus_state=0;
// l_u8 temp;
l_u8 receive_data[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};



LIN_MASTER_state LIN_MASTER = Idle;	 //LIN总线发送报文状态初始化	 
LIN_SLAVE_state  LIN_SLAVE = Init; 	//LIN总线接收初始化	  
 
 l_u8 count=0;
 l_u8 bus_cnt=0;    
  
  /***********************************************************
   * 															   ***
   *本程序主要实现的功能是循环显示发送3组数据并交替发送2个报文 ***
   *															   ***
   ***********************************************************
  */

main()
{
  
 l_sys_init(); //51单片机初系统始化 ,包括波特率设置 (即定时计数器初始化)串口输入输出设置 TJA1020模式设置		  
  while (1)//while语句用来循环发送报文
  {						    
      switch (LIN_MASTER)//用switch语句来发送一个报文
    {                  	//LIN总线的一个报文由同步间隔场 同步场 ID场 数据场 奇偶校验位 组成
      case Idle:
		delay(0xFFFF);	//延时一段时间开始发报文    
        LIN_MASTER = SendBreak;					    
        break;

      case SendBreak:
        l_send_break();  //发送同步间隔场   
        LIN_MASTER = VerifBreak;
        break;

      case VerifBreak:
        if (BreakReceived) //发送同步间隔场完后进入 发送同步场状态		 
        {
          BreakReceived = 0;
          LIN_MASTER = SendSynch;
        }
        break;

      case SendSynch:
        l_send_bytes(0x55);	 //发送同步场   
        LIN_MASTER = VerifSynch;
        break;

      case VerifSynch:
        if (USART_DataReceived)	   //同步场发送完后进入 发送ID场状态	  
        {
          USART_DataReceived = 0;
          LIN_MASTER = SendPID;//发送ID场,信息包括要发送的数据字节数和标识符,可以加ID_Table[]			 
        }
        break;
                      //本次实验有2个ID场,包括发送数据ID场和接收数据ID场	    
      case SendPID:
			if(bus_state==1) //bus_state==1 则发送SPID(发送数据ID场)
               {
				l_send_bytes(SPID);
				 //bus_state=0;				 
			   }		
			else if(bus_state==0) //bus_state==0 则发送RPID(接收数据ID场)		 
              {
				l_send_bytes(RPID);				
			//	bus_state=1;
			  }				  										
		LIN_MASTER = SendData;	 
        break;

  
      case SendData:
        if (USART_DataReceived)	//ID场发送完进入 发送数据状态	  
        {
          USART_DataReceived = 0;
		  if(bus_state==0)           	//只发送报文头,
		   {	 bus_state=1;	 	   //如果从机接收到这个报文头 就可以发送数据给主机 从而接收数据		    
              LIN_MASTER = Idle;  //发送完报文头后又重新跳到等待发送报文头状态 
            } 					
			 
	        else 	    
			{ 	
			   clear_LCD();   //清屏 			   
			   l_send_data(lindata[j],8);//发送8个字节的数据     
			    j++;  //循环发送3组数据	   即lindata[3][8]的数据	    
			   if(j==3)  j=0;
			    bus_state=0;			  
			   LIN_MASTER =Idle;//发送完8个字节数据后又重新跳到等待发送报文的状态
			  }
		}       
		break;							
    }

/******************接收数据***********************/
	switch (LIN_SLAVE)	//采用串口中断来接收从机发来的数据	    
    {
      case Init:
	  ES=1;//开串口中断	 
      LIN_SLAVE = WaitDate;
       break;

      case WaitDate:	   //等待接收数据   
        if (WaitReceived)
        {
          WaitReceived = 0;
         
         receive_data[n]=DataTemp; //将从机上接收到的数据存到receive_data[n]数组里  
		 n++;           //连续接收8个字节数据
		 if(n==8) 
		 {n=0;				 //接收完8个字节数据后 进入接收数据显示状态		  
		  LIN_SLAVE=Date_display;
		 }  		  
         else 	 LIN_SLAVE = WaitDate;	//重新等待下个数据	 
		}
		else    LIN_SLAVE= Init;	
	
		break;   
		
		case Date_display:
		  clear_LCD();		 
		  for(n=0;n<8;n++)   	  		  			 		  
		  {   clear_LCD();
			display_LCD_number(receive_data[n]);//显示接收到锝个字节的数据  	
          	display_LCD_string(" ");
          }
		   display_LCD_string("<R>");
		   delay(0x6FFF);  //延时显示
   		    
           LIN_SLAVE= Init;//显示完后重新跳到等待接收数据状态	   
           break;
  }
  } 
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -