全套51单片机超声波液位仪资料,含程序、仿真、PCB文件,做出来的实物能实现功能。利用超声波测液位,用LCD1602现实,带温度补偿,带报警指示。PCB蜂鸣器处忘加驱动,电流不够,声音不够大,可换成灯。
初始零液位距离为15CM,报警液位为低于5CM,低于5CM时大灯点亮。
如需要校准改变零液位:
点击设置,设置指示灯亮起
点击液位归零
再次点击设置,指示灯熄灭,开始正常工作。
如需改变报警液位:
点击设置
点击加或者减
换位可以改变按加减时改变个位还是十分位的值,默认为十分位。
仿真说明:
仿真需要先校准归零。
如第一次仿真失败,方法如下:
停止仿真;
双击MCU,出现对话框;
点击program file栏目后的文件夹图标,出现文件选择框;
选择chengxu--output--双击HC-SR04.hex
点击确定
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
Altium Designer画的原理图和PCB图如下:(51hei附件中可下载工程文件)
单片机源程序如下:
- #include "config.h"
- #include "Lcd1602.h"
- #include "Ultrasonic.h"
- #include <reg52.h>
- uint8 flag; //定义定时标志
- uint16 set_s; //设定值
- uint16 lv_0; //零位
- uint16 length;
- uint16 lv_n;
- bit flag1s = 0; //1s定时标志
- bit fusu = 0; //1s定时标志
- bit setflag= 0; //进入设置模式标志
- bit changewei=0;
- unsigned char T0RH = 0; //T0重载值的高字节
- unsigned char T0RL = 0; //T0重载值的低字节
- //
- void ConfigTimer0(unsigned int ms);
- unsigned char IntToString(unsigned char *str, int dat);
- extern bit Start18B20();
- extern bit Get18B20Temp(int *temp);
- sbit led=P2^0;
- sbit bz=P1^5;
- sbit k3=P1^7; //更换十位和百位
- sbit k1=P3^0; //加
- sbit k2=P3^1; //减
- sbit k4=P1^6; //设置零位
- void ShowDistance();
- void ShowSets();
- void delayms(unsigned int ms);
- /* 主函数 */
- void main()
- {
- bit res;
-
- int temp; //读取到的当前温度值
- int intT, decT; //温度值的整数和小数部分
- unsigned char len;
- unsigned char str[12];
- set_s=50;//mm
- lv_0=150;//mm
- EA = 1; //开启总中断
- TMOD &= 0Xf0;
- TMOD |= 0X01; //设置T0为方式1
- TH0 = 0xFC; //为T0赋初值0xFC67,定时1ms
- TL0 = 0x67;
- ET0 = 1; //使能T0中断
- TR0 = 1; //启动T0
- IT0=1; //设置外部中断0的触发方式为下降沿
- EX0=1; //开启外部中断
- InitUltrasonic(); //超声波模块初始化
- InitLcd1602(); //1602初始化
- Start18B20(); //启动DS18B20
- LcdShowStr(0, 0,"SETD:"); //显示距离单位
- LcdShowStr(0, 1,"LV:"); //显示距离单位
- LcdShowStr(10, 1,"T:"); //显示距离单位
- k1=1;
- while(1)
- {
- if(flag == 1)
- {
- flag = 0;
- ShowSets();
- ShowDistance();
- if (1) //每秒更新一次温度
- {
- res = Get18B20Temp(&temp); //读取当前温度
- if (res) //读取成功时,刷新当前温度显示
- {
- intT = temp >> 4; //分离出温度值整数部分
- decT = temp & 0xF; //分离出温度值小数部分
- len = IntToString(str, intT); //整数部分转换为字符串
- str[len++] = '.'; //添加小数点
- decT = (decT*10) / 16; //二进制的小数部分转换为1位十进制位
- str[len++] = decT + '0'; //十进制小数位再转换为ASCII字符
- while (len < 6) //用空格补齐到6个字符长度
- {
- str[len++] = ' ';
- }
- str[len] = '\0'; //添加字符串结束符
- LcdShowStr(12, 1, str); //显示到液晶屏上
- }
- else //读取失败时,提示错误信息
- {
- LcdShowStr(12, 1, "error!");
- }
- Start18B20(); //重新启动下一次转换
- }
- }
- while(setflag){//按下设置键,进入设置模式,循环直到再一次按下设置键
- if(k1==0) //检测按键K1是否按下
- {
- delayms(5); //消除抖动 一般大约10ms
- if(k1==0) //再次判断按键是否按下
- {
- if(changewei==0)set_s++;
- else set_s+=10;
- }
- while(!k1); //检测按键是否松开
- }
- if(k2==0) //检测按键K1是否按下
- {
- delayms(5); //消除抖动 一般大约10ms
- if(k2==0) //再次判断按键是否按下
- {
- if(changewei==0)set_s--;
- else set_s-=10;
- }
- while(!k2); //检测按键是否松开
- }
- if(k3==0) //检测按键K1是否按下
- {
- delayms(5); //消除抖动 一般大约10ms
- if(k3==0) //再次判断按键是否按下
- {
- changewei=~changewei;
- }
- while(!k3); //检测按键是否松开
- }
- if(k4==0) //检测按键K1是否按下
- {
- delayms(5); //消除抖动 一般大约10ms
- if(k4==0) //再次判断按键是否按下
- {
- lv_0=length;
- }
- while(!k4); //检测按键是否松开
- }
- ShowSets();
- }
- if(lv_n>set_s) bz=1;
- else bz=0;
- }
- }
- unsigned char IntToString(unsigned char *str, int dat)
- {
- signed char i = 0;
- unsigned char len = 0;
- unsigned char buf[6];
-
- if (dat < 0) //如果为负数,首先取绝对值,并在指针上添加负号
- {
- dat = -dat;
- *str++ = '-';
- len++;
- }
- do { //先转换为低位在前的十进制数组
- buf[i++] = dat % 10;
- dat /= 10;
- } while (dat > 0);
- len += i; //i最后的值就是有效字符的个数
- while (i-- > 0) //将数组值转换为ASCII码反向拷贝到接收指针上
- {
- *str++ = buf[i] + '0';
- }
- *str = '\0'; //添加字符串结束符
-
- return len; //返回字符串长度
- }
- /* 执行测距并显示结果 */
- void ShowDistance()
- {
- uint8 i;
- uint8 buff[4];
- uint8 buff2[5];
- uint16 Distance ; //暂存距离值
- Distance = GetDistance();
- length = Distance;//mm
- if (Distance < lv_0)
- {
- Distance = lv_0-Distance;
- lv_n= Distance;
- fusu=0;
- }
- else
- {
- Distance =Distance- lv_0;
- lv_n=0;
- fusu=1;
- }
- if((Distance<999)&&(fusu==0)){
- buff[3] = Distance%10 + '0'; //将数据转换为字符形式
- buff[2] ='.';
- buff[1] = (Distance/10)%10 + '0';
- buff[0] = (Distance/100)%10 + '0';
- for(i = 0; i <= 0; i++) //整数部分高位的0转换为空白符
- {
- if(buff[i] == '0') //判断是不是字符0
- buff[i] = ' '; //将字符0 转换为空格 即不显示
- else
- break;
- }
- LcdShowStr(3, 1, &buff); //显示距离值
- LcdShowStr(7, 1, "cm"); //显示距离单位
- }
- if((Distance<99)&&(fusu==1)){
- buff[3] =' '; //将数据转换为字符形式
- buff[2] =Distance%10 + '0';
- buff[1] ='.';
- buff[0] = (Distance/10)%10 + '0';
- // for(i = 0; i <= 0; i++) //整数部分高位的0转换为空白符
- // {
- // if(buff[i] == '0') //判断是不是字符0
- // buff[i] = ' '; //将字符0 转换为空格 即不显示
- // else
- // break;
- // }
- LcdShowStr(3, 1, "-"); //显示距离单位
- LcdShowStr(4, 1, &buff); //显示距离值
- LcdShowStr(7, 1, "cm"); //显示距离单位
- }
- if(Distance>999||((Distance>99)&&(fusu==1))){
- LcdShowStr(3, 1, "ERROR"); //显示距离单位
- // else {
- // buff2[4] = Distance%10 + '0'; //将数据转换为字符形式
- // buff2[3] ='.';
- // buff2[2] = (Distance/10)%10 + '0';
- // buff2[1] = (Distance/100)%10 + '0';
- // buff2[0] = (Distance/1000)%10 + '0';
- // for(i = 0; i <= 3; i++) //整数部分高位的0转换为空白符
- // {
- // if(buff2[i] == '0') //判断是不是字符0
- // buff2[i] = ' '; //将字符0 转换为空格 即不显示
- // else
- // break;
- // }
- // LcdShowStr(3, 1, &buff2); //显示距离值
- // LcdShowStr(8, 1, "cm"); //显示距离单位
- // }
- }
- }
- void ShowSets()
- {
- uint8 i;
- uint8 buff[4];
- if(set_s>999)set_s=999;
- buff[3] = set_s%10 + '0'; //将数据转换为字符形式
- buff[2] ='.';
- buff[1] = (set_s/10)%10 + '0';
- buff[0] = (set_s/100)%10 + '0';
- for(i = 0; i <= 3; i++) //整数部分高位的0转换为空白符
- {
- if(buff[i] == '0') //判断是不是字符0
- buff[i] = ' '; //将字符0 转换为空格 即不显示
- else
- break;
- }
- LcdShowStr(6, 0, &buff); //显示距离值
- LcdShowStr(10, 0, "cm"); //显示距离单位
- }
- /* 定时器0中断服务函数 */
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei附件下载:
超声波液位仪.7z
(131.92 KB, 下载次数: 130)
|