首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 嵌入开发 > 单片机 >

串口中断顺序及原理,该如何处理

2013-12-11 
串口中断顺序及原理#include reg52.h#define uchar unsigned char bit Flag//串口接收到字符的标志uns

串口中断顺序及原理
#include <reg52.h>
#define uchar unsigned char ;
bit Flag;   //串口接收到字符的标志
unsigned char UartChar;

    
/*--------------------------------------------------------------
                           函数声明
--------------------------------------------------------------*/
void InitUART(void);
void SendByte(unsigned char dat);
void SendStr(unsigned char *s);

/*--------------------------------------------------------------
                            主函数
--------------------------------------------------------------*/
void main (void)
{
    //串口初始化
    InitUART();

    SendStr("\r\n\n SZ-51 UART test OK if you see these words!");
    SendStr("\r\n ARM技术论坛 神舟51开发板 单片机串口收发测试");
    SendStr("\r\n 神舟51开发板,中断方式接收,请输入字符:");
    
    Flag = 0;
    while (1)                       
    {
        if(Flag == 1) 
        {
            Flag = 0;
            SendByte(UartChar);
            if(UartChar == '\r')
            {
                SendByte('\n');
            }
        }
    }
}

/*--------------------------------------------------------------
                            串口初始化
--------------------------------------------------------------*/
void InitUART(void)
{

    SCON  = 0x50;   // SCON: 模式 1, 8-bit UART, 使能接收  
    TMOD |= 0x20;   // TMOD: timer 1, mode 2, 8-bit 重装
    //TH1 = 0xF3;   // 波特率4800、数据位8、停止位1。效验位无 (12M)
    TH1   = 0xFD;   // TH1:  重装值 9600 波特率 晶振 11.0592MHz  
    TR1   = 1;      // TR1:  timer 1 打开                         
    EA    = 1;      //打开总中断
    ES    = 1;      //打开串口中断
}                            

/*--------------------------------------------------------------
                            发送一个字节
--------------------------------------------------------------*/
void SendByte(unsigned char dat)
{
    SBUF = dat;
    while(!TI);
    TI = 0;
}

/*--------------------------------------------------------------
                            发送一个字符串
--------------------------------------------------------------*/
void SendStr(unsigned char *s)
{
    //检测是否字符串末尾, '\0'表示字符串结束标志,
    while(*s != '\0')
    {
        SendByte(*s);
        s++;
    }
}

/*--------------------------------------------------------------
                     串口中断程序
--------------------------------------------------------------*/
void UART_SER (void) interrupt 4 //串行中断服务程序
{
    if(RI)                  //判断是接收中断产生
    {
        RI=0;               //标志位清零


        UartChar = SBUF;    //读入缓冲区的值
        Flag = 1;           //把值输出到P1口,用于观察
    }
    
    if(TI)                  //如果是发送标志位,清零
    {
        //TI=0;             //发送为查询方式
    }


这是一个正常的串口收发函数,当我需要对中断接收的数据进行处理的时候,就会出现问题,所以我做了如下测试:
    while (1)                       
    {
        if(Flag == 1) 
        {
            Flag = 0;
            SendByte('a');

        }
    }
这样的话,当我从串口精灵发送一串字符,发送的时候就会出发中断,所以我收到的‘a’的个数是我发送字符的个数
我现在又这么做,不发送字符了,我发送字符串
while (1)                       
    {
        if(Flag == 1) 
        {
            Flag = 0;
            SendStr(“abcdef”);

        }
    }
这样的话,当我从串口精灵发送字符串给单片机,如果说每个字符都产生中断,那么“abcdef”的个数,应该跟我的字符串长度一致,但是实际上不是这样的,可能因为以前指示发送一个字符,所以只用之行一个机器周期,所以是跟原始程序一样,不影响操作。输出是正确的,但是发送字符串的话,执行的机器周期多了,改变了原有的操作,所以发送“abcdef”的个数大致上跟字符串长度是这样的关系1-1,2-1,3-2,4-2..7-3...
如果是这样的话,那我接收数据就会不断的丢失。。。
[解决办法]
中断接收中采用缓存方式:
   UartChar[RcLen++] = SBUF;    //读入缓冲区的值
   if(RcLen > MAXLEN)  RcLen = 0;
然后设置一个定时器,超时后再置Flag = 1;    

热点排行