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

📄 uart.c

📁 单片机8051 MTV512,用了串口缓冲区收发合一的方式,中断
💻 C
字号:
//PC reads MCU instruction structure: (by interrupt, ACII code display)
//format:  start byte | type | device id | device add | length n | chksum | stop byte 
//value?     'n' 'y'    |   'r'   |  0x01      |        x       |      x      |      x     |0x13 0x10 
//byte?         2       |   1    |     1        |       1       |      1      |      1     |       2 


#include <reg51.h> 
//#include <config.h> 

//declaration
sbit P1_0 = P1 ^ 0;
sbit P1_1 = P1 ^ 1;
sbit P1_2 = P1 ^ 2;
sbit P1_3 = P1 ^ 3;
sbit P1_4 = P1 ^ 4;
sbit P1_5 = P1 ^ 5;
sbit P1_6 = P1 ^ 6;
sbit P1_7 = P1 ^ 7;

#define F_ST1 	0x6e       //start byte            n 
#define F_ST2 	0x79       //start byte         y 
#define F_R 		0x72       //read            		r 
#define F_W 		0x77       //write               w 
#define F_D 		0x64       //data           		d 
#define F_B 		0x62       //respond   	   b 
#define F_C 		0x63       //resend instruction	c 
#define F_Q 		0x71       //quit 	  	   q 
#define F_ADDR 	0x31      	//device address    	0-9 
#define F_END 	0x7a       //end byte          z 
#define F_SPACE 	0x30     	//space               	0 
#define F_ERR1 	0x31       //error1,flagerr    1 
#define F_ERR2 	0x32       //error2                	2 

//define value 
#define S_MAXBUF 			16           //send/receive buffer size
#define FIELD_MAXBUF 		48    	//minimum buffer, bigger than 48 bits?coz protocol based on                                            //20 bytes per transmission
#define communicationing 	P1_7	//communication mode 
#define ERRFRAME_MAX 		5        	//continuous NOFRAME_CNT frame error    
#define ERR_NOCNTMAX_RESEND   \
              if(++errframe_cnt<=ERRFRAME_MAX)  resend_frame();  else errframe_cnt=communicationing=0; 
              //if over ERRFRAME_MAX, then stop communication ERR_NOCNTMAX_RESEND 

//public 
unsigned char databuf[FIELD_MAXBUF],errframe_cnt; 

//function prototype
//void send(unsigned char ch);
//unsigned char receive(void);
//unsigned char CharToHex(unsigned char bChar);
//unsigned char HexToChar(unsigned char bHex);
//void com_init(unsigned int baud_rate);

//FUNCTIONS
///////////////////////////////////////////////////////////////////// 
//function name?send() 
//function?send one ASCII code to serial port  
//input?ch-to be sent ASCII code
///////////////////////////////////////////////////////////////////// 
void send(unsigned char ch) 
{ SBUF=ch; while(TI==0);TI=0; } 

///////////////////////////////////////////////////////////////////// 
//function name?receive() 
//function?receive one byte from serial  
//return?one ASCII code
///////////////////////////////////////////////////////////////////// 
unsigned char receive(void) 
{while(RI==0);RI=0;return SBUF;} 

///////////////////////////////////////////////////////////////////// 
//function?CharToHex() 
//function?convert ASCII code to 16 bits 
//input?ASCII code
//return?16bits
///////////////////////////////////////////////////////////////////// 
unsigned char CharToHex(unsigned char bChar)
{ 
    if((bChar>=0x30)&&(bChar<=0x39)) //0x30='0'; 0x39='9'
        bChar -= 0x30; 
    else if((bChar>=0x41)&&(bChar<=0x46))//capital letter  0x41='A'; 0x46='F'
        bChar -= 0x37; 
    else if((bChar>=0x61)&&(bChar<=0x66))//small letter   0x61='a'; 0x66='f'
        bChar -= 0x57; 
    else 
        bChar = 0xff; 

    return bChar; 
} 

///////////////////////////////////////////////////////////////////// 
//Function name?HexToChar() 
//Function?convert 16 bits to ASCII code 
//Input ?16 bits 
//Return?ASCII code 
///////////////////////////////////////////////////////////////////// 
unsigned char HexToChar(unsigned char bHex)
{ 
    if((bHex>=0)&&(bHex<=9)) 
        bHex += 0x30; 
    else if((bHex>=10)&&(bHex<=15))  //capital letter
        bHex += 0x37; 
    else 
        bHex = 0xff; 
	
    return bHex; 
} 

///////////////////////////////////////////////////////////////////// 
//Function name?com_int() 
//Function?initialized serial 
//Forma6t? [baud_rate],n,8,1 
//Input?baud_rate  
///////////////////////////////////////////////////////////////////// 
void com_init(unsigned int baud_rate)
{ 
    EA=1;ES=1;//ET1=1;   
    SCON = 0x50;    /* 0x52;//SCON */ 
    TMOD = 0x20;    /*0x20;// TMOD */ 
    TCON = 0x60;    /*0x60;// TCON */ 
    PCON=PCON&0x7f; 

    switch(baud_rate) 		//baud rate setting
    {   
        case 1200: 
            TL1=0xe8;TH1=0Xe8;break;//1200 
        case 2400: 
            TL1=0xf4;TH1=0Xf4;break;//2400 
        case 4800: 
            TL1=0xfa;TH1=0Xfa;break;//4800 
        case 9600: 
            TL1=0xfd;TH1=0Xfd;break;//9600 
        case 19200: 
            PCON=PCON|0x80;TL1=0xfd;TH1=0Xfd;break;//19200 
        case 38400: 
            PCON=PCON|0x80;TL1=0xfe;TH1=0Xfe;break;//38400 
        default: 
             TL1=0xfd;TH1=0Xfd;break;//9600 
    } 
} 

