请各位帮小弟我修改下串口程序的异常

请各位帮我修改下串口程序的错误
C/C++ code

#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
unsigned char flag,a,i;
uchar b[4];
uchar code table[]="I get ";
void init()
{
    TMOD=0x20;     //确定T1的工作方式
    TH1=0xfd;        //计算T1的初值,装载TH1,TL1
    TL1=0xfd;
    TR1=1;            //启动T1
    REN=1;            //确定串行口的工作方式
    SM0=0;
    SM1=1;
    EA=1;
    ES=1;
}

void main()
{
    init();
    while(1)
    {
        if(flag==1)
        {
            ES=0;            //关闭串口中断,否则发送数据时同样申请中断,程序进入死循环
            for(i=0;i<6;i++)
            {
                SBUF=table[i];
                while(!TI);
                TI=0;
            }
            for(i=0;i<4;i++)
            {
                SBUF=b[i];
                while(!TI);        //发送完毕后,TI会被硬件置1,跳出循环,说明数据发送完毕
                TI=0;    //
            }
            ES=1;
            flag=0;
        }
    }
}

void ser() interrupt 4
{
    uchar j;
    for(j=0;j<4;j++)
    {
        while(!RI);
        RI=0;                //接受数据完成后,内部硬件置1,进入串口中断函数后
        b[j]=SBUF;    
    }                        //必须有软件清0
    flag=1;                //将flag置1,方便在主程序中检测
}


  现在用串口助手发送字符的时候,如果一次输入正好是4个字符,那么程序时没有错误的
但如果每次输入了2个字符,那么点击发送键后,串口助手是没有显示的,因为中断函数里的j还没有到4,
这样就需要发送2次,串口助手才会收到字符

但如果每次发送3个字符的话,第一次依然没有显示,但第二次发送后会保留多余的字符到b[j],这样以后再一次发送4个字符的话,串口助手以后收到的字符就会和发送的有点出入

求修改!
  如果输入少于4个字符,下次发送的时候,可以把b[]里保存的字符清空
  如果输入大于4个字符,下子发送的事业,也可以把b[]里多保存的字符清空

最好在中断函数里修改后发出来

------解决方案--------------------
1.你给一个数据接受中断就进入了,然后进入了那个for循环,如果你输入的不满4个字符,由于 while(!RI);你的中断程序总是 处于等待状态,根本就没有从接收中断跳出来,所以不会返回的数据的,
2.而当你给的字符一旦满4个立刻回从接收中断跳出,并执行串口发送,所以你会看到发的字符多于4个的时候,能够显示前4个字符,至于多余的部分,由于你第五发送的数据引起中断前,你就在主函数里关闭了中断,进行串行发送,所以第五个数据及其以后的就进入等待状态,等到你给pc发送完毕之后重新打开串口中断,又把第五个及其以后的数据写入你那个字符数组b[]了。但是这时候再次进入接收中断,重新进行初始化,j在for循环被赋初值0,所以你发的4个以后的多余数据存储在b[0]b[1]。。。。。当中了,当然了你多余的数据如果不足4个又回到了第一种情况,只有等到4个才会从中断跳出来了。。多余四个就是第二种情况,多余的等到下次从头开始存入。。。。
------解决方案--------------------
楼主可以加一个接收超时,如果超过一定时间还没接收到4个字符,就将接收清空;
如果超过四个接不保存,超时并且接收到大于等于4个时就将表明,接收完毕。
------解决方案--------------------

#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
unsigned char flag,a,i;
uchar b[4];
uchar code table[]="I get ";
void init()
{
TMOD=0x20; //确定T1的工作方式
TH1=0xfd; //计算T1的初值,装载TH1,TL1
TL1=0xfd;
TR1=1; //启动T1
REN=1; //确定串行口的工作方式
SM0=0;
SM1=1;
EA=1;
ES=1;
}

void main()
{
init();
while(1)
{
if(flag==1)
{
ES=0; //关闭串口中断,否则发送数据时同样申请中断,程序进入死循环
for(i=0;i<6;i++)
{
SBUF=table[i];
while(!TI);
TI=0;
}
for(i=0;i<4;i++)
{
SBUF=b[i];
while(!TI); //发送完毕后,TI会被硬件置1,跳出循环,说明数据发送完毕
TI=0; //
}
ES=1;
flag=0;
}
}
}

void ser() interrupt 4
{ long int i=0,p=0;
uchar a[100];
uchar j;
for(j=0;j<100;j++)
{
while(!RI){i++;if(i==10000) return;}
RI=0; //接受数据完成后,内部硬件置1,进入串口中断函数后
p++;
if (p<4)
b[j]=SBUF;
else 
a[j]=SBUF;
} //必须有软件清0
flag=1; //将flag置1,方便在主程序中检测
}
------解决方案--------------------