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

📄 uart.c

📁 AVR单片机基础上的以太网协议编程
💻 C
字号:
/**************************************************************************
**
**    文件: UART.c
**    描述: 该文件完成串口的初始化、与传感器串口的数据交互、通过串口中断为EPA网络提供信息分发数据            
**
**************************************************************************/

//include library files
#include <iom128v.h>
#include <macros.h>

//include user defined files
#include "Extern_Function.h"
#include "UART.h"

static uchar Cmd_Buf[350];//串口命令数据
static struct DPT_t_OBJECT *DPT_Buf=(struct DPT_t_OBJECT *)Cmd_Buf;

static uchar CMD_DATA_SIZE[DPT_CMD_NUMBER]={59,22,28,30,4,4,4,4,4,4,2,2,8,8,8,1,1,2,2,7,7,1,1,4,1,60,13,13};

/* sending  */
static uchar   UART_TxSize;
static uchar   UART_TxBuf[UART_TXBUFFER_SIZE];
static uchar   UART_TxPos;
 
//标志量
static uchar UART_WatchDogFlag;
static uchar UART_DPTInitFlag;
static uchar UART_RecvEndFlag; //串口接收结束标志
static uchar CoffFlag;         //for CMD161
static uchar resp;

/* receiving  */
static uchar   UART_RxBuf[UART_RXBUFFER_SIZE] ;

static uchar  UART_DNCmdWr=0xFF;      
static uchar  UART_DNCmdRd=0xFF;
static uchar  UART_DNCmdAux=1;
static uchar  cmdindex=0xFF;

/*DPT_CMD_NUMBER=28,point to the data address and length of every cmd*/
static UART_t_CmdData  UART_CmdData[DPT_CMD_NUMBER];

static uchar  UART_WatchDogTimer;
static uchar  UART_RespTimer;         /* wait the end of a new msg */
static uchar  UART_ReSendCount;

static int CMDTOINDEX[] = {0, 128, 138, 1, 11, 21, 23, 12, 22, 24, 14, 25, 34, 35, 36, 71, 72,  150, 151, 
                           133, 149, 173, 174, 165, 163, 161, 162, 79};//161-162只查找用,不留空间

//UART_Init();
void UART_ToReady( void ) //初始化相关的缓冲器、标志位
{
  UART_DPTInitFlag = 0;
  UART_WatchDogTimer = 0x00;
  UART_WatchDogFlag = FALSE;
  CoffFlag = 0;

  UART_DNCmdWr = 0xFF;
  UART_DNCmdRd = 0xFF;
  UART_ReSendCount = 0x00;
  UART_RespTimer = 0xFF; 
}

void UART1_UartInitiate( void )//串口1初始化
{
    UCSR1B=0x00;
	UBRR1L = UBRR_L;           //fosc=8M,BAUD=9.6kbps  
	UBRR1H = UBRR_H; 
	
	UCSR1B=(1<<RXEN1)|(1<<TXEN1)|(1<<RXCIE1)|(1<<TXCIE1);//使能发送和接收,使能发送和接收中断
	UCSR1C=0x36;                                         //异步,奇检验,8位数据,1位停止位
} 

void UART_Init(void)
{
  uchar i;
  uchar size;
  uchar * pb;

  UART1_UartInitiate(); 
  pb = Cmd_Buf;
  for (i=0; i <DPT_CMD_NUMBER; i++) //DPT_CMD_NUMBER=28
  {
    size = CMD_DATA_SIZE[i];
    UART_CmdData[i].addr = pb;
    UART_CmdData[i].size = size;
    pb += size;
  }
  UART_ToReady();
}

//发送与接收中断服务程序
uchar GetChar(void)
{
   while(!(UCSR1A&(1<<RXC1)));
   return UDR1;
}

#pragma interrupt_handler uart1_rx_isr:iv_USART1_RXC
void uart1_rx_isr(void) //接收中断服务程序
{
    uchar UART_RxPos;
	
    UART_RxBuf[0] = UDR1;
	
	if(UART_RxBuf[0]==0xFF)
	{
	   for(UART_RxPos=0;UART_RxPos<3;UART_RxPos++)
	   {
	       UART_RxBuf[1+UART_RxPos]=GetChar();
		   if(UART_RxBuf[1+UART_RxPos]!=0xFF)
		       break;
	   }
	   if(UART_RxPos==3)
	   {
	   	  UART_RxBuf[4]=GetChar();
		  if((UART_RxBuf[4]==0x55)||(UART_RxBuf[4]==0xAA))
		  {
	         UART_RxBuf[5]=GetChar();
	   	  	 UART_RxBuf[6]=GetChar();
	         if(UART_RxBuf[6]<70)
			 {
	   	        for(UART_RxPos=0;UART_RxPos<=UART_RxBuf[6];UART_RxPos++)//最后一位为校验和
	   	  	    {
	               UART_RxBuf[7+UART_RxPos]=GetChar();
	   	        }
			 }
			 if(UART_RxBuf[5]!=1)
			 {
	   	  	    UCSR1B&=~(1<<RXEN1);    //接收禁止
	   	  	    UCSR1B&=~(1<<RXCIE1);   //禁止接收中断
			 }
	   	  	 UART_RecvEndFlag=0x01;
			 Send_Distribute(UART_RxBuf+7,UART_RxBuf[6]);//见Application.c
	      }
	   }
	}
}

