标题:
蓝桥杯单片机超声波测距报警实时时钟电路电路具体功能与程序
[打印本页]
作者:
njz123
时间:
2023-4-25 14:26
标题:
蓝桥杯单片机超声波测距报警实时时钟电路电路具体功能与程序
要求:1. 电路通电后进入初始化状态:灯L1亮,数码管全亮,蜂鸣器接通,1s后全部关闭,显示时间设定11-50-59。2. 按下S7按键切换显示实时时钟XX-XX-XX、显示超声波测量距离XXX。3. 显示实时时钟状态下,按S6按键进行时间调整,第一次按下S6进入时调整, “时”闪烁;第二次按下S6进入分调整,“分”闪烁。再一次按下退出调整。S4、S5为调节数值S5+,S4-(时间距离)的加减按键。4. 显示超声波测距状态下,按S6按键进行报警距离调整,S6按第一次进入调整状态,第二次按下退出,将调节后的数值保存到24C02中。S4、S5为调节数值S5+,S4-(时间距离)的加按键。显示超声波报警距离--XXX。5. 超声波测距报警初值设定为30cm,超声波检测超过设定值X不报警,小于X立即报警,小于1.2倍的X, L1灯闪烁。6. 设计一个欠压电路,12V供电,电压小于10V切断电路电源。
单片机源程序如下:
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#include"dsp.h" //显示函数头文件
#include"1302.h"
#include"chaoshenbo.h"
#include"iic.h"
sbit s7=P3^0; //按键
sbit s6=P3^1;
sbit s5=P3^2;
sbit s4=P3^3;
uint sec_add; //中断1秒标志
bit sec_flag;
uint sec_szadd;
bit sec_szflag;
uchar bj_jl; //报警距离
uint ss; //距离函数
uchar sz_time[3];
uchar ms_add; //模式标志位
bit ms_flag;
bit ms_HCflag; //测距模式下 设置与正常显示的标志位 为0时正常显示距离 为1时设置报警距离
void int_t0(); //定时器T0、T1初始化
void open_led1();
void cls_led1();
void open_beep();
void cls_beep();
void int_sd(); //上电初始化
void moshi(); //正常显示模式
void sz_moshi(); //设置时间时的显示模式
void szHC_moshi(); //设置报警距离时的显示模式
void key_s7(); //s7功能按钮,设置时间模式或者距离模式
void key_s6_time(); //s6设置时间模式功能按钮
void key_s6_HC(); //s6设置距离模式功能按钮
void jiaohu(); //功能交互函数
void main()
{
int_t0(); //定时器初始化
int_sd(); //上电初始化
int_1302(); //初始化1302
// bj_jl=30; //设置报警距离 第一次写入程序时要把这两行屏蔽的恢复 然后再屏蔽掉再写入
// w_iic(0x00,bj_jl); //将报警距离写入24C02
bj_jl=r_iic(0x00); //从24C02中读取报警距离
while(1)
{
red_1302(); //读取1302时间
if(sec_flag) //1s读取一次超声波距离
{
ss=red_HC();
sec_flag=0;
}
key_s7(); //s7按键功能
jiaohu(); //功能交互
if(ss<bj_jl) //报警函数
{
open_beep();
}
else
{cls_beep();}
if(ss<(uint)(bj_jl*1.2)) //小与1.2倍距离时led1闪烁
{
if(sec_szflag)
open_led1();
else
cls_led1();
} else cls_led1();
}
}
void t0() interrupt 1
{
TH0=(65535-1000)/256;
TL0=(65535-1000)&256;
sec_add++; //1秒后sec_flag标志位置1
if(sec_add==200)
{
sec_add=0;
sec_flag=1;
}
sec_szadd++;
if(sec_szadd==1000)
{
sec_szadd=0;
sec_szflag=~sec_szflag;
}
display();
}
void int_t0()
{
TMOD=0X11;
EA=1;
ET0=1;
TH0=(65535-1000)/256;
TL0=(65535-1000)&256;
TH1=0;
TL1=0;
TR0 = 1; //定时器0开始计时
}
void open_led1()
{
P2=(P2&0x1f)|0x80;
P0=0x7f;
P2&=0x1f;
}
void cls_led1()
{
P2=(P2&0x1f)|0x80;
P0=0xff;
P2&=0x1f;
}
void open_beep()
{
P2=(P2&0x1f)|0xa0;
P0=0xff;
P2&=0x1f;
}
void cls_beep()
{
P2=(P2&0x1f)|0xa0;
P0=0x00;
P2&=0x1f;
}
void int_sd()
{
open_led1(); //开led1
dspbuf[0]=dspbuf[1]=dspbuf[2]=dspbuf[3]=dspbuf[4]=dspbuf[5]=dspbuf[6]=dspbuf[7]=12; //数码管全量
open_beep(); //开蜂鸣器
while(!sec_flag); //等待1秒
cls_led1(); //关led1 关显示 关蜂鸣器 sec_flag标志位清零
dspbuf[0]=dspbuf[1]=dspbuf[2]=dspbuf[3]=dspbuf[4]=dspbuf[5]=dspbuf[6]=dspbuf[7]=11;
cls_beep();
sec_flag=0;
}
void delay(uint time)
{
uint i;
while(time--)
{
for(i=0;i<800;i++);
}
}
void moshi() //显示模式
{
uchar x;
x=ms_flag;
switch(x)
{
case 0: dspbuf[0]=shi/10; //显示时间模式
dspbuf[1]=shi%10;
dspbuf[2]=10;
dspbuf[3]=min/10;
dspbuf[4]=min%10;
dspbuf[5]=10;
dspbuf[6]=sec/10;
dspbuf[7]=sec%10;
break;
case 1: dspbuf[5]=ss/100; //显示距离模式
dspbuf[6]=ss%100/10;
dspbuf[7]=ss%10;
dspbuf[0]=11;
dspbuf[1]=11;
dspbuf[2]=11;
dspbuf[3]=11;
dspbuf[4]=11;
break;
}
}
void key_s7()
{
if(s7==0)
{
delay(5);
if(s7==0)
{
ms_flag=~ms_flag; //模式 当MS_FLAG=0时 为显示时间模式 当MS_FLAG=1时为显示距离模式
while(!s7);
}
}
}
void key_s6_time() //时间模式下 s6按键功能函数
{
if(s6==0)
{
delay(5);
if(s6==0)
{
if(ms_add==0) //如果s6被按下
{
sz_time[0]=shi; //储存当前的时间
sz_time[1]=min;
sz_time[2]=sec;
}
ms_add++;
if(ms_add==3) //当按钮按下三次以后 将设置后的时间写入1302
{
ms_add=0; //标志清零
write_13(0x8e,0x00);
write_13(0x80,sz_time[2]); //秒存
write_13(0x82,sz_time[1]); //分存
write_13(0x84,sz_time[0]); //时存
write_13(0x8e,0x80);
}
while(!s6);
}
}
}
void key_s6_HC() //距离模式时 s6按钮功能函数
{
if(s6==0)
{
delay(5);
if(s6==0)
{
if(ms_HCflag) //再次按下时将设置的报警距离存入24C02
{
w_iic(0x00,bj_jl);
delay(10);
}
ms_HCflag=~ms_HCflag;
while(!s6);
}
}
}
void sz_moshi() //设置时间的显示模式
{
switch(ms_add) //ms_add为1时显示case 1的内容 时闪烁 为2时显示case 2的内容 分闪烁
{
case 1: if(sec_szflag) //小时位闪烁
{
dspbuf[0]=sz_time[0]/10;
dspbuf[1]=sz_time[0]%10;
} else
{
dspbuf[0]=11;
dspbuf[1]=11;
}
dspbuf[2]=10;
dspbuf[3]=sz_time[1]/10; //显示按下设置键后存储的时间
dspbuf[4]=sz_time[1]%10;
dspbuf[5]=10;
dspbuf[6]=sz_time[2]/10;
dspbuf[7]=sz_time[2]%10;
break;
case 2: if(sec_szflag)
{
dspbuf[3]=sz_time[1]/10;
dspbuf[4]=sz_time[1]%10;
} else
{
dspbuf[3]=11;
dspbuf[4]=11;
}
dspbuf[2]=10;
dspbuf[0]=sz_time[0]/10;
dspbuf[1]=sz_time[0]%10;
dspbuf[5]=10;
dspbuf[6]=sz_time[2]/10;
dspbuf[7]=sz_time[2]%10;
break;
}
}
void szHC_moshi()
{
dspbuf[5]=bj_jl/100;
dspbuf[6]=bj_jl%100/10;
dspbuf[7]=bj_jl%10;
dspbuf[0]=11;
dspbuf[1]=11;
dspbuf[2]=11;
dspbuf[3]=11;
dspbuf[4]=11;
if(s5==0)
{
delay(5);
if(s5==0)
{
bj_jl++;
while(!s5);
}
}
if(s4==0)
{
delay(5);
if(s4==0)
{
bj_jl--;
while(!s4);
}
}
}
void jiaohu()
{
if(ms_flag==0)
{
key_s6_time();
if(ms_add==0) //s6按键没有被按下时 ms_add为0 显示正常界面
{
moshi();
}
else
{
sz_moshi(); //s6被按下后 ms-add不为0 显示设置时间模式函数
if(s5==0) //如果s5按下 对应的时间加1
{
delay(5);
if(s5==0)
{
sz_time[ms_add-1]++;
while(!s5);
}
}
if(s4==0) //如果s4按下 对应的时间减1
{
delay(5);
if(s4==0)
{
sz_time[ms_add-1]--;
while(!s4);
}
}
}
}
else
{ //显示距离模式时
key_s6_HC();
if(ms_HCflag==0)
moshi();
else
szHC_moshi(); //设置报警距离显示模式
}
}
复制代码
Keil代码下载:
超声波测距及时钟.rar
(144.53 KB, 下载次数: 37)
2023-4-25 14:11 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
1015282347
时间:
2024-3-21 21:41
楼主这个真的很全啊!!!
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1