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

📄 uart.c

📁 是嵌入式处理器
💻 C
字号:
#include <mc9s12e64.h>     /* derivative information */
#include <hidef.h>      /* common defines and macros */
#define NOP {__asm NOP; }

#define SIZE_IN_BUFFER  145                              //接收 缓冲区长度
#define FrameHeader     0xF2           //报文帧头 低维---协议 高维---帧头

extern const word vswr1   @0xC004; 
extern const word vswr2   @0xC006;
extern const word gate    @0xC008;


#pragma CONST_SEG  PPAGE MY_ROM

#pragma CONST_SEG DEFAULT
 // word *far data1=(word *far)0x3C8004;
 // word *far data2=(word *far)0x3C8006;
 // word *far data3=(word *far)0x3C8008;


byte RXData[SIZE_IN_BUFFER];           //数据缓冲区
typedef struct serialStruct
{//串口的各种属性
    unsigned char status;                          //当前状态
    unsigned char cmd;                             //命令字
    unsigned int  length;                          //报文字节长度
    unsigned char checkSum;                        //检验和
    unsigned char inAddr;                          //接收缓冲区的 存数偏置        serial[1] com -> host's buffer 
    unsigned char token;                           //0x00:初始化
                                      //接收标志范围:0x0f:接收缓冲区满
                                      //接收报文标志:0xf8:报文接收中
                                                   //0xf0:报文接收完整
                                                   //0xff:报文处理完
}Structserial;

Structserial  serial[3];              //同时可以接收到的数据队列深度为三


extern word ADC_Conver(byte channel);
void CommInt(void);     //串口初始化配置
void CommDeal(void); 
void TX_Result(word answer);
void TxByte(unsigned char TxValue);

extern void FlashWrite_RAM(byte *WriteData,word * address,byte page);

byte Cal_CRC(byte *ptr, word len);

extern void ShowVswr(void);//处理驻波比
extern void Write_IIC(byte address,byte data);

//串口通信初始化部分
void CommInt(void) {

  SCI2BD_SBR =156;     // 设置波特率为9600bps
  SCI2CR2_TE =1;     	 // 使能SCI2的发送功能
  SCI2CR2_RE =1;     	 // 使能SCI2的接收功能
  SCI2CR2_RIE=1;			 // 使能SCI2的接收中断功能
  SCI2CR1 =0x00;  
}


//发送子函数
void TxByte(byte TxData) {
  
  byte ReadTemp;
  ReadTemp=SCI2CR1; 
  SCI2DRL = TxData;   // 发送一个byte
  while(!SCI2SR1_TC) ;
}

//发送一串四位数
void TX_Result(word answer)
{
   byte i;
   byte target[4];
   target[0]=(byte)(answer/1000);
   target[1]=(byte)((answer%1000)/100);
   target[2]=(byte)((answer%100)/10) ;
   target[3]=(byte)(answer%10) ;
   for (i=0;i<4;i++)
   {
    TxByte(target[i]+'0');
   }
}


