📄 main.c
字号:
//#include "STC12C5410AD.h"
#include <REG52.H>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
/*----------------------
分体式超声波发射接收对管
型号:TR40
频率:40K
T是发射
R是接收
----------------------*/
sbit k1 = P3^4;
sbit bg = P3^3;
sbit csbout = P3^5; //超声波发送
sbit csbint = P3^7; //超声波接收
float csbc = 0.034; //声音的传播速度 0.034 cm/us(厘米/微秒)
uchar csbds,digit,buffer[3],xm1,xm2,xm0,key,jpjs; //显示标识
uchar convert[10]={ 0x3F, //0
0x06, //1
0x5b, //2
0x4f, //3
0x66, //4
0x6d, //5
0x7d, //6
0x07, //7
0x7f, //8
0x6f //9
}; //0~9段码
uint s,t,i, xx,j,sj1,sj2,sj3,mqs,sx1;
bit cl;
void csbcj();
void delay(j); //延时函数,延时的时间由变量J决定
void scanLED(); //显示函数
void timeToBuffer(); //显示转换函数
void keyscan(); //用于识别是设定最近值还是最远值及报警值和各种情况所对应的延时值mqs
void k1cl(); //用于设定测距的最近值
void k2cl(); //用于设定测距的报警值,如果到了设定的报警值时,bg位置1
void k3cl(); //用于设定测距的最远值
void k4cl(); //用于设定在发送超声信号后,所要的延时值,在不同地最近值时,其延时值也不会相同
void offmsd();
void main() //主函数
{
EA=1; //开中断
TMOD=0x11; //设定时器0为计数,设定时器1定时
ET1=1; //定时器1中断允许
TH0=0x00;
TL0=0x00;
TH1=0x9E;
TL1=0x57;
csbds=0;
cl=0;
TR1=1;
jpjs=0;
sj1=30;
sj2=80;
sj3=200;
P2=0xff;
k4cl();
P0=0xff;
P3=0xff;
while(1)
{
keyscan();
if(jpjs<1) csbcj();
timeToBuffer(); //将值转换成LED段码
offmsd();
scanLED(); //显示函数
if(s<sj2) //距离小于报警值,报警,点亮指示灯
bg=0;
else
bg=1;
}
}
void scanLED() //显示功能模块
{
digit=0x80;
for( i=0; i<3; i++) //3位数显示
{
P2=~digit; //依次显示各位数
P0=~buffer[i]; //显示数据送P0口
delay(20); //延时处理
P2=0xff;
P0=0xff; //P1口置高电平(关闭)
digit>>=1; //循环右移1位
}
P2=0xff;
}
void timeToBuffer() //转换段码功能模块
{
xm0=s/100;
xm1=(s-100*xm0)/10;
xm2=s-100*xm0-10*xm1;
buffer[2]=convert[xm2];
buffer[1]=convert[xm1];
buffer[0]=convert[xm0];
}
void delay(i)
{
while(--i);
}
void timer1int (void) interrupt 3 //定时器延时一段时间,消除未接受的超声波信号的干扰
{
TH1=0x9E;
TL1=0x57;
csbds++;
if(csbds>=40)
{
csbds=0;
cl=1; //延时时间结束,置标志信号,可以再次测距
TR1=0;
}
}
/*---------测距函数---------------
先发送5个周期的超声波信号,然后开计数器0,
延时一段时间mqs,再识别是否收到超声波信号.
如有则关计数器0,然后读计数器内的值,再经运
算换算成三位的整数,存放在S中.
--------------------------------*/
void csbcj() //产生超声波并测距
{
csbint=1;
if(cl==1) //检测是否可以开始测距
{
TR1=0;
TH0=0x00;
TL0=0x00;
i=10;
TR0=1;
while(i--)
{
csbout=!csbout;
}
i=0;
while(csbint)
{
if(++i>=4000) //上限值,最多可循环4000次,以防止定时器T0溢出
break; //达到上限,强制退出循环
}
TR0=0; //停止计时
TH1=0x9E;
TL1=0x57;
csbds=0;
cl=0; //测试允许标志位清零,关闭测试
TR1=1; //启动定时器1延时,消除尚未接收的超声波信号
t=TH0;
t=t*256+TL0;
s=t*csbc/2.0; //测距离
}
}
void keyscan() //健盘处理函数
{
xx=0;
if(k1!=1) // 判断开关是否按下
{
delay(400); //延时去抖动
if(k1!=1) // 判断开关是否按下
{
while(!k1)
{
delay(30);
xx++;
}
if(xx>2000) //若按下一定时间,则为功能设定,将功能选项下移一位
{
jpjs++;
if(jpjs>4) //若已到最后一项选项,则退出设定
jpjs=0;
}
xx=0;
switch(jpjs)
{
case 1: k1cl();break; //用于设定测距的最近值
case 2: k2cl();break; //用于设定测距的报警值,如果到了设定的报警值时,bg位置1
case 3: k3cl();break; //用于设定测距的最远值
case 4: k4cl();break; //用于设定在发送超声信号后,所要的延时值,在不同地最近值时,其延时值也不会相同
}
}
}
}
/*---设定测距的最近值---*/
void k1cl()
{
sj1=sj1+5;
if(sj1>100)
sj1=30;
s=sj1;
}
/*---设定测距的报警值,如果到了设定的报警值时,bg位置1---*/
void k2cl()
{
sj2=sj2+5;
if(sj2>500)
sj2=40;
s=sj2;
}
/*---用于设定测距的最远值---*/
void k3cl()
{
sj3=sj3+10;
if(sj3>500)
sj3=100;
s=sj3;
}
/*---用于设定在发送超声信号后,所要的延时值,在不同地最近值时,其延时值也不会相同---*/
void k4cl()
{
sx1=sj1-1; //最小测试距离-1
sx1=sx1/csbc; //传送时间
mqs=sx1/4.5; //延时时间
}
void offmsd()
{
if (buffer[0] == 0x3f)
buffer[0] = 0x00;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -