找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6831|回复: 1
收起左侧

基于59c52RC单片机的超声波测距程序 已更新

[复制链接]
ID:143793 发表于 2016-12-27 21:17 | 显示全部楼层 |阅读模式
程序更新//2016年12月27日21点
修复bug
程序更新//2016年12月26日23点
修复闪烁问题
增加开机初始化显示-AA-
增加超声波模块检测  未收到信号时显示-EE-
距离异常显示----更改为-EE-
如大家发现bug记得给我留言!!

源文件还未更新

交流群中有源文件免费下载往下看群号

   
也不能完全说是原创 别人都做烂了
第一次在数码之家发帖支持下哦
文章最后有程序源文件
可直接下载到单片机接上模块使用
上电一直扫描 距离并显示出来
因为我用的模块是必须一直扫描才能显示
所以测远距离时候会一闪一闪的
程序限制4-300CM测量距离实际上最长可达到5.7M
具体修改限制的方法可留言问我
技术交流群533743590新群求zhichi么么哒

图片

QQ图片20161223222850.jpg
QQ图片20161223222859.jpg
QQ图片20161223222906.jpg
数码管模块简介

1.采用2片595驱动数码管,需要单片机3路IO口,根据数码管动态扫描原理进行显示;

2.宽工作电压3.3V到5V;

3.PCB板尺寸:71mm*22mm

4.数码管型号:0.36 4位共阳


超声波模块简介

接线方式,VCC、trig(控制端)、  echo(接收端)、 GND地线

本产品使用方法:一个控制口发一个10US以上的高电平,就可以在接收口等待高电平输出.一有

输出就可以开定时器计时,当此口变为低电平时就可以读定时器的值,此时就为此次测距的时间,

方可算出距离.如此不断的周期测,就可以达到你移动测量的值了~~

模块工作原理:
(1)采用IO触发测距,给至少10us的高电平信号;

(2)模块自动发送8个40khz的方波,自动检测是否有信号返回;

(3)有信号返回,通过IO输出一高电平,高电平持续的时间就是

超声波从发射到返回的时间.测试距离=(高电平时间*声速(340M/S))/2


代码区

/*



*************街角卖幸福原创****************************
*************转载请注明出处*****************************
----------技术交流群533743590-------------------------
------------本人QQ1979466583------------------------
对应接线
数码管模块 型号【HC595驱动的8位数码管】
SCLK-P1.2
RCLk-P1.1
DIO-P1.0
超声波模块 型号【HC-SR04】
echo--P3.2
trig--P3.3

*/
#include <AT89X51.H>                                                                //头文件

