超声测距调试中遇到的2个问题,求指导。

2019-03-24 18:53发布

我用的是网上典型的89C52单片机控制+74LS04驱动发射+CX20106接收的电路。焊接都没有问题,而且测距也能实现。但是一般最大能到5M,我只能测到2.2M现在有2个问题:

1.可能是驱动能力不够,那么04是两路(正负倒相后)各通过两个非门并联,输出电流加倍,提高功率,我测量到一路(正相输出)电路是80mA,另一路(负相)是0.1mA。

那么我想:我再加一个04,每路再并联3个非门,那是不是正相的电流就能达到150-250mA了呢?可是后来测量发现仍然是80mA,这是为什么?输出电流有限制?请指教。

2.情况如下:我开始以为是驱动能力不够,后来1CM,1CM的测量,发现当到220CM的时候,再远一点就会变成003,然后004,继续测量一直到030.那么相当于可以测到250CM。

说明不是因为能量不够导致测不到,而我觉得有可能是溢出了?程序方面我也找不出哪里不对。我贴出程序请大家指正:(程序是4位的,不过用不到10M所以就3位就可以了)
个人觉得是中断时间设置或者计算上有干扰导致重新计数了吗?(我也不清楚,只是初学单片机,中断等指令还不是很懂)

这是小生第一次发帖,之前看了版主的置顶贴,很有感触。虽然这次也是参考了网上各种资料,不过毕竟自己动手做出来,还是很有成就感的。但是没能把成品做得达到要求,仍有遗憾,所以希望各位能看看,指点迷津呐。期末考试后,再将自己的心得以及调试的各种问题跟大家分享,希望对之后做超声测距的同学有所帮助,在此谢过! 此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
5条回答
立志成为EEer
2019-03-25 00:39
#include<reg51.h>
#include<math.h>
/*定义数据类型*/
#define uint unsigned int
#define uchar unsigned char
/*定义系统常数*/
long int  time;      //    时间   
bit   CLflag;   //  测量标志
char  cshu;       // 脉冲个数
#define  T12us   (256-12)    //定时器设初值   T=(256-T12us)*12/12MHZ  
sbit VOLCK=P1^0;    // 发射
sbit MING=P3^2;     // 外部中断0检测接收信号  

sbit dp=P0^1 ;
sbit S1=P0^3;            //第一位数码管控制脚
sbit S2=P0^5;                //第二位数码管控制脚
sbit S3=P0^6;                //第三位数码管控制脚
sbit S4=P0^7;                //第四位数码管控制脚

char  idata   disp[9];       //   显示数据  
char  idata  shuju[5];      // 显示数据
char  code tabsm[] ={0x81,0xcf,0x92,0x86,0xcc,0xa4,0xa0,0x8f,0x80,0x84}; //送数码管数字0-9的编码

/*    通用延时子程序  */
void delay( int j)
{   
        int i;   
        for(i=0;i<j;)
                i++;
}

void display(void)     //  显示4位数据   
{
        P2=tabsm[shuju[1]];
        S1=0;
        delay(200);
        S1=1;
        P2=tabsm[shuju[2]];
        dp=0;
        S2=0;
        delay(200);
        S2=1;
        P2=tabsm[shuju[3]];
        S3=0;
        delay(200);
        S3=1;
        P2=tabsm[shuju[4]];
        S4=0;
        delay(200);
        S4=1;
}

/*  初始化定时器,CTC0、CTC1用于定时     */
void   init_CTC(void )
{
        TMOD = 0x21;      //  设CTC1工作于模式2
        ET0 = 0;              // 不允许CTC0中断  
}

void init_INT( )    //  外部中断初始化为高优先级,并开中断  
{
        IP=0x01;   //  置外部中断INT0优先级为高   
        TCON=0;   //  设置外部中断0的中断方式为电平触发  
}
/*   将测量的时间转换为距离 */
void Timetojuli(void)   
{
        long  i;
        i=(long)time*170;
        shuju[1]=i/10000000;  // 十米  
        i=i-shuju[1]*10000000;
        shuju[2]=i/1000000;   // 米  
        i=i-shuju[2]*1000000;
        shuju[3]=i/100000;    // 分米  
        i=i-shuju[3]*100000;
        shuju[4]=i/10000;     // 厘米  
}

        /*  外部中断0,用于检测接收信号  */
void serve_INT0( ) interrupt 0
{
        TR0=0;       //  关闭定时器0
        EX0=0;       // 关中断  
       
        time=(long)TL0;
        time+=(long)TH0*256;
        Timetojuli();                                        //更新一次数据
        CLflag=1;
        TH0=0;
        TL0=0;
}

void CTC0_INT (  )   interrupt  1
{
        TR0=0;
        ET0=0;
}

/*  CTC1中断服务程序,12.5us 中断一次,用于发射  */
void CTC1_INT (  )   interrupt  3
{
        VOLCK=~VOLCK;
        cshu++;
}

/*主程序*/
void main()
{
        int  i;
        init_CTC(  );                      //  初始化定时器
        init_INT(  );                      //  初始化外部中断  
        CLflag=1;                         //  测量标志   
        for(i=6;i>4;i--)
        disp=0xff;
        cshu=0;                          //  传数
        delay(200);             //  延时
        IE=0x80;                           //  开中断  
        ET1=1;       ET0=1;
        TR1=0;       TR0=0;
        TL1=T12us; TH1=T12us;
        while(1)
        {
                CLflag=0;
                cshu=0;
                EX0=0;
                TH1=T12us;
                TL1=T12us;
                TL0 = 0;     TH0 = 0;            //  定时器0的初始时间
                VOLCK=0;
                TR1=1;                                        //  启动定时器1,发送信号  
                while(cshu<3) ;                             //  发1个脉冲串                         
                TR1=0;
                TR0=1;                                   //  启动定时器0,开始记时  
                EX0=1;
                display();  
        }
}

一周热门 更多>