打印

不再发数据给PC

[复制链接]
1030|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
llia|  楼主 | 2021-11-13 17:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#define   AD_OE    XBYTE[0xBFFF]
#define   AD_add   XBYTE[0xAFFF]
#define   po=P;
unsigned char j;
unsigned char i;
void delay( )
{
int a;
for(a=0;a<3;a++);
}
void interrupt1()interrupt 4 using 2
{
if(RI==1) {RI=0;}
else if(TI==1){;}
}
main()
{
EA=1;
ES=1;
ET1=1;
SCON=0x50;
PCON=0;
TMOD=0x20;
TH1=253;
TL1=253;
TCON=0x40;
while(!TI) {   
            AD_add=1;
             delay();
             AD_OE=1;
    i=P;
    SBUF=i;
     }
}
应该是AD采集一次数据,传输给PC后,因为TI为1,循环不能进行,就不会再发数据给PC了但是实际情况是PC不停的发同样的数据给PC,数据是6位16进制数;
后再循环前加入了TI=0;SBUF=0;结果发出的数都是0,请各位指点

使用特权

评论回复
沙发
heweibig| | 2021-11-13 17:12 | 只看该作者
貌似少了个while(1);------------------不然程序跑哪都不知道了,也许从头来过也说不定。

使用特权

评论回复
板凳
zhanghqi| | 2021-11-13 17:15 | 只看该作者

你的意思是你只需要给PC发一次数据就不再接着发了?
SBUF=0,发出的数据自然就是0了

使用特权

评论回复
地板
yszong| | 2021-11-13 17:18 | 只看该作者

while(!TI)那个不是么?
那当第一个0发完后,TI被置1,接着该在while(!TI)停下来吧,为什么不停的发送0呢

使用特权

评论回复
5
llia|  楼主 | 2021-11-13 17:20 | 只看该作者
刚才在中断服务程序中关串口中断,ES=0,还连续发数上来,困惑中,高手帮忙啊

使用特权

评论回复
6
guoyt| | 2021-11-13 17:22 | 只看该作者

初始化TI =0
当执行到while(!TI)时,满足条件,进入循环里面
执行SBUF=i;后,串口启动发送,但是发送这段时间内TI还是等于0,那么程序会在
while(!TI)中执行一小段时间(哪怕非常微小),所以可能就多发了几十个数据,当第一个数据发送完后,TI自动置位=1,进入中断函数,中断出来后必定返回while(!TI)循环体里面,而且里面有个延时呢!因为中断没清零,所以不断中断,不段地。。。

使用特权

评论回复
7
llia|  楼主 | 2021-11-13 17:24 | 只看该作者
为什么“程序会在while(!TI)中执行一小段时间(哪怕非常微小),所以可能就多发了几十个数据”呢?是不是这样的:SBUF要发送一帧完整数据需要10/9600s(约1ms),在这段时间AD采集到的数据会多次写入SBUF(在SBUF未发送完数据的情况,能再次写入么?),这样造成传入PC的数据是同样的数据的循环?为了只发一次数据,尝试在中断服务程序中关中断,结果单片机还是会连续发数到PC上,不解

使用特权

评论回复
8
lizye| | 2021-11-13 17:26 | 只看该作者

唉,又是一个不断复位操作的程序。

使用特权

评论回复
9
jiaxw| | 2021-11-13 17:28 | 只看该作者

LZ,你的main里没有死循环,所以每次执行完后又会从头开始,即又执行:
{
EA=1;
ES=1;
ET1=1;
。。。

到ET1=1;时,由于则是TI为1,所以进入中断,然后退出中断;
接着执行到SCON=0x50;,则是TI就变成0了!
然后继续下面的,while(!TI) 判断是当然就是真了,发送完后又一次回到main的开始。。。。

使用特权

评论回复
10
yufe| | 2021-11-13 17:29 | 只看该作者
有问题时建议多用下编译器自带的软件仿真,并点放大镜看一看汇编代码,很容易就能找出是哪里的问题了。

使用特权

评论回复
11
llia|  楼主 | 2021-11-13 17:35 | 只看该作者

void delay( unsigned char a )
{
for(;a>0;a--);
}

void interrupt1()interrupt 4 using 2
{
if(RI==1) {RI=0;}
else if(TI==1){TI=1;}
}
main()
{
EA=1;
ES=1;
ET1=1;
SCON=0x50;
PCON=0;
TMOD=0x20;
TH1=253;
TL1=253;
TCON=0x40;
while(1) {   
            AD_add=1;
             delay(20);
             AD_OE=1;
               i=P;
              SBUF=i;
                          delay(3000);
           }
}
修改后,仍然不断发数给PC,楼上各位,再帮帮忙,还有各情况,AD采不同信号,如5V,4V,3 V时,传到PC上是相同的值

使用特权

评论回复
12
xxrs| | 2021-11-13 17:38 | 只看该作者
提点意见

void delay( unsigned char a )
{
for(;a>0;a--);                //你知道这里延时多少吗?不会是乱写的吧。
}

void interrupt1()interrupt 4 using 2
{
if(RI==1) {RI=0;}
else if(TI==1){TI=1;}        //if  == 1  ,然后再等于1。这样子有意义吗?还不如去掉。
}
main()
{
EA=1;
ES=1;
ET1=1;
SCON=0x50;
PCON=0;
TMOD=0x20;
TH1=253;
TL1=253;
TCON=0x40;
while(1) {   
            AD_add=1;
             delay(20);
             AD_OE=1;
               i=P;
              SBUF=i;
                          delay(3000);               //uchar型的貌似最大255吧
           }
}

改改看

void delay( unsigned char a )
{
             for(;a>0;a--);
}

void interrupt1()interrupt 4 using 2
{
            if(RI==1) {RI=0;}
}
main()
{
          EA=1;
          ES=1;
          ET1=1;
          SCON=0x50;
          PCON=0;
          TMOD=0x20;
          TH1=253;
          TL1=253;
          TCON=0x40;
   
          AD_add=1;
          delay(20);
          AD_OE=1;
          i=P;
          SBUF=i;
          while(!TI);         //等待发送完
          TI =0;               //确实发完了,清标志

         while(1);          //按照你说的只发一次就行,那么,发完后就让它死循环得了。
}

使用特权

评论回复
13
llia|  楼主 | 2021-11-13 17:40 | 只看该作者
我又试了一次,这次倒是只发一个数上来,但是都是一样的FF,不论AD采的是什么,甚至我将写入SBUF的数改成个常数,还是发FF上来,不知道为什么

使用特权

评论回复
14
yszong| | 2021-11-13 17:43 | 只看该作者
用no_init主要是为了防止看门狗导致系统复位后数据重初始化。

使用特权

评论回复
15
pengf| | 2021-11-13 17:45 | 只看该作者
循环不能进行,就不会再发数据给PC了啊,估计是少了那个while了吧

使用特权

评论回复
16
llia|  楼主 | 2021-11-13 17:47 | 只看该作者

嗯,预料中的结果,先结贴吧,多谢大家啦

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

961

主题

8893

帖子

4

粉丝