单片机(16F877A)串口传数据问题

liuxiaosheng   2009-5-17 20:30 楼主
我用pc往单片机串口写数据,1次只能写1个字节,然后停留20MS才能写下一个。如果速度过快(一次写多字节或不停的1个1个往里写)串口中断1次后就没用中断产生。波特率两边都是9600,异步模式,大家帮我想下是什么原因啊?

回复评论 (7)

可能通信线路不好……
点赞  2009-5-17 21:01
还有点没说清楚:发送速度过快出错(没中断产生)后,用慢速发也没中断产生,必须复位单片机
点赞  2009-5-17 22:01
如果方便, 把主函数和中断处理函数贴出来吧。
点赞  2009-5-17 22:35
好的#include
#include

__CONFIG(HS&WDTDIS&PWRTEN&BORDIS&LVPDIS&DEBUGDIS&UNPROTECT);

//引脚功能定义

#define  BUSY RB0
#define  RES RB1
#define  REQ RB2
#define DATALEN 24

static volatile unsigned char SEND_DATA,TIME_S5;
static volatile unsigned int ReadData=0;
static volatile  bit                TMR1_IE;
static volatile unsigned char tData,bIsData,bIsCom,head=0,last=0,Rec_Data[DATALEN];
  

void        InitPort()       
{        PORTA=0X0;
        PORTB=0X06;                //REQ,低有效
        PORTC=0X00;
        PORTD=0x0;
        PORTE=0X0;       
        TRISA=0X0;       
        TRISC=0XC0;                //C7、C6为串行通讯口
        TRISB=0X01;
        TRISD=0X0;
        TRISE=0;
//定时器初始化
        TMR1IF=0;
        TMR1H=0X15;                //FOSC=12M
        TMR1L=0X9F;                //TIMER1=20MS=60000/3
        T1CON=0X1;
        TMR1IE=1;
          PEIE=1;
        PIE1=1;

//串行通讯初始化       
        TXSTA=0x24;        //SYNC=0、高波特率、TXEN=1
        SPBRG=0X4D;        //波特率产生9600 (0X4D)
        TXIE=0;
        RCIE=0;        //接收中断允许
        RCSTA=0x80;        //异步接收允许=0、串口允许
        CREN=1;//收允许
       
        ei();       
        RES=1;                        //复位LCD
        REQ=1;
        RBPU=0;                //弱上拉允许
}
void send_byte()
{
          REQ=1;NOP();NOP();
        while(BUSY==1)
        {;}
        PORTD=SEND_DATA;
        NOP();NOP();NOP();NOP();       
        REQ=0;
        while(BUSY==0)
        {;}
        REQ=1;NOP();NOP();
}
void InitLED()
{
        SEND_DATA=0XF4;                //清屏
        send_byte();
       
        SEND_DATA=0XFF;                //正常工作
        send_byte();
        SEND_DATA=0X00;
        send_byte();
       
        SEND_DATA=0XFE;                //显示模式
        send_byte();
        SEND_DATA=0X00;
        send_byte();
        SEND_DATA=0X02;
        send_byte();
}

void ShowOK()
{
        SEND_DATA=0XDC;        //EB
        send_byte();
        SEND_DATA=0;
        send_byte();
        SEND_DATA=0;
        send_byte();
        SEND_DATA='O';       
        send_byte();       
        SEND_DATA='K';       
        send_byte();
        SEND_DATA='.';       
        send_byte();
        SEND_DATA=0X0;        //END
        send_byte();
       
}
void        interrupt INT()
{       
        //串口接收中断处理
          if (RCIF==1)                //串口接收中断
    {  if(FERR||OERR)
          { FERR=0;
            OERR=0;
            #asm
            BCF        _STATUS,0X5
            BCF        _STATUS,0X6
            MOVF        _RCREG,W
            MOVF        _RCREG,W
            #endasm
           }
                  tData=RCREG;//0X01接收数据开始,0X02命令,0X00传输结束
                RC1=!RC1;
                 if(((last+1)%DATALEN)!=head)
                {
                        Rec_Data[last]=tData;//将数据装入循环链表       
                        last=(last+1)%DATALEN;                       
                }        
          
    }  
        if (TMR1IF==1)                //TIME1
        {
                TMR1IF=0;
                TMR1H=0X15;                //+6
                TMR1L=0XA5;                //TIMER1=20MS=60000/3
                PIE1=1;
                TIME_S5+=1;
                if(        TIME_S5>18)        //25*20=0.5S
                {
                        TIME_S5=0;
                        TMR1_IE=1;
                }
        }
   
}  

void main()
{
        InitPort();
        InitLED();
          ShowOK();
        while(1)
        {       
                if(head!=last)
                {       
                         if(Rec_Data[head]==0X01)       
                        {       
                                SEND_DATA=0XDC;        //EB
                                send_byte();
                                SEND_DATA=0;
                                send_byte();
                                SEND_DATA=0;
                                send_byte();                                       
                        }
                        else if(Rec_Data[head]==0X00)       
                        {       
                                SEND_DATA=0X00;
                                send_byte();
                                                       
                        }
                        else if(Rec_Data[head]==0X02)       
                        {       
                                                                                       
                        }
                        else
                        {       
                                SEND_DATA=Rec_Data[head];
                                send_byte();                       
                        }
                        head=(head+1)%DATALEN;
                        RC2=!RC2;
                }
                if(TMR1_IE)
                {
                        TMR1_IE=0;
                        RC0=!RC0;
                }       
        }       
}

点赞  2009-5-18 09:11
为何一次只传一个数据,是你单机的问题比较大。
点赞  2009-5-18 10:17
传多个,或一个一个快速传就会出问题,没有中断
点赞  2009-5-18 11:13
波特率太大?再检查一下
点赞  2010-3-9 16:59
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复