找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2034|回复: 9
收起左侧

51单片机串口中断碰到的问题请前辈指教一下晚辈

[复制链接]
ID:745568 发表于 2020-5-7 23:08 | 显示全部楼层 |阅读模式
我在今天学习了串口通讯,写了个串口通讯的小程序,部分功能实现了,但有个BUG,我不知道哪里出来的问题,程序功能是这样的,单片机P1.3有个按键,按一下发送一个0X11到串口助手上面,现在的情况是程序烧录到单片机里面初次按按键有数据上传到串口助手上面,但是一旦关了单片机电源再开,再按按键,那就没有任何数据上传到串口助手上面,但是这时候用串口助手随意发一个16进制数给单片机,这时候单片机又奇迹般的活了,我现在不知道从哪下手修改程序了,请论坛的前辈指教一下,下面附上单片机程序
#include<reg52.h>
#define uchar unsigned char

sbit key1=P1^3;
sbit key2=P1^2;
sbit key3=P1^1;
sbit key4=P1^0;
sbit l1=P0^0;
sbit l2=P0^1;
sbit l3=P0^2;
sbit l4=P0^3;
void ConfigUART(unsigned int baud);
void delay()
{
unsigned int i=11000;
while(i--);
}
void main()
{
   EA=1;
   ConfigUART(9600);
   while(1);
}

void ConfigUART(unsigned int baud)
{
   SCON=0x50;
   TMOD&=0x0f;
   TMOD|=0x20;
   TH1=256-(11059200/12/32)/baud;
   TL1=TH1;
   ET1=0;
   ES=1;
   TR1=1;
}

/*void InterruptUART()interrupt 4
{
  if(RI)
  {
    RI=0;
        SBUF=SBUF+1;
  }
  if(TI)
  {
    TI=0;
  }
}*/

void InterruptUART()interrupt 4
{
uchar temp,temp1;
      if(!key1)
                          {
                             delay();
                                 while(!key1);
                                 {
                                   temp=0x11;
                                        SBUF=temp;
                                   while(!TI);
                                 TI=0;
                                       
                                 }
              
    }
                                 
                                 
}

回复

使用道具 举报

ID:195446 发表于 2020-5-8 01:40 | 显示全部楼层
实现楼主只发不收的功能,不需要中断。就在楼主程序上改了下。(如果要自发自收再用串口接收中断)
void main()
{
     ConfigUART(9600);
    while(1);
{key_tran();}
}

void key_tran()
{
uchar temp,temp1;
       if(!key1)
                           {
                              delay();
                                  while(!key1);
                                  {
                                    temp=0x11;
                                         SBUF=temp;
                                    while(!TI);
                                  TI=0;
                                         
                                  }
       }
}
回复

使用道具 举报

ID:482935 发表于 2020-5-8 07:20 | 显示全部楼层
因为楼主的按键触发是在串口中断服务函数里,主函数中没扫描按键程序,(你的外部中断是否有按键中断没看到)。所以你触发不了按键一次,发送一个字节数据的现象。 你PC串口发送数据给51单片机,一旦51单片机接收完毕一个字节,RI会置1,会自动进入串口中断服务函数,然后一看你里面if(key==0),满足条件了,所以触发一次发送数据。 建议你把串口发送数据放入主函数中。 串口中断一般只有接收数据才使用。
回复

使用道具 举报

ID:213173 发表于 2020-5-8 08:17 | 显示全部楼层
在楼主程序基础上修改:操作按键发送数据到上位机和串口中断收到数据后返回上位机。看明白就能掌握串口的最基本运用。
  1. #include<reg52.h>
  2. #define uchar unsigned char

  3. sbit key1=P1^3;

  4. void ConfigUART(unsigned int baud)
  5. {
  6.    SCON=0x50;
  7.    TMOD&=0x0f;
  8.    TMOD|=0x20;
  9.    TH1=256-(11059200/12/32)/baud;
  10.    TL1=TH1;
  11.    ET1=0;
  12.    ES=1;
  13.    TR1=1;
  14. }

  15. void delay()
  16. {
  17.         unsigned int i=11000;
  18.         while(i--);
  19. }

  20. void main()
  21. {
  22.         EA=1;
  23.         ConfigUART(9600);
  24.         while(1)
  25.         {
  26.                 if(!key1)
  27.                 {
  28.                         delay();
  29.                         ES=0;                //关串口中断,防止与串口中断冲突
  30.                         while(!key1);
  31.                         {
  32.                                 SBUF=0x11;//发送数据到上位机
  33.                                 while(!TI);
  34.                                 TI=0;
  35.                                 ES=1;        //开串口中断
  36.                         }
  37.                 }
  38.         }
  39. }

  40. void InterruptUART()interrupt 4
  41. {
  42.         uchar temp;
  43.         RI=0;     //接收中断请求标志位
  44.         temp=SBUF;//获取SBUF接收到的数据
  45.         SBUF=temp;//将接收到的数据返回上位机
  46.         while(!TI);
  47.         TI=0;
  48. }