#pragma interrupt_handler uart1_tx_isr:iv_USART1_TXC
void uart1_tx_isr(void)      //发送中断服务程序
 {      
    UART_TxPos++;
    if (UART_TxPos < UART_TxSize)
       UDR1 = UART_TxBuf[UART_TxPos];
	else
	{
	   UART_TxSize = 0x00;
  	   UART_TxPos = 0;
	}
 }

//UART_Main();
uchar UART_CalCode(uchar *pd, uchar length) //由所有字节异或值组成
{
  uchar calcode = 0x00;
  uchar i;

  for (i=0; i<length; i++)
  {
    calcode ^= *pd++;
  }
  return calcode;
}

void UART_MsgCreat(uchar cmdid, uchar cmdtype, uchar resp1, uchar resp2)//构造命令帧与响应帧,并发送
{
  uchar i,isize;
  
  //index = Cmd2Index(cmdid);
  if(cmdindex != 0xFF)
  {
    if(cmdtype==UART_RESPONSE)   //响应  0,128,138,1
    {
     UART_TxBuf[0]=cmdtype; 
  	 UART_TxBuf[1]=cmdid;
  	 UART_TxBuf[2]=2;           //晢时字节计数
  	 UART_TxBuf[3]=resp1;
	 UART_TxBuf[4]=resp2;
	
	 if (cmdid == 1)           //确定响应数据和字节数
        isize = 2;
     else
     {
        for (i=0; i<UART_CmdData[cmdindex].size; i++)
        {
          UART_TxBuf[5+i] = *(UART_CmdData[cmdindex].addr + i);
        }
        isize = UART_TxBuf[2]= (2+UART_CmdData[cmdindex].size);
	 }
    }//end of response
  
    /*SENDING CMD- UART_REAUEST */
    else if(cmdtype==UART_REQUEST)
    {
	   UART_TxBuf[0]=cmdtype;
	 
	   if((cmdid == 128)||(cmdid == 138))
	       cmdid = (resp1==1)?(++cmdid):cmdid;
  	   UART_TxBuf[1]=cmdid;
	   
	   if(resp1==0) //read cmd
	   {			
	 	  if (cmdid == 161)
		  {
		  	 isize = 1;
		     UART_TxBuf[3]=UART_DNCmdAux++;
			 CoffFlag=1;
		  }
		  else
		     isize = 0;
	   }
       else         //write cmd
	   {
	       isize = UART_CmdData[cmdindex].size;
	   }
	   resp1=0;
	   UART_TxBuf[2]= isize;
    }//end of command
    UART_TxBuf[isize+3] = UART_CalCode((&UART_TxBuf[0]), isize+3);
    UART_TxSize = isize + 4;
	
    /* start sending */
    UART_TxPos  = 0;
    UDR1 = UART_TxBuf[UART_TxPos];   //UDR1 串口数据缓冲区
  }
}

uchar Cmd2Index(uint CMD)
{
 	uchar i;
	for (i = 0 ;i < sizeof(CMDTOINDEX)/sizeof(int) ;i++)
    	{
    	   if(CMD==CMDTOINDEX[i])
    	       return i;
        }
    return 0xff;
}

