当前位置: 代码迷 >> 单片机 >> 请各位帮小弟我修改下串口程序的异常
  详细解决方案

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

热度:218   发布时间:2016-04-28 16:29:30.0
请各位帮我修改下串口程序的错误
C/C++ code
#include <reg52.h>#define uchar unsigned char#define uint unsigned intunsigned 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,方便在主程序中检测
}
------解决方案--------------------
  相关解决方案