***********************************************************/ #include "reg52.h" #include "timer.h" #include "uart.h" #define _UART_C_ // 485协议 bit irc_flag; bit uartRcving,uartSending,uartSend_waiting; bit repeat,F_state;//等待状态反馈 unsigned char uartRcvCnt; // 接收计数 unsigned char uartSendCnt;//uartSendP; 发送计数 unsigned char uartRcvTimer; unsigned char uartSendTimer;//uart接收到数据/发送后的计时===4ms //============================================================= unsigned char sendBuff[6]; unsigned char rcvBuff[20]; unsigned char bytes; //接收字节数 unsigned char idata result[4]; //数据存储单元 unsigned char key_data; void Delaya(void) //4MS { unsigned char i; for(i=0;i<685;i++); } void Delayb(void) //0.84MS { unsigned char i; for(i=0;i<96;i++); } //********************************************************** void init_uart() { uartRcvCnt=0; uartSendCnt=0; uartRcving=0; SCON=0X50; // PCON=0X80; RCAP2H=0xFF; //对timer2初始化 // RCAP2L=0xD9; //6T+19200+12M,T2的初值 RCAP2L=0xB2; ////6T+9600+12M,T2的初值 T2CON=0x34; //定时器2开始运行 ES=1; F_485WR=0;//收 } /* void init_uart() { uartRcvCnt=0; uartSendCnt=0; uartRcving=0; SCON=0X50; PCON=0; TH1=TL1=0xFD; ES=1; F_485WR=0;//收 } */ //发送数据种类:1-状态反馈,2-重发,3-控制 //**uart 中断程序:****************************************** /* void uart0() interrupt 4 using 3 { if(RI) //receive interrupt { RI=0; if(!uartRcvCnt) { if(SBUF!=0xAA)return; } else if(SBUF==0xAA)uartRcvCnt=0; uartRcving=1; rcvBuff[uartRcvCnt]=SBUF; uartRcvCnt++; if(uartRcvCnt==6) { if(SBUF==0xBB) { if(rcvBuff[1]<=1&&(!rcvBuff[4]||rcvBuff[4]==0xFF)) { chanIdle=1; uartRcvTimer=datams;//计时(100us左右) if(rcvBuff[1]==0)//控制 {light2=~light2; if(rcvBuff[2]==localRoom&&(rcvBuff[3]&0xf)==localType&&(rcvBuff[3]>>4)==localTeam)//本地 { chanIdle=0; if(!rcvBuff[4])OUT1=1; else OUT1=0; F_state=1;//等待状态反馈 } else if(rcvBuff[3]>>4)chanIdle=2;//单控 } else if(uartSend_waiting) { uartSend_waiting=0; if(ROOM!=rcvBuff[2]||((rcvBuff[3]&0xf)!=TYPE)||((rcvBuff[3]>>4)!=TEAM)) dataType=2;//重发 } } } uartRcvCnt=0;uartRcving=0; } } else if(TI) //transmit interrupt { TI=0; if(uartSending) { uartSendTimer=datams; if(uartSendP>4);//team if((rcvBuff[2]&&rcvBuff[2]!=localRoom)||(x&&x!=localTeam))chanIdle=2;//单控 else if((x&&rcvBuff[2])||((!x||!rcvBuff[2])&&!rcvBuff[4])) { if(!rcvBuff[4])OUT1=1; else OUT1=0; // RUN_LED=~OUT1; if(rcvBuff[2]&&x) { chanIdle=0;//本地单控 F_state=1;//等待状态反馈 } } } } else if(uartSend_waiting) { uartSend_waiting=0; if(ROOM!=rcvBuff[2]||((rcvBuff[3]&0xf)!=TYPE)||((rcvBuff[3]>>4)!=TEAM)) dataType=2;//重发 } } } uartRcvCnt=0;uartRcving=0; } } else if(TI) //transmit interrupt { TI=0; if(uartSending) { uartSendTimer=datams; // if(uartSendP>1; //为“0”右移一位 if (P3_2==1) { result[bytes]=(result[bytes]|0x80); // 为“1”写入1 } } } if((result[0]&result[1]&result[2]&result[3])==0xff) { goto ir_exit; //防止连击 } if (!(result[0]==0x20&&result[1]==0xdf)) { goto ir_exit; //固定用户码是否正确 } key_data = result[2]; irc_flag=1; //z外中断红外数据接收完毕,置位返回主程序解码 } ir_exit: EA=1; EX0=1; //开外中断0 } /**************************************************************************** //uart数据发送执行程序,配合uart中断完成数据包的发送, //入口参数:发送字节 //当需要发送数据时且串口具备发送条件被调用 直接发送uartSendBuff中的数据 6A 01 01 02 FF 7B 6A 01 01 02 FF 7B //发送数据种类:1-状态反馈,2-重发,3-控制 *****************************************************************************/ void uartSendPerform() { if(uartSending||uartRcving)return; if(uartSend_waiting)return; if(F_state) { F_state=0; ROOM=localRoom;TYPE=localType;TEAM=localTeam; if(OUT1)STATE=0; else STATE=0xff; dataType=1;//状态反馈 } else if(!dataType)return; uartSending=1; sendBuff[0]=0xaa;sendBuff[5]=0xbb; if(dataType!=4&&dataType!=2) { if(dataType==1) { repeat=1;sendBuff[1]=0x01;//状态反馈 } else { sendBuff[1]=0x00;//控制 if(dataType==3)uartSend_waiting=1; } sendBuff[2]=ROOM;//房间 sendBuff[3]=(TEAM<<4)+TYPE; sendBuff[4]=STATE; } // uartSendCnt=6; SBUF=sendBuff[0]; // uartSendP=1; uartSendCnt=1; dataType=0; uartSendTimer=datams; F_485WR=1; } /***************************************************************************************/ 本文来自:proteus仿真论坛(http://proteus.5d6d.com),详细出处参考:http://proteus.5d6d.com/viewthread.php?tid=10660&highlight=485