找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 7886|回复: 8
打印 上一主题 下一主题
收起左侧

超声波 测距 1602显示 亲测可用 接线为普中科技

[复制链接]
跳转到指定楼层
楼主
ID:183197 发表于 2017-4-8 13:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include<reg52.h>   
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit rs=P2^6;            //1602的数据/指令选择控制线
sbit rw=P2^5;           //1602的读写控制线
sbit en=P2^7;          //1602的使能控制线
sbit trig=P1^0;      //超声波测距模块Trig
sbit echo=P1^1;     //超声波测距模块Echo
bit flag1;         //触发信号标志位//
uchar count;           //中断累加变量
long int distance;    //测量所得距离
unsigned char code table[ ]={"0123456789"}; //定义字符数组显示数字
/*------------------------------------------------
                  延时函数
------------------------------------------------*/
void delay(uint n)                           
{
    uint x,y;  
    for(x=n;x>0;x--)
    for(y=110;y>0;y--);
}

/*------------------------------------------------
                  延时函数
------------------------------------------------*/
void delayt(uint x)
{
    uchar j;
    while(x-- > 0)
    {
              for(j = 0;j < 125;j++)
        {
          ;
        }
    }
}

/*------------------------------------------------
                1602写命令函数
------------------------------------------------*/
void lcd_wcom(uchar com)            
{
    rs=0;                //选择指令寄存器
    rw=0;               //选择写
    P0=com;            //把命令字送入P0
    delay(5);         //延时一小会儿,让1602准备接收数据
    en=1;            //使能线电平变化,命令送入1602的8位数据口,这点非常重要
    en=0;
}

/*------------------------------------------------
               1602写数据函数   
------------------------------------------------*/
void lcd_wdat(uchar dat)        
{
    rs=1;             //选择数据寄存器
    rw=0;            //选择写
    P0=dat;         //把要显示的数据送入P0
    delay(5);      //延时一小会儿,让1602准备接收数据,也就是检测忙信号,这点非常重要。
    en=1;         //使能线电平变化,数据送入1602的8位数据口
    en=0;
  }

/*------------------------------------------------
                1602初始化函数      
------------------------------------------------*/
void lcd_init()              
{
    lcd_wcom(0x38);       //8位数据,双列,5*7字形  ,用到功能设定指令     
    lcd_wcom(0x0c);      //开启显示屏,关光标,光标不闪烁,用到显示开关控制指令
    lcd_wcom(0x06);     //显示地址递增,即写一个数据后,显示位置右移一位,用到了写入模式设置指令
    lcd_wcom(0x01);    //清屏,用到了清屏指令
}

/*------------------------------------------------
              1602显示固定字符函数      
------------------------------------------------*/
void lcd_xianshi()              
{
    lcd_wcom(0x80+0x40);
        lcd_wdat('D');
        lcd_wdat('i');
        lcd_wdat('s');
        lcd_wdat('t');
        lcd_wdat('a');
           lcd_wdat('n');
        lcd_wdat('c');
        lcd_wdat('e');
        lcd_wdat(':');
        lcd_wcom(0x80+0x4c);
        lcd_wdat('.');
        lcd_wcom(0x80+0x4e);//单位是厘米//
        lcd_wdat('c');
        lcd_wdat('m');
}

/*------------------------------------------------
定时器0初始化,用于计算响应信号时间
------------------------------------------------*/
void init_t0()
{
        TMOD=0x01;         
         TL0=0x66;
        TH0=0xfc;              //1ms
    ET0=1;            
        EA=1;                     
}

/*------------------------------------------------
    超声波模块触发信号
------------------------------------------------*/
void trigger()
{
    trig=1;
        delayt(1);
        trig=0;        
}

/*------------------------------------------------
   超声波模块相应端口初始化函数
------------------------------------------------*/
void init_measuring()
{
        trig=0;
        echo=0;
        count=0;
}

