设计要求
驱动超声波传感器,启动距离测量功能,并将其结果显示到数码管上。
按键“S5”定义为参数按键,按下S5按键,设备自动将当前采集的距离数据作为距离参数;
若测量的距离数据超过距离参数,指示灯L1点亮,否则L1熄灭。
距离数据保留小数点后两位有效数字,数码管显示格式如下:
距离为0.40m(数码管高位显示标识符U)
备注
单片机IRC振荡器频率设置为12MHz。
按键模式:BTN;扩展方式:IO模式。
距离参数初始值为0。
代码
sys.h
#ifndef __SYS_H__
#define __SYS_H__
#include <STC15F2K60S2.H>
//sys.c
extern float distance_keep;
extern float distance;
void init74hc138(unsigned char n);
void init();
void led1();
//seg_key.c
extern unsigned char Seg_Buff[8];
void Key_Loop();
void Seg_Loop();
void ui();
#endif
main.c
#include "sys.h"
#include "intrins.h"
#define NUM 10
sbit TX=P1^0;
sbit RX=P1^1;
bit flag1=0,flag2=0,flag3=0;
void delay(){//超声波延时
unsigned char i=0;
for(i;i<NUM;i++){
_nop_();
}
}
void Timer1_Init(void) //100微秒@12.000MHz
{
AUXR |= 0x40; //定时器时钟1T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0x50; //设置定时初始值
TH1 = 0xFB; //设置定时初始值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
ET1 = 1; //使能定时器1中断
EA=1;
}
void send_wave(){//发送超声波脉冲
unsigned char i=8;
while(i--){
TX=1;
delay();
TX=0;
}
}
void re_wave(){//接收超声波并计算距离
send_wave();
TH0=0;
TL0=0;
TR0=1;
while((RX==1)&&(TF0==0));
TR0=0;
if(!TF0){
distance=(float)(TH0<<8|TL0)*0.017;//cm
}else{
TF0=0;
distance=0.0;
}
}
void main(){
init();
Timer1_Init();
TMOD |= 0x01;
while(1){
if(flag1){
flag1=0;
Seg_Loop();
}
if(flag2){
flag2=0;
Key_Loop();
}
if(flag3){
flag3=0;
re_wave();
led1();
ui();
}
}
}
void Timer1_Isr(void) interrupt 3
{
static unsigned char count1=0;
static unsigned char count2=0;
static unsigned int count3=0;
count1++;count2++;count3++;
if(count1==2){
count1=0;
flag1=1;
}
if(count2==50){
count2=1;
flag2=1;
}
if(count3==1000){
count3=0;
flag3=1;
}
}
sys.c
#include "sys.h"
float distance=0;
float distance_keep=0;
void init74hc138(unsigned char n){
P2=(P2&0x1f)|(n<<5);
P2&=0x1f;
}
void init(){
P0=0x00;
init74hc138(5);
P0=0xff;
init74hc138(4);
}
void led1(){
static bit flag=0;
if(distance>distance_keep&&!flag){
flag=1;
P0=0xfe;
init74hc138(4);
}else if(distance<=distance_keep&&flag){
flag=0;
P0=0xff;
init74hc138(4);
}
}
seg_key.c
#include "sys.h"
code unsigned char Seg_Table[]={
0xc0,//0
0xf9,//1
0xa4,//2
0xb0,//3
0x99,//4
0x92,//5
0x82,//6
0xf8,//7
0x80,//8
0x90,//9
0xc1,//U 10
0xff //熄灭 11
};
unsigned char Seg_Buff[8]={11,11,11,11,11,11,11,11};
unsigned char keyval,keyold,keyup,keydown;
void Key_Loop(){
if(P32==0)keyval=5;
keydown=keyval&(keyold^keyval);
keyup=~keyval&(keyold^keyval);
if(keyval==5&&!keyold!=5){
distance_keep=distance;
}
keyold=keyval;
keyval=0;
}
void seg(unsigned char addr,num){
P0=0xff;
init74hc138(7);
P0=0x01<<addr;
init74hc138(6);
P0=Seg_Table[num];
if(addr==5) P0&=0x7f;
init74hc138(7);
}
void Seg_Loop(){
static unsigned char i=0;
seg(i,Seg_Buff[i]);
i++;
if(i==8)i=0;
}
void ui(){
Seg_Buff[0]=10;
Seg_Buff[1]=11;
Seg_Buff[2]=11;
Seg_Buff[3]=11;
Seg_Buff[4]=11;
if(distance>=100)
Seg_Buff[5]=(unsigned char)distance/100;
else
Seg_Buff[5]=0;
if(distance>=10)
Seg_Buff[6]=(unsigned char)distance/10%10;
else
Seg_Buff[6]=0;
if(distance>0)
Seg_Buff[7]=(unsigned char)(distance+0.5)%10;
else
Seg_Buff[7]=0;
}