蓝桥杯单片机刷题——超声测距显示

设计要求

驱动超声波传感器,启动距离测量功能,并将其结果显示到数码管上。

距离数据单位为m,保留小数点后两位有效数字,数码管显示格式如下:

              

按键S9定义为“设置”按键,按下S9按键,设备自动将当前采集的距离数据设置为距离参数;

若实时距离数据超过距离参数,指示灯L1点亮,否则L1熄灭。

备注:

单片机IRC振荡器频率设置为12MHz。

按键模式:KBD;扩展方式:IO模式

个人代码

#include <STC15F2K60S2.H>
#include "intrins.h"
sbit TX=P1^0;
sbit RX=P1^1;
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
0xff
};
unsigned char Seg_Buff[]={10,10,10,10,10,10,10,10};
unsigned char keyval,keyold,keyup,keydown;
bit flag_seg=0,flag_key=0,flag_wave=0;
float distance_max=50.0; //当前距离
float distance=0.0;			//设置的距离参数

//----------74HC138译码器控制----------
void init74hc138(unsigned char n){
	P2=(P2&0x1f)|(n<<5);
	P2&=0x1f;
}

//----------系统初始化----------
void init(){
	P0=0x00;
	init74hc138(5);
	P0=0xff;
	init74hc138(4);
	//初始化蜂鸣器、LED等
}

//----------超声波延时----------
void delay() {
    _nop_();_nop_();_nop_();_nop_();_nop_();
    _nop_();_nop_();_nop_();_nop_();_nop_();
}

//----------发送超声波脉冲----------
void send_wave(){
	unsigned char i=8;
	do{
		TX=1;
		delay();
		TX=0;
	}while(i--);
}
//----------接收超声波并计算距离----------
void re_wave(){
	send_wave();
	TH1=0;
	TL1=0;	
	TR1=1;
	while((RX==1)&&(TF1==0));
	TR1=0;
	
	if(TF1){	//超时未收到回波
		TF1=0;
		distance=0.0;
	}else{
		distance=(float)(TH1<<8|TL1)*0.017;	
		if(distance > 500.0) distance = 0.0; //过滤无效值
	}
}

//----------按键处理----------
void Key_Loop(){
	P42=0;
	keyval=0;
	if(P32==0)keyval=1;
	keydown=keyval&(keyold^keyval);
	keyup=~keyval&(keyold^keyval);
	if(keyval&&keyold!=keyval)distance_max=distance;
	keyold=keyval;
}

//----------数码管动态扫描----------
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 seg_dis(){
	unsigned char temp=(unsigned char)(distance+0.5);
	Seg_Buff[7] = temp % 10;					//小数第二位
  Seg_Buff[6] = (temp / 10) % 10;		//小数第一位
  Seg_Buff[5] = (temp / 100) % 10;	//个位
}

//----------LED状态更新----------
void led_max(){
	P0 = (distance > distance_max) ? 0xfe : 0xff;
	init74hc138(4);
}

void Timer0_Init(void)		//100微秒@12.000MHz
{
	AUXR |= 0x80;			//定时器时钟1T模式
	TMOD &= 0xF0;			//设置定时器模式
	TL0 = 0x50;				//设置定时初始值
	TH0 = 0xFB;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
	ET0 = 1;				//使能定时器0中断
	EA	=	1;		
}
//void Timer1_Init(void)		//1毫秒@12.000MHz
//{
//	TMOD &= 0x0F;			//设置定时器模式
//	TL1 = 0x00;				//设置定时初始值
//	TH1 = 0x00;				//设置定时初始值
//}
void main(){
	init();
	Timer0_Init();
//	Timer1_Init();
	TMOD |= 0x10;      //定时器1模式1
	while(1){
		if(flag_seg){
			flag_seg=0;
			Seg_Loop();
		}
		if(flag_key){
			flag_key=0;
			Key_Loop();
			led_max();
		}
		if(flag_wave){
			flag_wave=0;
			re_wave();
			seg_dis();
		}
	}
}
void Timer0_Isr(void) interrupt 1
{
	static unsigned int count=0;
	count++;
	flag_seg=1;
	if(count==1000){
		count=0;
		flag_wave=1;
		flag_key=1;
	}
}

尚待解决的问题

测量距离有限,不超过40cm,一旦超过这个距离超声波接收装置就无法收到超声波,使得数码管不断闪烁。应该是我板子的问题,因为在平台测试结果显示正常。

测试结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lzb759

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值