unsigned char code fseg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned char code segbit[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
unsigned char  disbuf[8]={0,0,0,0,0,0,0,0};


//-----------------------------------------------------------------------------
// 函数原形定义
#define uchar unsigned char
#define uint unsigned int

void main (void);                    // 主函数
void LED4_Display (void);            // LED显示
void LED_OUT(uchar X);                // LED单字节串行移位函数
void delayms(uint);                    //延时子函数 ms
void jisuan(void);

unsigned char code LED_0F[];        // LED字模表

sbit DIO=P1^0;                //串行数据输入
sbit RCLK=P1^1;                //时钟脉冲信号——上升沿有效
sbit SCLK=P1^2;                //打入信号————上升沿有效
sbit echo=P3^2;                                                    //echo
sbit trig=P3^3;                                                    //trig



//-----------------------------------------------------------------------------
// 全局变量
uchar LED[8];    //用于LED的8位显示缓存
uint temp;                                                                                       
uint temp1;
uint a,b;                                                            //定义一个变量a,b  后者用于判断是否收到信号
//
// 主程序
//
void main(void)                                        //主函数开始
{   
        uint f;
    echo=0;                                            //先拉低echo,trig引脚
    trig=0;
        f=500;
    while(f>0);                                        //启动延时  消除第一次上电产生的波动
        {
           LED[3]=16;
      LED[2]=15;
      LED[1]=15;
      LED[0]=16;
         f--;
       }
    EA=1;                                            //开总中断
    TMOD=0x11;                                        //设置定时器为方式1
    ET0=1;        //允许定时器中断  这里主要是防止超声波模块未发送信号
    ET1=1;
    while(1)
    {
        echo=0;//a赋值
        a=0;        
        b=1;
        TH0=0;                                        //定时器装初值
        TL0=0;
        TH1=(65536-25000)/256;                        //定时器装初值
        TL1=(65536-25000)%256;
        trig=1;                                        //trig送高
        LED4_Display ();                                //    延时3ms
        LED4_Display ();
        LED4_Display ();
        LED4_Display ();
        LED4_Display ();
        LED4_Display ();
        LED4_Display ();
        trig=0;                                                                                   //trig送低
        TR1=1;
        while(echo==0);                                    //等待echo变为高电平
                if(b==1)                                                                                  判断是否收到信号
        {
                                                               
            TR1=0;                                        //关定时器1
            EX0=1;                                        //开外部中断
            TR0=1;                                        //启动定时器
            while(a==0);                                    //注意这里!    前面给a赋0 程序停在这里等待中断
//本来是在这里加上扫描屏幕程序的  发现有重大BUG索性删除  
        }
        else
        {
        
            LED[3]=16;
            LED[2]=15;
            LED[1]=15;
            LED[0]=16;
        LED4_Display ();
        LED4_Display ();
        LED4_Display ();
        LED4_Display ();
        LED4_Display ();
        LED4_Display ();

        
        }
    }
}
void waibu() interrupt 0                                //外部中断服务子程序
{
    temp=TH0;                                    //取出定时器的值
    temp1=TL0;                                                                                    
    EX0=0;                                        //关闭外部中断
    TR0=0;                                        //关闭定时器
    jisuan();                                        //运行计算子程序
    a=1;                                            //a赋值1    程序回到刚才的  while(a)  中因为a的值已变为1,程序从头开始
}
void time1() interrupt 1                                  //定时器中断服务子程序
{
    TH0=0;                                        //重装初值
    TL0=0;
}

void time2() interrupt 3
{
    TR1=0;
    TH0=(65536-25000)/256;                        //定时器装初值
    TL0=(65536-25000)%256;
    b=0;
    echo=1;
   
}
void jisuan(void)                                    //计算子程序
{
    uint c,d;                                        //定义一个变量c,d 用来判断距离
    c=0;                                            //赋值0
    d=0;                                         //给b重新赋值
    LED4_Display ();                                //扫描一下数码管
    temp=(temp<<8)+temp1;                            //TH0 TL0合并
    temp=temp/5;                                    //我没有精确计算 直接除5得出大概值
   
    if(temp>40)                                    //判段距离是否过近
        {
            c=1;
        }
        LED4_Display ();                            //扫描一下数码管
    if(temp<40)
        {
         c=0;
        }
        LED4_Display ();
        if(temp<3000)                                            //判断距离是否过远
        {
            d=1;
        }
        LED4_Display ();
    if(temp>3000)
        {
         d=0;
        }
    c=c&d;                                                //与运算
    if(c==1)                                                //判断距离是否正常
        {
                                                            
            LED[3]=temp/1000;                                //数值分离显示
            LED[2]=temp%1000/100;
            LED[1]=(temp%1000%100/10)+20;    //这个为什么要加上20呢?  因为这是个位  需要显示小数点  
            LED[0]=temp%1000%100%10;
        }
    if(c==0)                                            //判断距离是否正常
        {
   
            LED[3]=16;
            LED[2]=14;
            LED[1]=14;
            LED[0]=16;
        }
   
}
void delayms(uint xms)                    //延时子函数 ms
    {
        uint i,j;
        for(i=xms;i>0;i--)
            for(j=110;j>0;j--);
    }
   
    //下面的程序是hc595模块显示程序
    //每个模块的程序可以到资料的例程中移植
    //*******************************************************//
void LED4_Display (void)                                //屏幕扫描子函数   

{
    unsigned char code *led_table;          // 查表指针
    uchar i;
    //显示第1位
    led_table = LED_0F + LED[0];
    i = *led_table;

    LED_OUT(i);            
    LED_OUT(0x01);        

    RCLK = 0;
    RCLK = 1;
    //显示第2位
    led_table = LED_0F + LED[1];
    i = *led_table;

    LED_OUT(i);        
    LED_OUT(0x02);        

    RCLK = 0;
    RCLK = 1;
    //显示第3位
    led_table = LED_0F + LED[2];
    i = *led_table;

    LED_OUT(i);            
    LED_OUT(0x04);   

    RCLK = 0;
    RCLK = 1;
    //显示第4位
    led_table = LED_0F + LED[3];
    i = *led_table;

    LED_OUT(i);            
    LED_OUT(0x08);        

    RCLK = 0;
    RCLK = 1;

}

void LED_OUT(uchar X)
{
    uchar i;
    for(i=8;i>=1;i--)
    {
        if (X&0x80) DIO=1; else DIO=0;
        X<<=1;
        SCLK = 0;
        SCLK = 1;
    }
}
//下面是显示数组
unsigned char code LED_0F[] =
{// 0      1       2       3     4      5       6       7     8      9       A       b     C    d      E    F     -        .
    0xc0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x8C,0xBF,0xC6,0xA1,0x86,0x8e,0xbf,0x7f,0x00,0x00,
//    20    21     22   23   24   25   26    27   28  29   30
    0x40,0x79,0x24,0x30,0x19,0x12,0x12,0x78,0x00,0x10,0xbf,
};

回复

使用道具 举报

ID:158248 发表于 2016-12-28 09:31 来自触屏版 | 显示全部楼层
很好的东西,自己尝试做一个
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表