找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3465|回复: 21
打印 上一主题 下一主题
收起左侧

新手请教个关于单片机串口和pc通信的问题

[复制链接]
跳转到指定楼层
楼主
ID:70774 发表于 2014-12-20 12:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我用PC(串口调试助手)给单片机发送两个字节的数据,我搞不清楚这两个字节发送时的具体情况,于是写了下面的程序校验一下,我疑惑的是在if语句中如果把ES=1这句去掉,为什么一个字节都收不到了,程序如下
#include <reg52.h>
unsigned char flag,a;
void init();
void main()
{
init();
while(1)
{
if(flag==1)
{
ES=0;
flag=0;
SBUF=a;
while(!TI);
TI=0;
ES=1;//把这个去掉就一个字节都收不到了。
}
}
}
void ser() interrupt 4
{
RI=0;
flag=1;
a=SBUF;
}
void init()
{
TMOD=0x20;
TH1=0xf4;
TL1=0xf4;
TR1=1;
REN=1;
SM0=0;
SM1=1;
EA=1;
ES=1;
}
我对程序的理解是:我在PC上写两个字节的数据,一个一个发送,首先发送一个字节。那么单片机SBUF收到一个字节后会请求中断,这时我把sbuf中的值取走,并且主程序中检测标志位flag等于1,再把这个数据发送到PC,如果在主程序中最后一句ES=1保留,那么第二个发送的数据发送完时,在中断中又去取数,取完后再发送到PC,但是如果我把这一句删除掉,那么我理应收到第一个字节啊,第二字节由于没有开中断,就无法执行中断,也无法取出第二个字节的数据,进而无法发送到PC啊,可是我一个字节都收不到了。。有大神解惑吗?不太理解传输过程,我的理解是,单片机一直在执行主程序,只不过SBUF收到一个数据,CPU停下手头的工作去执行取数据的命令(或者不取,主程序跟所取数据无关,一般通信也不会这么干吧),那么为什么一个字节都收不到呢,我觉得应该可以收到一个字节的数据啊

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:67992 发表于 2014-12-20 16:29 | 只看该作者
单片机上电复位时是不稳定的,理想情况当然如你所想那样。上电不该运行的中断服务程序自动运行了一次,导致flag=1,结果主程序里满足if条件也运行了,发送a给串口,a的内容是自动运行读取的内容,大多为0xff.
结果你又把ES关住了。你第一次输入数据,对单片机来说是第二次了,当然没反应了。
回复

使用道具 举报

板凳
ID:67992 发表于 2014-12-20 16:33 | 只看该作者
改成这样试下:
#include <reg52.h>
unsigned char flag,a;
void init();
void main()
{
init();
while(1)
{
if(flag==1)
{
ES=0;
flag=0;
SBUF=a;
while(!TI);
TI=0;
//ES=1;//把这个去掉就一个字节都收不到了。
}
}
}
void ser() interrupt 4
{
RI=0;
a=SBUF;
if(a!=0xff)
flag=1;
}
void init()
{
TMOD=0x20;
TH1=0xf4;
TL1=0xf4;
TR1=1;
REN=1;
SM0=0;
SM1=1;
EA=1;
ES=1;
}
回复

使用道具 举报

地板
ID:18297 发表于 2014-12-20 16:37 | 只看该作者
单片机 的ES是串行口中断允许位。
如果ES=0,不会即使有数据发给单片机,也不会产生中断。
这里ES=0,然后进行发送。(为了发送时禁止产生接受中断)
而发送完后,再设置ES=1,允许串口中断,可以接受数据并产生串口中断,执行串口中断程序。
回复

使用道具 举报

5#
ID:70774 发表于 2014-12-20 22:38 | 只看该作者
dgahz 发表于 2014-12-20 16:33
改成这样试下:
#include
unsigned char flag,a;

谢谢您的回答,可以加您的微信或者qq吗?
回复

使用道具 举报

6#
ID:67992 发表于 2014-12-20 23:29 | 只看该作者
我很少上Q,有什么问题发本坛我看到会的话会答复的,我初学单片机,喜欢分析,从中也可学到东西,原理性的东西我说的也不一定对,大家一起探讨,理不辩不明。
回复

使用道具 举报

7#
ID:70774 发表于 2014-12-21 09:58 | 只看该作者
dgahz 发表于 2014-12-20 23:29
我很少上Q,有什么问题发本坛我看到会的话会答复的,我初学单片机,喜欢分析,从中也可学到东西,原理性的东 ...

真实太感谢您了。以后有电路方面不懂的还需向您多多请教啊。感觉找到了志同道合的。对了下面还有一个问题,想问问您的看法。有时候我把程序烧录到单片机中,打开串口助手,还没点发送呢,它就直接发送了而且停不下来,这又是为什么呢?我也没有按复位键。是不是因为烧录时,也是通过RXD引脚烧录进去的,这时已经在接收数据了,从而导致程序收到烧录的影响?(不知道你所说的上电复位是什么意思,因为烧录的时候就需要上电啊。)还有就是通信过程和定时器工作差不多,就是通信时,CPU不问事,等到串口中断标志位置一,cPU才会去取数,当然也可以不开中断,但是总要有某种方式来清空标志位把(比如位检测,一直检测是否中断标志位是否置一,但是这样会影响效率,占用CPU),要不然标志位一直是1,无法判断是否又完成了一次数据的传输,一般来说单片机会用中断的形式对SBUF里的值进行操作(取),毕竟通信的目的就是发送指令或者传递数据啊,这都是我自己的想法,不知道里面有没有错,希望您能解答!谢谢您。
回复

