打印
[51单片机]

写了一个超声波数码管测距的程序有点问题麻烦大神解答

[复制链接]
1761|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
px123zx|  楼主 | 2014-1-10 19:11 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar code table[]={                //共阴数码管0~9 -
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x40};
sbit Trig  = P2^5; //产生脉冲引脚
sbit Echo  = P2^4; //回波引脚
sbit DU = P2^6;
sbit WE = P2^7;                                                                          
bit flag=0;
uint time,s,timer;
uchar a,b,c,d;
void delay(uchar n)         //延时1us函数
{
        uchar i;
        for(i=0;i<n;i++)
        {
                _nop_();
        }
}
void delaym(uint z)
{
        uint x,y;
        for(x=z;x>0;x--)                                         
                for(y=110;y>0;y--);
}
void start()           // 触发超声波测距模块
{
//        delaym(800);
        Trig=1;
        delay(60);
        Trig=0;        
}
void conut()                 //计算距离
{
        time=TH0*256+TL0;                                                           
        TH0=0;
        TL0=0;
        s=time/58;
        a=s/1000;
        b=s%1000/100;
        c=s%100/10;
        d=s%10;
}
void display(uchar a,uchar b,uchar c,uchar d)   //显示距离
{
        if(flag==1||s>=700)
        {
                flag=0;
                DU=0;
                P0=table[10];
                DU=1;
                DU=0;

                WE=0;
                P0=0;
                WE=1;
                WE=0;
                delaym(4);
        }
        else
        {
                DU=0;
            P0=table[a];
            DU=1;
            DU=0;
           
            WE=0;
            P0=0xfe;
            WE=1;
            WE=0;
            delaym(4);
           
            P0=table[b];
            DU=1;
            DU=0;
           
            P0=0xfd;
            WE=1;
            WE=0;
            delaym(4);
        
            P0=table[c];
            DU=1;
            DU=0;
           
            P0=0xfb;
            WE=1;
            WE=0;
            delaym(4);
           
            P0=table[d];
            DU=1;
            DU=0;
           
            P0=0xf7;
            WE=1;
            WE=0;
            delaym(4);
                }
}
void main()
{
        TMOD=0x01;//设置定时器0工作方式
        TH0=0;
        TL0=0;
        ET0=1;//允许定时器0中断
        EA=1; //开总中断
        while(1)
        {  
                start();
                 while(!Echo);                  //当RX为零时等待
                 TR0=1;                                  //开启计数                                    
                 while(Echo);                  //当RX为1计数并等待
                 TR0=0;                                  //关闭计数
                conut();                          //计算
                display(a,b,c,d);                        
        }
}
void time0 () interrupt 1
{
        flag=1;
}

距离近没问题距离过远就会出现一点问题

相关帖子

沙发
px123zx|  楼主 | 2014-1-10 20:01 | 只看该作者
距离一远 第4位 由于扫描问题会比其他的亮 怎么解决呢

使用特权

评论回复
板凳
dirtwillfly| | 2014-1-10 21:11 | 只看该作者
楼主的电路是怎么连接的?

使用特权

评论回复
地板
gx_huang| | 2014-1-11 10:15 | 只看该作者
软件架构问题,测量、计算、显示是一条线顺序的,显示自然和距离有关了。
距离远,反射时间长,显示就不均匀了。

使用特权

评论回复
5
px123zx|  楼主 | 2014-1-11 10:16 | 只看该作者
dirtwillfly 发表于 2014-1-10 21:11
楼主的电路是怎么连接的?

用的开发板实验的

使用特权

评论回复
6
px123zx|  楼主 | 2014-1-11 10:35 | 只看该作者
gx_huang 发表于 2014-1-11 10:15
软件架构问题,测量、计算、显示是一条线顺序的,显示自然和距离有关了。
距离远,反射时间长,显示就不均 ...

这个我知道 后来我把数码管扫描换到定时器1里面去了

使用特权

评论回复
7
px123zx|  楼主 | 2014-1-11 10:37 | 只看该作者
gx_huang 发表于 2014-1-11 10:15
软件架构问题,测量、计算、显示是一条线顺序的,显示自然和距离有关了。
距离远,反射时间长,显示就不均 ...
void main()
{
        TMOD=0x11;
        TH0=0;
        TL0=0;
        TH1=0xf8;  //2ms定时
        TL1=0x30;
        ET0=1;//允许定时器0中断
        EA=1; //开总中断
        TR1=1;
        while(1)
        {  
                 while(!Echo);                  //当RX为零时等待
                 TR0=1;                                  //开启计数                                    
                 while(Echo);                  //当RX为1计数并等待
                 TR0=0;                                  //关闭计数
                conut();                          //计算               
        }
}
void time0 () interrupt 1
{
        flag=1;
}
void time1 () interrupt 3
{
        TH1=0xf8;
        TL1=0x30;
        display(a,b,c,d);
        timer++;
        if(timer>=400)
        {
                timer=0;
                start();
        }
}

后面改成这样了  就不显示了 还在找问题

使用特权

评论回复
8
px123zx|  楼主 | 2014-1-11 11:59 | 只看该作者
少了个ET0=1  加上还是有问题

使用特权

评论回复
9
gx_huang| | 2014-1-11 12:41 | 只看该作者
你的架构貌似改进了,其实还是错误的。
定时器里的显示程序,要每进一次定时中断,显示一个数字。
你一下子显示4个,和主程序显示有区别吗?

使用特权

评论回复
10
px123zx|  楼主 | 2014-1-11 15:38 | 只看该作者
gx_huang 发表于 2014-1-11 12:41
你的架构貌似改进了,其实还是错误的。
定时器里的显示程序,要每进一次定时中断,显示一个数字。
你一下子 ...

已经凌乱了 该怎么改呢

使用特权

评论回复
11
gx_huang| | 2014-1-11 15:44 | 只看该作者
我已经说的很明白了,剩下的要你自己思考。
比如4个数码管,定时中断时间4毫秒,每次进入中断,显示一个数字,马上退出,则每次进中断的处理时间很短。
每4毫秒,定时中断进去一下,显示完马上退出了。

你现在每次进入中断,显示完4个数码管,则起码需要16毫秒。失去了定时中断的意义。

使用特权

评论回复
12
ZG11211| | 2014-1-11 21:46 | 只看该作者
因为超声波测距时,距离远的话,测量的时间会超过最佳的动态显示扫描时间,所以做这种方案是必须考虑采用锁存显示方式,比如液晶显示或者专用LED显示芯片(比如TM1668),只在测距得到结果后才刷新显示。

使用特权

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

本版积分规则

3

主题

13

帖子

0

粉丝