这个51超声波测距程序为什么数码管只显示最高位?后面几位都很暗?应该怎么改一下,谢谢

2019-07-15 12:55发布

#include <reg52.H>  //器件配置文件
  #include <intrins.h>
  unsigned int  time=0;
  unsigned int  timer=0;
  unsigned long S=0;  //用于显示最后计算得到的距离
  bit  flag =0;      //判断是否溢出
sbit dula=P2^6;
sbit wela=P2^7;      //用于数码管显示
sbit RX=P1^1;             //echo
sbit TX=P1^2;             //trig
// sbit D5=P1^4;            //可以不要。echo高电平时点亮D5灯
unsigned long x;     //用于数码管显示

unsigned char code table[]={   //共阴数码管
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71
};

void Display(unsigned long num);
void Delay(unsigned int z);     //z=1大概是1ms
void Conut(void)///////////计算程序
{
  time=TH0*256+TL0;          //这是最后算到的时间往返时间但应该再乘以
                               //12/11.0593M是一个机器周期时间应该是
time*12/11.0592  ;
  TH0=0;            //定时器0的初始值为0

  TL0=0;

  S=(time*1.845)/100;     //算出来是CM
//   S=(time*1.845)/10;   //算出来是mm
//time*12*170/(11.0592*1000)mm=time*1845/10000 mm

if (S>=500)        //最大距离5m即500cm
  S=888888;
if (flag==1)        //判断是否溢出
  {S=888888;
   flag=0;
   TH0=0;
   TL0=0;
  }
}
/********************************************************/

     void zd0() interrupt 1    //T0中断用来计数器溢出,超过测距范围

  {

    flag=1;     //中断溢出标志

  }                       //这是最重要的计时0中断TH0和TL0初始值为0

/********************************************************/
void  zd3()  interrupt 3    //T1中断用来扫描数码管和计800MS启动模块
  {                                 //这是计时器1中断

  TH1=0xf8;                      //赋初值应该是2ms
  TL1=0x30;

  timer++;

  if(timer>=400)

  {

   timer=0;

   TX=1;                  //800MS  启动一次模块

   Delay(30);            //一次超声波信号时长30ms

   TX=0;
}  

  }

/*********************************************************/
void  main(  void  )
  {   

    TMOD=0x11;     //设T0为方式1GATE=1

TH0=0;              //目的都是用中断T0和T1

TL0=0;          //中断0初始化

TH1=0xf8;     //2MS定时

TL1=0x30;

ET0=1;             //允许T0中断

ET1=1;      //允许T1中断

TR1=1;      //开启定时器

EA=1;      //开启总中断
while(1)
{

  while(!RX);  //当RX为零时等待即echo为低电平

  TR0=1;       //开启计数

//  D5=0;             //可以不要指示灯
  while(RX);   //当RX为1计数并等待

  TR0=0;    //关闭计数
//  D5=1;             //可以不要指示灯
   Conut();   //计算
Display(S);         //数码管显示
}
}
void Display(unsigned long num)  //定义子函数用于显示五位数
{
                  //调用子函数前先要在main函数前面声明位选和段选
/*即
sbit dula=P2^6;
sbit wela=P2^7;
*/
unsigned int temp;  //用于延迟for函数
unsigned char shiwanwei,wanwei,qianwei,baiwei,shiwei,gewei;
//定义这个六位数的十万位到个位

shiwanwei=num/100000;
wanwei=num%100000/10000;
qianwei=num%10000/1000;
baiwei=num%1000/100;
shiwei=num%100/10;
gewei=num%10;

wela=1;
P0=0xdf;//1111 1011  //位选个位
wela=0;
dula=1;
P0=table[gewei];
dula=0;  
for(temp=100;temp>0;temp--);

    if(shiwanwei!=0||wanwei!=0||qianwei!=0||baiwei!=0||shiwei!=0)
{//判断高位是否都为0为0的话不显示高位的0
  wela=1;
  P0=0x6f; //1111 0110 //位选十位
  wela=0;
  P0=0xff;
  dula=1;
  P0=table[shiwei];
  dula=0;  
  for(temp=50;temp>0;temp--);
}

    if(shiwanwei!=0||wanwei!=0||qianwei!=0||baiwei!=0)
{
  wela=1;
  P0=0x77; //1110 1110 //位选百位
  wela=0;
  P0=0xff;   
  dula=1;
  P0=table[baiwei];  
  dula=0;  
  for(temp=50;temp>0;temp--);
}


if(shiwanwei!=0||wanwei!=0||qianwei!=0)
{
  wela=1;
  P0=0x7b; //1101 1110 //位选千位
  wela=0;  
  P0=0xff;  
  dula=1;
  P0=table[qianwei];   
  dula=0;  
  for(temp=50;temp>0;temp--);
}
if(shiwanwei!=0||wanwei!=0)
{
  wela=1;
  P0=0x7d; //1011 1110 //位选万位
  wela=0;  
  P0=0xff;  
  dula=1;
  P0=table[wanwei];   
  dula=0;  
  for(temp=50;temp>0;temp--);
}  
if(shiwanwei!=0)
{
  wela=1;
  P0=0x7e; //0111 1110 //位选万位
  wela=0;  
  P0=0xff;  
  dula=1;
  P0=table[shiwanwei];   
  dula=0;  
    for(temp=50;temp>0;temp--);
}  
}

void Delay(unsigned int z)  //基本上是z赋值为1就对应1ms
{
unsigned int a,b;
for(a=z; a>0; a--)
  for(b=110; b>0; b--);
}


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
4条回答
liu_z-w
1楼-- · 2019-07-15 13:34
可能延时太长。各位之间显示延时去掉。或者减少 最佳答案
小贼你别跑
2楼-- · 2019-07-15 15:16
会不会是硬件连接的问题,我曾经就碰到过这样的例子
275849752
3楼-- · 2019-07-15 17:47
 精彩回答 2  元偷偷看……
275849752
4楼-- · 2019-07-15 18:01
liu_z-w 发表于 2016-10-14 09:51
可能延时太长。各位之间显示延时去掉。或者减少

嗯,以后试试。。。

一周热门 更多>