基于51单片机的超声波测距设计(带温度补偿)

发布者:EternalBliss最新更新时间:2019-11-21 来源: 51hei关键字:51单片机  超声波测距  温度补偿 手机看文章 扫描二维码
随时随地手机看文章

利用STC89C52单片机、超声波模块(HC-RS04)、DS18B20数字温度传感器和LCD1602液晶显示模块制作一个超声波测距仪,液晶屏第一行显示温度和超声波速度“T:30°C  V:349m/s”,第二行显示测量距离“S=X.XXXm”。

所设计的测距仪测量单位为米,精确到小数点后面3位(毫米),测量范围:0.05m~5m。

(一)基本部分

1、液晶显示功能 

(1)开机时,液晶屏第一行显示温度和超声波速度,例如“T:30°C  V:349m/s”,第二行显示测量距离“S=0.000m”

(2)操作对应的功能按键时,液晶屏第一行显示温度和超声波速度,例如“T:30°C  V:349m/s”,第二行显示测量距离“S=X.XXXm”。

(3)本超声波测距仪使用4个独立按键。第1个按键为复位清零功能;第2个按键为单次测量功能;第3个按键为瞬时连续测量功能;第4个按键为平均连续测量功能。

(4)第1个按键为复位清零功能。无论什么时候按下该键,液晶屏第二行均显示测量距离“S=0.000m”

(5)第2个按键为单次测量功能。每按一次该键,就发射一次超声波,液晶屏第二行对应显示一次测量距离“S=X.XXXm”

(6)第3个按键为瞬时连续测量功能。按下该键,连续发射超声波,液晶屏第二行对应显示瞬时测量距离“S=X.XXXm”,再按一次该键,数字保持,以便读数

(7)第4个按键为平均连续测量功能。按下该键,连续发射超声波,液晶屏第二行对应显示平均测量距离“S=X.XXXm”,再按一次该键,数字保持,以便读数


(8)第5个按键为自动/手动温度设置按键,转换到手动设置温度值,这时可以利用加键和减键使温度在0度至50度范围内调节,再按一次该键,重新回到自动温控状态,如此循环。

(9)第6个按键为温度加按键,当处于手动温度控制状态时,按下本按键可以加温度,最高可以加到50摄氏度。

(10)第7个按键为温度减按键,当处于手动温度控制状态时,按下本按键可以减温度,最低可以减0摄氏度。


程序代码如下:

/**************************************/

/*   超声波测距(自动/手动温度校正)  */

/*   (超声波模块+18B20+1602液晶)    */

/**************************************/

#include

#include

#define uchar unsigned char 

#define uint unsigned int

#define LcdData P0                   //1602数据端口


sbit LCD_RS=P2^6;      //1602 RS端口

sbit LCD_RW=P2^5;      //1602 RW端口

sbit LCD_EN=P2^7;      //1602 EN端口

sbit Echo=P2^4;        //HC-SR04 接收端口

sbit Trig=P2^3;        //HC-SR04 发射端口

sbit Resets_Key=P1^0;  //复位清零按键

sbit Single_Key=P1^1;  //单次测量按键    误差较大 

sbit Contin_Key=P1^2;  //连续测量按键    误差小 

sbit Averag_Key=P1^3;  //连续(平均测量)按键   误差较小 

sbit Setting_Key=P1^4; //温度修正按键

sbit Add_Key=P1^5;     //温度加1按键

sbit Sub_Key=P1^6;     //温度减1按键

sbit DQ=P3^7;          //DS18B20单总线接口


bit Temp_Flag;         //正负温度标志:温度为正Temp_Flag=0,否则为1

uint temp=25;          //温度值

bit flag_flow=0,flag_one=0,flag_clear=0,flag_con1=0,flag_con2=0,flag_temp=0;

uchar i=0,m,j,k;

uint time=0,S=0,S1=0,totle=0;

float V=346.0;

uint Sav[11];                                                          //连续测量时10次平均值数组

uchar Line1[16]={"T:   C  V:346m/s"};          //1602第一行初始字符显示数组

uchar Line2[16]={"S=     m        "};          //1602第二行初始字符显示数组


void Delayms(uchar xms);                        //延时xms函数

void WriteLcd(uchar Dat,bit x);        //1602写函数

void InitLcd(void);                                //1602初始化函数

void DisplayLcd();                                //1602显示函数

void init();                                        //初始化函数

void keyscan();                                        //键扫描函数

void StartModule();                            //启动模块函数

void Conut(void);                                 //测量计算函数

void Delayus(uchar xus);        //us级延时函数

bit Init_DS18B20(void);         //初始化DS18B20函数

uchar Read_DS18B20(void);       //读DS18B20函数

void Write_DS18B20(uchar Dat);  //写DS18B20函数

void GetTemp();                 //取温度函数

void CalcTestTemp();            //温度处理函数


void main(void)    //主函数