///////////////////////////////////////////////////////////////////// 
//Function name?resend_frame() 
//Funcion?resend frame 
//Note?Acknowledge PC to resend 
///////////////////////////////////////////////////////////////////// 
void resend_frame(void)
{ 
    	send(F_ST1);
	send(F_ST2);
	send(F_C);
 	send(F_SPACE);
 	send(F_SPACE);//send checksum
    	send(F_END); 
} 

///////////////////////////////////////////////////////////////////// 
//Function name?quit_frame() 
//Fucntion?send quit frame 
//Function note?acknowledge PC to quit communication 
///////////////////////////////////////////////////////////////////// 
void quit_frame(void)
{ 
    	send(F_ST1);
 	send(F_ST2);
 	send(F_Q);
 	send(F_ERR1);
 	send(F_ERR1);//Send checksum
    	send(F_END); 
} 

///////////////////////////////////////////////////////////////////// 
//Function name?com_int() 
//Function description?serial interrupt
///////////////////////////////////////////////////////////////////// 
void com_int()interrupt 4
{ 
  unsigned char i,csaddr,clen,csum,tempbuf[S_MAXBUF]; 
  csum=0; 
  if(receive()==F_ST1)
  {//frame guide 1
	if(receive()==F_ST2)
	{//frame guide 2
	communicationing=1;//set flag to  indicate start commication 
       switch(receive())
	{ 
	       case F_R://read instruction 'r '
	              if(receive()==F_ADDR)
			{
				P1_2=!P1_2;//correct address         
	                     csaddr=CharToHex(receive())<<4;
				csaddr+=CharToHex(receive()); 
                          	clen=CharToHex(receive())<<4;
					clen+=CharToHex(receive()); 
                          	csum=csaddr+clen; 
                          	i=CharToHex(receive())<<4;
					i+=CharToHex(receive()); 
                          	if(i==csum)	//checksum verification
           			{ 
                               	if(receive() ==F_END)		//end correct frame 
             				{   
             				//start sending data 
                         
               			csum=0;
               			send(F_ST1);
               			send(F_ST2);
               			send(F_D); 
                                 	send(HexToChar((clen&0xf0)>>4));
               			send(HexToChar(clen&0x0f));
               			csum+=clen; 
						
                                    for(i=0;i<clen;i++)
               			{ 
                                      	send(HexToChar((databuf[i+csaddr]&0xf0)>>4));
                				send(HexToChar(databuf[i+csaddr]&0x0f)); 
                                      	csum+=databuf[i+csaddr]; 
                                    } 

					//if(csum>127)?csum-=128; 
               			send(HexToChar((csum&0xf0)>>4));
               			send(HexToChar(csum&0x0f));
               			send(F_END); 
                             
                  			//end data sending 
                                 	P1_0=! P1_0; 
       				}

				else  
             				{
               			ERR_NOCNTMAX_RESEND 
               			break;
             				}//end wrong indicator 
                   		}
           		else 
           		{
             			ERR_NOCNTMAX_RESEND  
             			break;
           		}//wrong checksum
              }//wrong address 
            	break; 
					 
          	case F_W://write instruction from PC, w 
              	if(receive()==F_ADDR)
         		{//correct address
                          	csaddr=CharToHex(receive()) <<4;
           			csaddr+=CharToHex(receive()); 
                    		clen=CharToHex(receive()) <<4;
           			clen+=CharToHex(receive()); 
                          	csum=csaddr+clen; 

				for(i=0;i<clen;i++)
           			{ 
                             	tempbuf[i+csaddr]=CharToHex(receive())<<4;
             				tempbuf[i+csaddr]+=CharToHex(receive()); 
                               	csum+=tempbuf[i+csaddr]; 
                             } 
                          	i=CharToHex(receive()) <<4;
           			i+=CharToHex(receive()); 

				if(csum!=i) 
           			{
            	 			ERR_NOCNTMAX_RESEND
             				break;
           			}//checksum error
           			
                          	if(F_END!=receive()) 
           			{
             				ERR_NOCNTMAX_RESEND 
             				break;
           			}//end byte error
           			
                          	for(i=csaddr;i<clen+csaddr;i++)
             				databuf[i-csaddr]=tempbuf[i-csaddr];//save correct data 
            		} //PC acknowledge after success receiving data
         	//start send respond byte 
                     send(F_ST1);
         		send(F_ST2);
         		send(F_B);
         		send(F_SPACE);
         		send(F_SPACE);//send checksum
                     send(F_END);//acknowledge 
               	P1_1=!P1_1; 
                 	break; 
					
            	case F_Q://quit communication
                   	csaddr=receive();
       		csum+=csaddr;//csaddr as quit register 
                   	if(csaddr!=F_ERR1 && csaddr!=F_ERR2) 
       		{
         			ERR_NOCNTMAX_RESEND
         			break;
       		} 
					
                   	if(csum!=receive()) 
       		{
         			ERR_NOCNTMAX_RESEND 
         			break;
       		} 
                   	if(F_END!=receive()) 
      			{
         			ERR_NOCNTMAX_RESEND 
         			break;
       		} 
                   communicationing=0;//error and quit communication 
                   break; 
				   
              default: 
                   resend_frame();//request resend
	} 
    }    
  }
  if(!communicationing)
    quit_frame();//send quit byte?tell PC quit communication 
} 


void main(void)
{ 
  	unsigned char i; 
  	for (i=0;i<FIELD_MAXBUF;i++)
    		databuf[i]=i+0x30; 

  	com_init(38400); 

	while(1)
	{ 
   	/* may add other instruction */ 
  	} 
}

 
 
                      



⌨️ 快捷键说明

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