使用道具 举报

8#
ID:67992 发表于 2014-12-21 10:09 来自触屏版 | 只看该作者
我调试中初始(烧录完程序)发现RI有置1的现象,按道理应该不会有这个现象,只能猜想硬件须平稳过程,也有可能如你所说和烧录共用了串口的原因。
回复

使用道具 举报

9#
ID:67992 发表于 2014-12-21 10:14 来自触屏版 | 只看该作者
清标志接收一般在中断吧,cPu可及时处理,发送给串口助手由cPu掌控,几时发由编好的程序决定。
回复

使用道具 举报

10#
ID:67992 发表于 2014-12-21 10:23 来自触屏版 | 只看该作者
程序运行不外乎两个地方,中断内和中断外,中断内处理一些cPu无法预知何时发生的事件,中断外cpu以查询指令的方式运行,当没有查询到某个指令时,即使和这个指令相关的事件已发生,cPu是蒙在鼓里的,它不可能去处理,如此时它在处理一些延时较长的其它事件,情況更糟。
回复

使用道具 举报

11#
ID:67992 发表于 2014-12-21 10:26 来自触屏版 | 只看该作者
烧录停不下来的程序贴上来我看看,应该不会有这样的问题。
回复

使用道具 举报

12#
ID:70774 发表于 2014-12-21 10:40 | 只看该作者
dgahz 发表于 2014-12-21 10:26
烧录停不下来的程序贴上来我看看,应该不会有这样的问题。

#include <reg52.h>
unsigned char flag,a,p,temp;
void init();
void main()
{

  flag=0;
  init();
  while(1)
   {  
    if(flag==1)
     {
       
                flag=0;
                SBUF=p;
                while(!TI);
                TI=0;
                ES=1; //这句去掉,一个字节都收不到了      
     }


       
         
}

}
void   dd() interrupt 4
{
        RI=0;
        p=SBUF;
        flag=1;
}

void init()
{
TMOD=0x20;
TH1=0xf4;
TL1=0xf4;
TR1=1;
REN=1;
SM0=0;
SM1=1;
EA=1;
ES=1;
}
只是把上面的ES=0去掉了,烧录完,打开调试助手的“打开串口”,我没点发送,哗啦啦,FFFF就出现了,不断在接收。
回复

使用道具 举报

13#
ID:67992 发表于 2014-12-21 10:54 | 只看该作者
RI和TI是或的关系,看说明书有讲到。只要两者之一置1,都 会执行中断服务函数,就会不断发送和接收。SBUF没数据就会填充FF.
回复

使用道具 举报

14#
ID:67992 发表于 2014-12-21 10:58 | 只看该作者
去掉ES=0,TI置1也进中断了。
回复

使用道具 举报

15#
ID:70774 发表于 2014-12-21 11:11 | 只看该作者
dgahz 发表于 2014-12-21 10:58
去掉ES=0,TI置1也进中断了。

但是我还没有发送数据,整个程序应该还没执行,当我发送一个数据之后,才应该陷入死循环啊。不知道为什么就直接陷入死循环了
回复

使用道具 举报

16#
ID:67992 发表于 2014-12-21 11:28 来自触屏版 | 只看该作者
我之前不是说过了吗,烧录完单片机自己发送了FF一次,RI置1了,结果就有你说的现象了。
回复

使用道具 举报

17#
ID:67992 发表于 2014-12-21 11:32 来自触屏版 | 只看该作者
烧录完它自己进了一次中断,原因不明。
回复

使用道具 举报

18#
ID:67992 发表于 2014-12-21 11:34 来自触屏版 | 只看该作者
你沒输数据,里面数据默认为FF。
回复

使用道具 举报

19#
ID:70774 发表于 2014-12-21 11:47 | 只看该作者
dgahz 发表于 2014-12-21 11:34
你沒输数据,里面数据默认为FF。

明白,谢谢
回复

使用道具 举报

20#
ID:241242 发表于 2017-11-17 19:10 | 只看该作者
学习一下!
回复

使用道具 举报

21#
ID:250537 发表于 2017-11-17 20:12 | 只看该作者
单片机 的ES是串行口中断允许位。 如果ES=0,不会即使有数据发给单片机,也不会产生中断。 这里ES=0,然后进行发送。(为了发送时禁止产生接受中断) 而发送完后,再设置ES=1,允许串口中断,可以接受数据并产生串口中断,执行串口中断程序。
回复

使用道具 举报

22#
ID:250542 发表于 2017-11-17 20:33 来自触屏版 | 只看该作者
这里可以学习很多
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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