本帖最后由 电子哎嗨 于 2021-1-9 10:01 编辑
原创作品,禁止转载售卖,仅供学习参考!!! 功能说明: 1.本设计采用STC89C52单片机作为主控制器; 2.LCD1602液晶显示测量的距离和温度; 3.带有温度补偿功能(DS18B20传感器); 4.测量范围0.02m~4m,精度为0.01m; 5.带实时语音播报功能; 6.按键功能:按键2:加报警值按键3:减报警值按键1:设置按键(只有在按下设置的时候才可以加减报警值),在未按下按键1时,按下按键3播报测量距离。 需要设计实物请私聊~ 实物制作图:
原理图:
单片机源程序如下:- //宏定义
- #define uchar unsigned char
- #define uint unsigned int
- #define ULint unsigned long int
- //温度零上与零下的标志位
- char flag=0;
- //超声波
- char flags=0;
- //超声波距离
- char flag1s=0;
- //计算定时间
- uint time=0;
- //计算距离
- ULint L_=0;
- //温度
- uint t_=0;
- //显示模式 0正常 1最大值调整 2最小值调整
- uchar mode=0;
- uint Max=490;
- uint Min=10;
- //按键标志
- uchar k=0;
- //数值有误
- uchar FW=0;
- //头函数
- #include <reg52.h>
- #include <intrins.h>
- #include "BJ_Key.h" //报警按键
- #include "display.h" //显示头函数
- #include "ultrasonic_wave.h"//超声波头函数
- #include "DS18B20.h" //温度传感器头函数
- uchar ONE1[6]={0x7E,0x04,0x03,0x00,0X0D,0xEF};//现在距离为
- uchar ONE2[6]={0x7E,0x04,0x03,0x00,0X0C,0xEF};//米
- uchar ONE3[6]={0x7E,0x04,0x03,0x00,0X0B,0xEF};//点
- uchar ONE4[6]={0x7E,0x04,0x03,0x00,0X00,0xEF};//百位
- uchar ONE5[6]={0x7E,0x04,0x03,0x00,0X00,0xEF};//十位
- uchar ONE6[6]={0x7E,0x04,0x03,0x00,0X00,0xEF};//个位
- void delayms(uint ms)
- {
- uchar i=100,j;
- for(;ms;ms--)
- {
- while(--i)
- {
- j=10;
- while(--j);
- }
- }
- }
- /******** UART初始化 波特率:9600 ******/
- void UART_init(void)
- {
- SCON = 0x50; // 10位uart,允许串行接受
- TMOD = 0x20; // 定时器1工作在方式2(自动重装)
- TH1 = 0xFD;
- TL1 = 0xFD; //设置波特率为9600
- TR1 = 1;
- }
- /*
- * UART 发送一字节
- 入口参数uint8的数据类型 即要发送的数据
- */
- void UART_send_byte(uchar dat)
- {
- SBUF = dat;
- while (TI == 0);
- TI = 0;
- }
- /*
- * UART 发送字符串
- 第一个参数要发送字符串或数据的首地址
- 第二个参数是要发送的数据或字符串的长度
- */
- void UART_send_string(uchar *buf,uchar len)
- {
- uchar i;
- for(i=0;i<len;i++)
- UART_send_byte(*buf++);
- }
- //主函数
- void main()
- {
- UART_init();
- Init_ultrasonic_wave();
- //屏幕初始化
- Init1602();
- //温度初始化
- tmpchange();
- t_=tmp();
- tmpchange();
- t_=tmp();
- tmpchange();
- t_=tmp();
- //循环显示
- while(1)
- {
- Key();
- if(yuyin_flag==1)
- {
- yuyin_flag=0;
- ONE4[4]=L_/100;
- ONE5[4]=L_/10%10;
- ONE6[4]=L_%10;
- if(ONE4[4]==0)ONE4[4]=0x0A;
- if(ONE5[4]==0)ONE5[4]=0x0A;
- if(ONE6[4]==0)ONE6[4]=0x0A;
-
- UART_send_string(ONE1,6);
- delayms(1);
- UART_send_string(ONE4,6);
- delayms(1);
- UART_send_string(ONE3,6);
- delayms(1);
- UART_send_string(ONE5,6);
- delayms(1);
- UART_send_string(ONE6,6);
- delayms(1);
- UART_send_string(ONE2,6);
- delayms(1);
- }
- //正常显示
- if(mode==0)
- {
- StartModule();//启动超声波
- while(!RX); //当RX为零时等待
- TR0=1; //开启计数
- while(RX); //当RX为1计数并等待
- TR0=0; //关闭计数
-
- delayms(20); //20MS
- tmpchange(); //温度转换
- t_=tmp(); //度温度
- Conut(t_/10); //计算距离
- if(L_>Max||L_<Min)
- {
- Feng_Start();
- }
- else
- {
- if(FW!=1)
- Feng_Stop();
- }
- Display_1602(t_/10,L_);
- }
- //调整显示
- else if(mode!=0)
- {
- //最大最小值
- Init_MaxMin();
- while(mode!=0)
- {
-
- Key();
- if(k==1&&mode==1)
- {
- Init_MaxMin();
- write_com(0x8d);//设置位置
- }
- else if(k==1&&mode==2)
- {
- Init_MaxMin();
- write_com(0x8d+0x40);//设置位置
- }
- k=0;
- }
- //界面初始化
- Init1602();
- }
- }
- }
- //T0中断用来计数器溢出,超过测距范围
- void CJ_T0() interrupt 1
- {
- flags=1; //中断溢出标志
- }
复制代码
|