//接收中断函数
void interrupt SCI2Rec(void) {
	 unsigned char bTemp,ch;
	 static byte index;
	 if(SCI2SR1_RDRF) {
	  
	 ch= SCI2DRL; 
	 bTemp=SCI2SR1;

	 if (serial[index].token == 0x0F)  //在缓冲区不满的情况下,接收数据
   {  
    return;
   }
	  
   switch (serial[index].status )//解释报文-根据接收到的字节转移状态
   {
     case 0x00 :
          if (ch == FrameHeader)// 如果接收到第一个数据为正确的报头
          {
            serial[index].status = 0x01;
            serial[index].token  = 0xF8;//报文接收中
            if (serial[index].inAddr >= SIZE_IN_BUFFER)  //接收缓冲区 满
            {
	             index=0;
	             serial[index].status = 0x00;
	             serial[index].inAddr = 0x00;
             }
             RXData[serial[index].inAddr++] = ch;
           }
           else
	         {
	           serial[index].status = 0x00;
	         }
           break;
      case 0x01 ://接收 报文长度 1byte
           RXData[serial[index].inAddr++] = ch;
           serial[index].length = ch*256;	
	         serial[index].status = 0x02;	
	         if (serial[index].inAddr >= SIZE_IN_BUFFER)  //接收缓冲区 满
           {
	           index=0;
	           serial[index].status = 0x00;
	           serial[index].inAddr = 0x00;
           }    
           break;
      case 0x02 ://接收 报文长度 1byte
           RXData[serial[index].inAddr++] = ch;
           serial[index].length = serial[index].length+ch;	
           //此处可以加上长度判断代码
	         serial[index].status = 0x03;	
	         if (serial[index].inAddr >= SIZE_IN_BUFFER)  //接收缓冲区 满
           {
             index=0;
	           serial[index].status = 0x00;
	           serial[index].inAddr = 0x00;
           }
           break;
      case 0x03 ://接收 CMD 1byte
           RXData[serial[index].inAddr++] = ch;
	         serial[index].cmd = ch;
           serial[index].status = 0x04;
           if (serial[index].inAddr >= SIZE_IN_BUFFER)  //接收缓冲区 满
           {
	           index=0;
	           serial[index].status = 0x00;
	           serial[index].inAddr = 0x00;
           }
           break;
      case 0x04 ://接收 报文内容 Xbyte 根据前面接收到的长度
           RXData[serial[index].inAddr++] = ch;
        
           if (serial[index].inAddr >= SIZE_IN_BUFFER)  //接收缓冲区 满
           {
	           index=0;
	           serial[index].status = 0x00;
	           serial[index].inAddr = 0x00;
           }
        
           if ( (--serial[index].length) == 2 )	    //接收完成后退出
	         {
	           serial[index].status = 0x05;
            
             if(index==0)
             {
	             serial[index].length = serial[index].inAddr;
	             serial[index].inAddr = 0x00;
	           }
	           else 
	           {
	             serial[index].length = serial[index].inAddr-serial[index-1].length-serial[index-1].inAddr;
	             serial[index].inAddr =serial[index-1].length+serial[index-1].inAddr;//起始位置+长度
	           }
	         }
        	 break;
      case 0x05 ://接收 报文内容校验和 1byte
           serial[index].checkSum=Cal_CRC((RXData+serial[index].inAddr),serial[index].length); 
	         if ( ch == serial[index].checkSum )
	         {
	          //置报文接收完整标志
	            serial[index].token = 0xF0;//收到完整报文
	            serial[index].status = 0x00;
	            index++;
	            if(index==2) 
	               index=0;//接收队列满,重新指向头位置
	            if(index==0)
	               serial[index].inAddr=0;
	            else
	               serial[index].inAddr=serial[index-1].length+serial[index-1].inAddr;//设置一个初始地址指针
	         }
	         else//报文内容校验和出错
	         {
	            serial[index].status = 0x00;
	            if(index==0)
	               serial[index].inAddr = 0x00;
	            else 
	               serial[index].inAddr =serial[index-1].length+serial[index-1].inAddr;;
	         }				    
	         break;
      default :
	    //将串口状态重置为 0x00
	         serial[index].status = 0x00;
	         if(index==0)
	            serial[index].inAddr = 0x00;
        	 else 
	            serial[index].inAddr =serial[index-1].inAddr;
           break;
    }//end switch(_sserial[1].status)
	 }
}




// CRC8=X8+X5+X4+1 -----0x31
byte Cal_CRC(byte *ptr, word len)
{
   word i;
   byte crc=0;
   while(len--)
   {
     for(i=0x80; i!=0; i>>=1)
      {
        if((crc&0x80)!=0) {crc<<=1; crc^=0x31;}
        else crc<<=1;
        if((*ptr & i)!=0) crc^=0x31;
       }
     ptr++;
   }
   return(crc);
}


//处理通信部分
void CommDeal(void) 
{  

  word k,j;
  byte i;
  
 // PPAGE=0x3C ;
  for( i=0;i<3;i++)
   if (serial[i].token == 0xF0) //收到了完整报文
   {
     switch(serial[i].cmd) 
     {
       case 1 :TxByte('1');break;
       case 2 :TxByte('2');
               TxByte(':');
               k=ADC_Conver(13);
               j=ADC_Conver(12);
               TX_Result(k);
 			         TxByte(' ') ;
 			         TX_Result(j);
 			         TxByte(' ') ;break;
               
       case 3 :TxByte('3');break;
       case 4 :TxByte(':') ;
 			         TX_Result(vswr1);
 			         TxByte(' ') ;
 			         TX_Result(vswr2);
 			         TxByte(' ') ;
 			         TX_Result(gate);
 			         TxByte(':') ;
 			         
 			         
 			      //   TX_Result(vswr_1);
 			         TxByte(' ') ;
 			      //   TX_Result(vswr_2);
 			         TxByte(' ') ;
 			      //   TX_Result(gate_1);
 			         break;	
       case 5 :TxByte('5');break;	          
       case 6 :DisableInterrupts;
             //  FlashWrite_RAM((RXData+serial[i].inAddr),(word *)0x8000,0x3c);
               
               FlashWrite_RAM((RXData+serial[i].inAddr),(word *)0xC000,0x00);
               EnableInterrupts;
               break;
       default:break;
     }
    serial[i].token=0xFF; 
   }          
}


//CRC_16多项式为0x1021
word cal_crc(byte *ptr, byte len) {
byte i;
word crc=0;
while(len--!=0) {
for(i=0x80; i!=0; i/=2) {
if((crc&0x8000)!=0) {crc*=2; crc^=0x1021;} /* 余式CRC 乘以2 再求CRC */
else crc*=2;
if((*ptr&i)!=0) crc^=0x1021; /* 再加上本位的CRC */
}
ptr++;
}
return(crc);
}

⌨️ 快捷键说明

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