宁采儿 发表于 2012-11-26 01:32:39

跪求高手解决超声波测距问题

/******************************************************
1 超声波的发射端口发出至少10us的高电平脉冲后,拉为低电平,等待接收端口发出低电平
2        定时器,外中断0清零初始化
3当检测到接收端口的高电平后,定时器开始计时,外中断也开始工作
4延时20ms左右后等待测量结果(经计算最远4米的距离测量时间也不超过20ms)
5当接收端口为低电平时关闭定时器,外中断
6计算距离,数码管显示
外中断0,当接收端口变为低电平时触发外中断,将定时器所记值取出来计算距离d(厘米)=0.017*t(计数器所记的数)
********************************************************/
#include<reg51.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
bit succeed_flag;   //测量成功与否的变量
uint timeH,timeL;
uchar bai,shi,ge;
uchar flag;                                  //扫描哪位数码管的变量
sbit TRIG=P3^3;                            //不能用P3^0与P3^1口,因为这两个口与串口通信有关系。
sbit ECHO=P3^2;
uchar code tab={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//0-9       
/**********************************************
20us的延时函数
**********************************************/
void delay_15us()
{
        _nop_();
        _nop_();
    _nop_();
        _nop_();
           _nop_();
        _nop_();
    _nop_();
        _nop_();
        _nop_();
        _nop_();
    _nop_();
        _nop_();
           _nop_();
        _nop_();
    _nop_();
       
}
/**********************************************
数据转换函数
**********************************************/
void date_change( uint distence_date)
{

        bai=tab;
        shi=tab[(distence_date%100)/10];
        ge=tab;

}
/**********************************************/
void main()
{
        uint distence;
        flag=0;
        TRIG=0;                //初始不能让ECHO为0
        TMOD=0X11; //采用定时器0 定时器1 的16位工作方式
        TR0=1;                //启动定时器0
        ET0=1;                //定时器0中断允许
        EX0=0;               //先关闭外中断
           IT0=0;      //低电平触发外部中断
        EA=1;
        while(1)
        {
               EA=0;
               TRIG=1;
               delay_15us();
               TRIG=0;          //由发射端发出15us的高电平脉冲
               while(ECHO==0);//如果接收端接收到超声波的返回就置位往下执行,否则就继续等待
               succeed_flag=0;//清零测量标志位       
               EX0=1;                  //打开外中断0
               TH1=0;
               TL1=0;                  //定时器1赋初值
               TR1=1;       //启动定时器1          没有用到T1的中断
               EA=1;                  //打开总中断
         while(TH1<50);//一段时间后,不管有没有测量成功都关闭定时器与外中断                              
               TR1=0;                  //关闭定时器
              EX0=0;                  //关闭外中断
               if(succeed_flag==1)
               {
                      distence=(timeH*256+timeL)*0.0172;
               }
               if(succeed_flag==0)
               {
                       distence=0;
               }
               date_change(distence);
        }               
}
/**********************************************
外中断0
**********************************************/
void out_time() interrupt 0
{

        timeH=TH1;
        timeL=TL1;              //先取出定时器1的值
    succeed_flag=1;          //成功标志位
        EX0=0;                         //关闭外中断

}
/**********************************************
定时器0 数码管显示
**********************************************/
void shumaguan_show() interrupt 1
{
       
        TH0=0Xf0;
        TL0=0Xf0;               
        switch(flag)
        {
                case 0:        P2=0X7F;P0=ge; flag++;break;
                case 1:        P2=0XbF;P0=shi;flag++;break;
                case 2:        P2=0XdF;P0=bai;flag=0;break;
        }

}





以上是我的测距程序,我的问题是(IT0=0;      //低电平触发外部中断)如果改为(IT1=1,下降沿触发外中断)时测距显示就不正常了,效果为模块正前方有障碍时,显示一下数据立马就变为显示0了,不改的话就能一直正常显示数据。这是为什么

lcw_swust 发表于 2012-11-26 10:18:26

EX0=1;                  //打开外中断0
此句之前加一句 IE0=0;

彼岸花开 发表于 2012-11-26 13:50:37

为什么要把IT0=0改为IT1=1呢?

1013850890 发表于 2013-1-10 21:18:46

下个看看

afei8856 发表于 2013-3-4 16:06:34

3楼问的对啊 为什么改成IT1呢?

宁采儿 发表于 2013-6-24 00:38:58

afei8856 发表于 2013-3-4 16:06 static/image/common/back.gif
3楼问的对啊 为什么改成IT1呢?

谢谢各位的指点,这个当时刚申请进入论坛,不知道回复的帖子怎么找到。不过这个后来早就调好了,后来我也把程序移植到AVR上面也能调通。再次感谢。
页: [1]
查看完整版本: 跪求高手解决超声波测距问题