static uchar count=0;
void UART_Main(void)
{  
  uchar i,length,startid;
  uchar respcode1 = 0x00;
  uchar respcode2 = 0x00;
  uchar icalcode,cmd=0xff;

  if (UART_RecvEndFlag)//串口接收完毕
  {
    UART_WatchDogTimer = 0x00;
    UART_WatchDogFlag = FALSE;

    UART_RecvEndFlag = 0;
    
	startid = UART_RxBuf[4];
    cmd = UART_RxBuf[5];
    length = UART_RxBuf[6];
	icalcode = UART_RxBuf[length+7];
	   
	if((cmd == 129)||(cmd == 139)||(cmd == 162))
	    cmd-=1;
    cmdindex = Cmd2Index(cmd);// for data buffer
	if(cmdindex!=0xFF)
	{
		if(cmd == 0x01)
       	   UART_DPTInitFlag = 1;  //已经完成初始化过程

       	// request command from 430  //0,128,138,1
	   	if ((startid == UART_REQUEST)&&(UART_CmdData[cmdindex].size==length))
       	  {
              /* check message */
      	  	  if (icalcode == UART_CalCode(&UART_RxBuf[4], (length+3)))
      	  	  {
	           	 /*save data */
	          	 for (i=0; i<length; i++)
	          	 {
	                 *(UART_CmdData[cmdindex].addr+i) = UART_RxBuf[7+i];
	          	 }
			  	 count++; 
      	  	  }
      	  	  else            // check sum error
			  	 respcode2 |= 0x08;   
      		/* if no command from DN, later the response msg would be send */
          }//end of request
		  
	   	// response from 430 //读、写命令的响应
        else if ((startid== UART_RESPONSE)&&((UART_CmdData[cmdindex].size==length-2)||(cmd == 161)))
       	  {
		  	 respcode1 = UART_RxBuf[7];
      	  	 respcode2 = UART_RxBuf[8];
		  
       	  	 /* check message, save data*/
      	  	 if(((respcode1|respcode2)==0)&&(icalcode == UART_CalCode(&UART_RxBuf[4], (length+3))))
      	  	 {
        	 	if (cmd == 161) // for 161,162, nine coef 
        	 	{
				   if((UART_RxBuf[9]&3)==1)
				   {
				   	  respcode2=UART_RxBuf[9]-1;
				      for (i=0; i<4; i++)
	        	   	  {
	                    *(UART_CmdData[cmdindex].addr+respcode2+i) = UART_RxBuf[10+i];
						*(UART_CmdData[cmdindex].addr+12+respcode2+i) = UART_RxBuf[14+i];
	          	   	  }
				   }
				   respcode2=((UART_RxBuf[9]-1)<<2);
				   for (i=0; i<4; i++)
	        	   {
	                 *(UART_CmdData[cmdindex].addr+24+respcode2+i) = UART_RxBuf[18+i];
	          	   }
				   UART_DNCmdRd = (CoffFlag==1)?161:UART_DNCmdRd;
             	}//end of cmd161
                else // for general write-response */
        	 	{
	                for (i=0; i<(length-2); i++)   //updata
	           		{
	                   *(UART_CmdData[cmdindex].addr+i) = UART_RxBuf[9+i];
	           	 	}
        	    }
      	     }
      	  	 /* clear resp code */
      	  	 respcode1 = 0x00;
      	  	 respcode2 = 0x00;
       	  }//----------UART_RESPONSE
	   	else
       	  {
            respcode2 |= 0x80;   // communation error
       	  }
		  UCSR1B|=((1<<RXEN1)|(1<<RXCIE1));
	}//cmdindex!=0xFF
	
    /* send command */
	if(UART_DPTInitFlag == 1)
	{
       if(UART_DNCmdAux>9)
	   {
		  CoffFlag = 0;
		  UART_DNCmdRd=0xff;
		  UART_DNCmdAux=1;
	   }
	   if (UART_DNCmdWr != 0xFF)  // creat request message
       {  //借用resp1代表写命令
      	  UART_MsgCreat(UART_DNCmdWr, UART_REQUEST, 0x01, 0x00); 
      	  UART_DNCmdWr = 0xFF;
       }
       else if (UART_DNCmdRd != 0xFF)
       {
      	  UART_MsgCreat(UART_DNCmdRd, UART_REQUEST, 0x00, 0x00);
		  UART_DNCmdRd=0xFF;
       }
	}
	/* send response */
    if ((startid == UART_REQUEST)&&(cmd != 0x01)&&(count == 2)) //1号命令暂不响应
    {
       UART_MsgCreat(cmd, UART_RESPONSE, respcode1, respcode2);
	   count=0;
    }
  }//end of RecvEndFlag
}

//UART_CheckTimer();
void UART_CheckTimer(void) //刷新定时器
{
  /* after request, wait for response from 430 */
  if (UART_WatchDogTimer < UART_WATCHDOG_TIME)
  {
    UART_WatchDogTimer ++;
    if (UART_WatchDogTimer>=UART_WATCHDOG_TIME)
    {
      UART_WatchDogFlag = TRUE;
    }
  }
  
  /* wait new msg */
  if (UART_RespTimer)
  {
    UART_RespTimer --;
  }
  
}

/******************* End Of File **********************/

⌨️ 快捷键说明

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