复制代码
回复

使用道具 举报

ID:65956 发表于 2020-5-8 08:57 | 显示全部楼层
按你这程序本来就只能执行一次
回复

使用道具 举报

ID:746236 发表于 2020-5-8 08:59 | 显示全部楼层
mffhxa 发表于 2020-5-8 01:40
实现楼主只发不收的功能,不需要中断。就在楼主程序上改了下。(如果要自发自收再用串口接收中断)
void m ...

楼主按键扫描的程序写在串口中断程序里面,如果单片机的串口终端未被触发,你的按键扫描程序就不会被执行,这就与你所得到的结果一样了,建议楼主如果只发不收的话采用楼上的建议,卓见仅供参考!
void InterruptUART()interrupt 4
{
uchar temp,temp1;
      if(!key1)
                          {
                             delay();
                                 while(!key1);
                                 {
                                   temp=0x11;
                                        SBUF=temp;
                                   while(!TI);
                                 TI=0;
                                       
                                 }
              
    }
回复

使用道具 举报

ID:65956 发表于 2020-5-8 09:05 | 显示全部楼层
你那程序本来就只能执行一次,简单的帮你改一下你试试,这样你每次按都可以的
#include<reg52.h>
#define uchar unsigned char

sbit key1=P1^3;
sbit key2=P1^2;
sbit key3=P1^1;
sbit key4=P1^0;
sbit l1=P0^0;
sbit l2=P0^1;
sbit l3=P0^2;
sbit l4=P0^3;
void ConfigUART(unsigned int baud);
void delay()
{
unsigned int i=11000;
while(i--);
}

//----------------------------
//发送串口数据
//----------------------------
void S1_SendData(unsigned char dat1)        //发送串口数据
{
        SBUF = dat1;                     //发送当前数据
        while (!TI);                    //等待前一个数据发送完成
        TI = 0;                         //清除发送标志
}


void main()
{
        ConfigUART(9600);
        EA=1;
        while(1)
        {
         if(!key1)
                }
                        delay();
                        if(!key1)
                        {
                                S1_SendData(0x11)        //发送串口数据
                        }       
                }
        }
}

void ConfigUART(unsigned int baud)
{
        SCON=0x50;
        TMOD&=0x0f;
        TMOD|=0x20;
        TH1=256-(11059200/12/32)/baud;
        TL1=TH1;
        ET1=0;
        ES=1;
        TR1=1;
}
回复

使用道具 举报

ID:745568 发表于 2020-5-8 12:43 | 显示全部楼层
13681878016 发表于 2020-5-8 07:20
因为楼主的按键触发是在串口中断服务函数里,主函数中没扫描按键程序,(你的外部中断是否有按键中断没看到 ...

哦,原来如此,我按这个思路改一下试试,感谢感谢
回复

使用道具 举报

ID:745568 发表于 2020-5-8 12:45 | 显示全部楼层
aking991 发表于 2020-5-8 08:57
按你这程序本来就只能执行一次

我初学,有时候被莫名其妙的问题给绕进去了,我按这个思路来改下程序,谢谢你了
回复

使用道具 举报

ID:745568 发表于 2020-5-8 12:46 | 显示全部楼层
haha1934 发表于 2020-5-8 08:59
楼主按键扫描的程序写在串口中断程序里面,如果单片机的串口终端未被触发,你的按键扫描程序就不会被执行 ...

好的,我会学习帖子所有的程序思路,十分感谢您了!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表