/*------------------------------------------------
     超声波模块距离测试函数
------------------------------------------------*/
void measuring()
{
        uchar l;
        uint h,y;
        TR0 = 1;
        while(echo)
    {
        ;
    }        
        TR0 = 0;
        l = TL0;
        h = TH0;
        y = (h << 8) + l;
        y = y - 0xfc66;//us部分
        distance = y + 1000 * count;//计算总时间,单位是微秒
        TL0 = 0x66;
        TH0 = 0xfc;
        delayt(30);
        distance = 3453* distance / 20000;//原始为:(0.34毫米/us)*时间/2//        
}

/*------------------------------------------------
   超声波模块测量结果显示函数
------------------------------------------------*/
void display(uint x)
{
        uchar qian,bai,shi,ge;
        qian=x/1000;
        bai=(x/100)%10;
        shi=(x/10)%10;
        ge=x%10;
        lcd_wcom(0x80+0x49);//单位是厘米//
        lcd_wdat(table[qian]);
        lcd_wdat(table[bai]);
        lcd_wdat(table[shi]);
        lcd_wcom(0x80+0x4d);
        lcd_wdat(table[ge]);
}
/*------------------------------------------------
              主函数
------------------------------------------------*/
void main()            
{   lcd_init();          //液晶初始化        
    init_t0();          //定时器0初始化   
        init_measuring();  //超声波相应端口初始化

        while(1)
        {
        lcd_xianshi();   //液晶显示特定字符
        trigger();      //触发超声波启动
                 while(echo==0)          //等待回声
         {
           ;
         }
                 measuring();           //进行距离测量
                 display(distance);    //对测量结果进行显示
                 init_measuring();    //超声波相应端口初始化
                 delayt(600);        //每次测量间隔60ms
        }
}

//……………………………………………中断服务函数…………………………………………………//
void T_0()interrupt 1
{
        TF0 = 0;
        TL0 = 0x66;
        TH0 = 0xfc;
        count++;
        if(count==18)
        {
          TR0 =0;
          TL0 = 0x66;
          TH0 = 0xfc;
          count = 0;
        }
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:82765 发表于 2017-4-8 14:35 | 只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

板凳
ID:87420 发表于 2017-4-9 23:14 | 只看该作者
cjjcjj1 发表于 2017-4-8 14:35
谢谢分享,测量距离最大是多少呢?

这个要看你的超声波模块了,实际所能测得距离你可以看程序T0中断那里,中断最多执行18次(count计数18次),然后换算出最长的有效收发时间,就能算出实际最远距离了,我用这个程序最多309....cm,310cm没出现过,如果超声波模块好一些,可以把中断执行次数增加一些
回复

使用道具 举报

地板
ID:87420 发表于 2017-4-9 23:16 | 只看该作者
为了显示更快一些,可以把main函数里面最后的60ms改小一些,可以确保数据更即时,更灵敏测距。如果是小车测距的话,可以硬件添加一个蜂鸣器,当distance<100(10cm)时,beep=0;蜂鸣器响
回复

使用道具 举报

5#
ID:183197 发表于 2017-4-11 22:10 | 只看该作者
小猴子卡勒 发表于 2017-4-9 23:16
为了显示更快一些,可以把main函数里面最后的60ms改小一些,可以确保数据更即时,更灵敏测距。如果是小车测 ...

谢谢,我是刚刚学的小白。
回复

使用道具 举报

6#
ID:318045 发表于 2018-4-28 15:59 | 只看该作者
请问这个是多少的晶振?
回复

使用道具 举报

7#
ID:280132 发表于 2018-4-28 18:57 | 只看该作者
谢谢大神,可以用。
回复

使用道具 举报

8#
ID:547254 发表于 2019-5-25 23:14 | 只看该作者
小猴子卡勒 发表于 2017-4-9 23:16
为了显示更快一些,可以把main函数里面最后的60ms改小一些,可以确保数据更即时,更灵敏测距。如果是小车测 ...

怎么加?
回复

使用道具 举报

9#
ID:730886 发表于 2020-6-27 09:42 | 只看该作者
LCD1602中,字符可以显示出来,但是距离的数值显示不出来
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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