{

        init();

        InitLcd();

        while(1)

        {

                keyscan();                         //键扫描函数

            DisplayLcd();

            if(flag_temp==0)

            {

                    GetTemp();

                    CalcTestTemp();

            }

            if(flag_one==1||flag_con1==1||flag_con2==1)

            {

                    StartModule();         //开始发射超声波

                while(!Echo);                 //当RX为零时等待

            TR0=1;                         //开启计数

            while(Echo);             //当RX为1计数并等待

                TR0=0;                         //关闭计数

            Conut();                 //计算

            Delayus(200);

                flag_one=0;

            }

        } 

}


void Delayms(uchar xms)   //延时ms函数

{

    uchar i,j;

    for(i=xms;i>0;i--)

            for(j=110;j>0;j--);

}


void WriteLcd(uchar Dat,bit x)  //1602写函数(写指令时x=0,写数据时x=1)

{

        LCD_EN=0;

        LcdData=Dat;

        LCD_RS=x;

        LCD_RW=0;

        LCD_EN=1;

        Delayms(1);

        LCD_EN=0;

}


void InitLcd(void)           //1602初始化函数

{

        WriteLcd(0x38,0);  //功能设定(38H),8位数据,2行显示,5*7点阵

        WriteLcd(0x0C,0);  //显示开、关设定(0CH),开显示,不显示光标,光标不闪烁

        WriteLcd(0x06,0);  //输入模式设定(06H),读写一个字符后,地址指针加1,且光标加1

        WriteLcd(0x01,0);  //清除显示(01H),清除数据RAM中的数据

}


void DisplayLcd()                                  //液晶屏显示函数

{

    uchar y;

    V=(331.4+temp*0.607);

    Line1[2]=temp/10+0x30;

    Line1[3]=temp%10+0x30;

    Line1[4]=0xDF;                  //显示℃中C前面的小圆

    Line1[10]=(uint)V/100+0x30;

    Line1[11]=(uint)V%100/10+0x30;

    Line1[12]=(uint)V%10+0x30;

    if(flag_clear==1)

    S1=0;

    if((S1>=7000)||flag_flow==1)    //超出测量范围显示“-”

        {         

            flag_flow=0;

            Line2[2]='-';

            Line2[3]='.';

            Line2[4]='-';

            Line2[5]='-';

            Line2[6]='-';

        }

    else

        {

            Line2[2]=S1/1000+0x30;

            Line2[3]='.';

            Line2[4]=S1%1000/100+0x30;

            Line2[5]=S1%100/10+0x30;

            Line2[6]=S1%10+0x30;

        }

    WriteLcd(0x80,0);               //设定第一行地址

    for(y=0; y<16; y++)

        WriteLcd(Line1[y],1);

    WriteLcd(0xc0,0);               //设定第二行地址

    for(y=0; y<16; y++)

        WriteLcd(Line2[y],1);

}


void init()        //初始化函数

{

    TMOD=0x01;        //设T0为方式1,GATE=1;

    TH0=0;

    TL0=0;          

    ET0=1; //允许T0中断

    EA=1;  //开启总中断

}


void keyscan()                         //键扫描函数

