| 
 
| 背景描述:小弟用PIC16F887单片机与电脑通信,因为是485的协议,所以使用了两片芯片SN75176,一片作为接收,一片作为发送。通信协议是,电脑先发送5个字节给单片机,单片机接收并判断正确了,则会置发送标志位,然后向电脑发送数据。 问题描述:现在目前的情况是,在线调试时,发现单片机总是出现接收溢出错误,然后就再也接收不了数据(我们使用中断接收)。如果直接置发送标志位,则可以向电脑发送数据。所以,目前排除了硬件上的问题,认为是软件的问题,但是却找不出来。
 请高手指点下,十分感谢!
 下面是具体的程序,用在其他单片机PIC16F77,可以成功的通信。
 
 #define     RECV_INIT       0
 #define     RECV_ID         1
 #define     RECV_STATE      2
 #define     RECV_Sum        3
 #define     RECV_END        4
 #define     RECV_TIMEOUT    50
 /********初始化**************/
 void Init_UART(void)
 {
 ADCON1=0X07;
 TRISC6=0; // output
 TRISC7=1; // input
 SPBRG=25;                      //9600
 TXSTA=0b00100100;
 RCSTA=0b10010000;
 GIE = 1;
 RCIE=1;
 }
 /********如果接收电脑发送的数据,若正确,则置标志位**************/
 if(RCIF)    //   放在中断程序里
 {
 ch=RCREG;
 Receive_timeout=RECV_TIMEOUT;
 switch(Receive_state)
 {
 case    RECV_INIT:
 if(ch==0x68)
 {
 Receive_state=RECV_ID;
 Receive_timeout=RECV_TIMEOUT;
 }
 else  Receive_timeout=1;
 break;
 case    RECV_ID:
 Receive_state=RECV_STATE;
 Receive_buf[0]=ch;      //uP ionizer ID
 Data_Checksum=ch;
 break;
 
 case    RECV_Sum:
 Receive_state=RECV_END;
 Receive_buf[2]=ch;           // the received checksum
 break;
 case    RECV_END:
 if(ch==0x68)
 {
 if(Receive_buf[0]==Device_Address)
 {
 if(Receive_buf[2]==Data_Checksum)
 {
 Receive_Flag=1;    //receive ok
 // Run_state=Receive_buf[1];
 }
 }
 }
 default:
 Receive_timeout=0;
 Receive_state=RECV_INIT;
 break;
 }
 
 /********如果接收成功,则开始向电脑发送数据**************/
 
 if(Receive_Flag==1)           //  放在main程序里
 {
 //增加通讯指示
 WriteLCDCommand(PageAddress+3,2);
 WriteLCDCommand(50,2);
 for(ch=0;ch<8;ch++)WriteLCDData(0xFF,2);
 //通讯开始,上传状态字 20060314
 Receive_Flag=0;
 RA2=1;         //start to send
 ch=Device_Address;
 TXREG=ch;                          //TXREG:USART Transmit Data Register 20050313
 Data_Checksum=ch;
 while(!TRMT);          //send the id
 ch=temp1&0xff;
 TXREG=ch;
 Data_Checksum+=ch;
 while(!TRMT);       //send the VB3 data low byte
 ch=(temp1>>8)&0xff;
 ch |=0x80;
 TXREG=ch;
 Data_Checksum+=ch;
 while(!TRMT);       //send the VB3 data high byte
 
 ch=temp2&0xff;
 TXREG=ch;
 Data_Checksum+=ch;
 while(!TRMT);       //send the VB2 data low byte
 ch=(temp2>>8)&0xff;
 ch |=0x80;
 TXREG=ch;
 Data_Checksum+=ch;
 while(!TRMT);             //send the VB2 data low byte
 
 ch=temp3&0xff;
 TXREG=ch;
 Data_Checksum+=ch;
 while(!TRMT);       //send the VB1 data low byte
 ch=(temp3>>8)&0xff;
 ch |=0x80;
 TXREG=ch;
 Data_Checksum+=ch;
 while(!TRMT);       //send the VB1 data high byte
 
 TXREG=Data_Checksum;
 while(!TRMT);       //send checksum
 RA2=0;               //switch off sending
 }
 | 
 |