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

[复制链接]
 楼主| 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 | 显示全部楼层
软件架构问题,测量、计算、显示是一条线顺序的,显示自然和距离有关了。
距离远,反射时间长,显示就不均匀了。
 楼主| px123zx 发表于 2014-1-11 10:16 | 显示全部楼层
dirtwillfly 发表于 2014-1-10 21:11
楼主的电路是怎么连接的?

用的开发板实验的

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

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

这个我知道 后来我把数码管扫描换到定时器1里面去了
 楼主| px123zx 发表于 2014-1-11 10:37 | 显示全部楼层
gx_huang 发表于 2014-1-11 10:15
软件架构问题,测量、计算、显示是一条线顺序的,显示自然和距离有关了。
距离远,反射时间长,显示就不均 ...
  1. void main()
  2. {
  3.         TMOD=0x11;
  4.         TH0=0;
  5.         TL0=0;
  6.         TH1=0xf8;  //2ms定时
  7.         TL1=0x30;
  8.         ET0=1;//允许定时器0中断
  9.         EA=1; //开总中断
  10.         TR1=1;
  11.         while(1)
  12.         {  
  13.                  while(!Echo);                  //当RX为零时等待
  14.                  TR0=1;                                  //开启计数                                    
  15.                  while(Echo);                  //当RX为1计数并等待
  16.                  TR0=0;                                  //关闭计数
  17.                 conut();                          //计算               
  18.         }
  19. }
  20. void time0 () interrupt 1
  21. {
  22.         flag=1;
  23. }
  24. void time1 () interrupt 3
  25. {
  26.         TH1=0xf8;
  27.         TL1=0x30;
  28.         display(a,b,c,d);
  29.         timer++;
  30.         if(timer>=400)
  31.         {
  32.                 timer=0;
  33.                 start();
  34.         }
  35. }

后面改成这样了  就不显示了 还在找问题
 楼主| px123zx 发表于 2014-1-11 11:59 | 显示全部楼层
少了个ET0=1  加上还是有问题
gx_huang 发表于 2014-1-11 12:41 | 显示全部楼层
你的架构貌似改进了,其实还是错误的。
定时器里的显示程序,要每进一次定时中断,显示一个数字。
你一下子显示4个,和主程序显示有区别吗?
 楼主| px123zx 发表于 2014-1-11 15:38 | 显示全部楼层
gx_huang 发表于 2014-1-11 12:41
你的架构貌似改进了,其实还是错误的。
定时器里的显示程序,要每进一次定时中断,显示一个数字。
你一下子 ...

已经凌乱了 该怎么改呢
gx_huang 发表于 2014-1-11 15:44 | 显示全部楼层
我已经说的很明白了,剩下的要你自己思考。
比如4个数码管,定时中断时间4毫秒,每次进入中断,显示一个数字,马上退出,则每次进中断的处理时间很短。
每4毫秒,定时中断进去一下,显示完马上退出了。

你现在每次进入中断,显示完4个数码管,则起码需要16毫秒。失去了定时中断的意义。
ZG11211 发表于 2014-1-11 21:46 | 显示全部楼层
因为超声波测距时,距离远的话,测量的时间会超过最佳的动态显示扫描时间,所以做这种方案是必须考虑采用锁存显示方式,比如液晶显示或者专用LED显示芯片(比如TM1668),只在测距得到结果后才刷新显示。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

13

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部