{

    if(Resets_Key==0)                         //复位清零键

    {

        Delayms(5);

        if(Resets_Key==0)

        {

                while(Resets_Key==0);

            flag_clear=1;

            }

    }

    if(Single_Key==0)                         //单次测量键

    {

        Delayms(5);

        if(Single_Key==0)

        {

                while(Single_Key==0);

                flag_one=1;

            flag_con1=0;

                flag_con2=0;

                flag_clear=0;

            }

    }

    if(Contin_Key==0)                         //连续瞬时测量键

[1] [2]
关键字:51单片机  超声波测距  温度补偿 引用地址:基于51单片机的超声波测距设计(带温度补偿)

上一篇:单片机舵机控制程序教程及proteus仿真原理图
下一篇:单片机+CXA1019S+锁相环BU2614数字式调频收音机设计

推荐阅读最新更新时间:2024-11-17 00:47

51单片机 定时器0中断实现LED流水灯
使用51单片机定时器0 方式1实现LED流水灯 代码: #include reg52.h typedef unsigned int u16; void timer0init() { TMOD=0x01; ET0=1; EA=1; TR0=1; TH0=64736/256; TL0=64736%256; } void main() { timer0init(); while(1); } void timer0() interrupt 1 { u16 i; TH0=64736/256; TL0=64736%256; i++; switc
[单片机]
51单片机最小系统的制作
因准备电子设计竞赛的需要重新制作了一套51单片机最小系统,现给出电路图和实物图供大家参考。 系统电路图如下,包括系统电源部分、89S52最小电路、ISP在线下载部分。实物与电路图稍有不同,仅供参考,有问题可在下面留言。 51单片机最小系统实物图: ISP下载线实物图:
[单片机]
<font color='red'>51单片机</font>最小系统的制作
51单片机PID的算法实现程序C语言
/* 用整型变量来实现PID算法,由于是用整型数来做的,所以也不是很精确,但是对于很多的使用场合,这个精度也够了, 关于系数和采样电压全部是放大10倍处理的.所以精度不是很高. 但是也不是那么低,大部分的场合都够了. 实在觉得精度不够, 可以再放大10倍或者100倍处理,但是要注意不超出整个数据类型的范围就可以了.本程序包括PID计算和输出两部分. 当偏差 10度全速加热,偏差在10度以内为PID计算输出. 具体的参考代码参见下面: */ //================================================================ // pid.H // Operation abou
[单片机]
51单片机并行接口P0~P3
前言 学习51单片机,IO口可以说是重中之重,在应用设计中应该理解,计算机内部是由数字电路组成的,只存在TTL电平,高电平3.5V~5V和低电平0V对应数字1和0,外设的状态输入要通过电路转换成高低电平,计算机才能识别。根据外设的需要的电平输出1或0,这就是程序控制外设的核心。 根据外设的需要的电平输出1或0,这就是程序控制外设的核心。 一、并行接口P0 ① 并口与数据存储器统一编址,作为数据存储器的特殊功能寄存器来访问,寄存器名分别为:P0、P1、P2、P3; ② P0、P1、P2、P3各对应8位双向I/O口,每个端口可以按字节输入或输出,也可以按位进行输入或输出,四个口共32根口线,用作位控制十分方便; ③ P0、
[单片机]
<font color='red'>51单片机</font>并行接口P0~P3
AT89C51单片机和SHT15传感器对湿度智能监控系统的设计
1引言 弹药从出厂到部队作战或训练使用以前主要存放在仓库中。在长期的储存过程中,弹药虽然处于宏观静止状态。但其质量不断发生变化。这是因为弹药主要由金属和装药组成.在长期储存过程中,由于温,湿度的影响。金属会锈蚀.从而使金属部件的强度降低。表面机械性能变坏,严重影响弹药的使用.甚至会造成重大事故。温,湿度还会使弹药装药的物理和化学性质发生变化.从而使其失去应有的战技要求。因此,温,湿度是弹药质量发生变化的主要矛盾。根据我军的仓库条件、我国的气候条件和目前仓库的管理水平.通常规定最高温度不超过30℃.最大湿度不超过。70%.即通常所说的“三七”线。 传统弹药仓库的监控系统采用的是干,湿球湿度计、毛发湿度计、湿敏电阻器或由普通的温,
[单片机]
AT89C<font color='red'>51单片机</font>和SHT15传感器对湿度智能监控系统的设计
MCS-51单片机的程序状态寄存器PSW有什么用?
PSW是一个8位寄存器,用于设定CPU的状态和指示指令执行后的状态。 CY(PSW.7):进位标志。在执行加减运算指令时,如果运算结果的最高位(D7)发生了进位或借位,则CY由硬件自动置1。 AC(PSW.6):半进位标志位,也称为辅助标志位。在执行加减运算指令时,如果运算结果的低半字节(D3)发生了向高半字节进位或借位,则AC由硬件自动置1。 F0、F1(PSW.5 和PSW.1):用户标志位。用户可以根据需要对F0、F1赋予一定的含义,由用户置1和清0,作为软件标志。 RS1、RS0(PSW.4 和PSW.3):工作寄存器组选择控制位。通过对这两位设定,可以从4个工作寄存器组中选择一组作为当前工作寄存器。
[单片机]
MCS-<font color='red'>51单片机</font>的程序状态寄存器PSW有什么用?
超声波测距原理
超声波传感器: 有触发控制端和echo接收端: 触发控制端每当输出一个大于10US的高电平就会驱动传感器发出8个40KHZ的超声波,实现电能-机械能-超声波转换。 ECHO接收端:通过测量接收端高电平的持续时间Th即可计算出离障碍物的距离。 distance=Th*340/2 实现方法: 将单片机的IO配置成输入边缘中断(上升沿和下降沿)同时利用定时器的输入捕获,分别在上升沿和下降沿触发捕获中断,从捕获寄存器中得到2次计数器的差值,差值*定时器定时周期=高电平的持续时间。
[单片机]
51单片机与PC通信总结
51单片机的串口,是个全双工的串口,发送数据的同时,还可以接收数据。 当串行发送完毕后,将在标志位 TI 置 1,同样,当收到了数据后,也会在 RI 置 1。 无论 RI 或 TI 出现了 1,只要串口中断处于开放状态,单片机都会进入串口中断处理程序。 在中断程序中,要区分出来究竟是发送引起的中断,还是接收引起的中断,然后分别进行处理。 常用的方法有: 接收数据时,使用“中断方式”,清除 RI 后,用一个变量通知主函数,收到新数据。 发送数据时,也用“中断方式”,清除 TI 后,用另一个变量通知主函数,数据发送完毕。 这样一来,收、发两者基本一致,编写程序也很规范、易懂。 更重要的是,主函数中,不用在那儿死等发送完毕,可以有更多
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved