蓝桥杯第十三届模拟题03——源代码

该博客主要介绍了基于单片机的超声波测距仪的实现方法。内容包括硬件配置,如矩阵按键、数码管显示、蜂鸣器等模块的接口设计,以及软件部分的定时器设置、中断服务、超声波信号发送与接收的处理。博主通过详细的代码展示了如何测量距离,并根据测量结果进行显示和报警功能的实现。
摘要由CSDN通过智能技术生成

还有几小时比赛了,做个模拟练练手感
先看原题
请添加图片描述

#include "reg51.h"
#include "absacc.h"
#include "intrins.h"

#define uchar unsigned char
#define uint unsigned int 
sbit TX = P1^0;
sbit RX = P1^1;

//矩阵按键配置
sbit R1=P3^0;//第一排初始化(如果跳线帽模式是BTN,则只有最左侧一列能用)
sbit R2=P3^1;//第二排初始化
sbit R3=P3^2;//第三排初始化
sbit R4=P3^3;//第四排初始化

sbit C1=P4^4;//第一列初始化
sbit C2=P4^2;//第二列初始化
sbit C3=P3^5;//第三列初始化
sbit C4=P3^4;//第四列初始化

sbit Buzz=P0^6;//蜂鸣器

unsigned int distance = 0;
uchar mode;
uchar mode_k;
uint high=50;
uint low=0;
uchar count_b;
uchar mode_led;
 0    1     2    3    4    5    6   7    8    9    -   全灭   .
unsigned char code shuzi[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0xbf,0xff,0x7f};
/// A     b   C     d    E    F    H   L     P    U   n
unsigned char code zimu[]={0x88,0x83,0xc6,0xa1,0x86,0x8e,0x89,0xc7,0x8c,0xc1,0xc8};
  0     1     2    3    4    5    6    7   
unsigned char code weizhi[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00};
//   1    2   3    4    5    6    7    8    灭
unsigned char ledweizhi[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0xff};

void delay_ms(int ms)
{
	int q,w;
	for(q=0;q<ms;q++)
	{
		for(w=845;w>0;w--);
	}
}
 void shumaguan_shuzi(uchar a,uchar b)
{
	delay_ms(1);
	P2=(P2&0X1f)|0xC0;P0=weizhi[a];
	P2=(P2&0X1f)|0xE0;P0=shuzi[b];
	delay_ms(1);
	//消隐
	P2 = (P2 & 0x1f) | 0xc0;
	P0 = 0x00;
	P2 = P2 & 0x1f;
}
//数码管字母显示
void shumaguan_zimu(uchar a,uchar b)
{
	delay_ms(1);
	P2=(P2&0X1f)|0xC0;P0=weizhi[a];
	P2=(P2&0X1f)|0xE0;P0=zimu[b];
	delay_ms(1);
	//消隐
	P2 = (P2 & 0x1f) | 0xc0;
	P0 = 0x00;
	P2 = P2 & 0x1f;
}
void ledlight(uchar x)
{
	P2=(P2&0X1f)|0x80;
	P0=ledweizhi[x];
}
void Init_Keys()
{
	R1=R2=R3=R4=1;
	C1=C2=C3=C4=1;
}
 void Init_timer0()//定时器配置      
{
	TMOD = 0x01;      
	TH0 = (65535 - 50000) / 256; //50ms技术   
	TL0 = (65535 - 50000) % 256;	
	EA  = 1;     
	ET0 = 1;     
	TR0 = 1;     
}
void Service_timer0() interrupt 1//定时器0,中断
{
		count_b++;//全局变量
	if(count_b==4)//计算了1s
	{
		count_b=0;
		if(mode_led==0)//mode_smg也是全局变量
		{
			mode_led=1;
		}
		else if(mode_led==1)
		{
			mode_led=0;
		}
	}
}
void L3_blink()//显示小时以1s的间隔显示一次
{
	if(mode_led==1)
		{
		ledlight(2);
		}
		if(mode_led==0)
		{
		ledlight(8);
		}
}
void display_d()
{
	if(distance == 999)
	{
		shumaguan_zimu(0,5);			//超出测量范围标志:F

	}
	else
	{
	shumaguan_shuzi(5, distance / 100);
	shumaguan_shuzi(5,12);
	shumaguan_shuzi(6, (distance % 100) / 10);

	shumaguan_shuzi(7, distance % 10);

	}
	P2=0x80;
	P0=0x00;
}
 
void Delay12us()                  //@12.000MHz 延时12us
{
	unsigned char i;
 
	_nop_();
	_nop_();
	i = 33;
	while (--i);
}
 
void Send_Wave()                 //产生8个40KHx超声波信号
{
	unsigned char i;
	for(i = 0; i < 8; i++)
	{
		TX = 1;
		Delay12us();	
		TX = 0;
		Delay12us();
	}
}
 
void Measure_Distance()	        //超声波测距
{
	unsigned int time = 0;
	
	TMOD &= 0x0f;	            //定时器1模式0,13位,最大8192个计数脉冲								
	TL1 = 0x00;										
	TH1 = 0x00;		
	
	Send_Wave();		        //发送超声波信号							
	TR1 = 1;            //启动定时器						
	while((RX == 1) && (TF1 == 0));    //等待超声波信号返回或者等到测量超出范围
	TR1 = 0;            //停止定时器				
	
	if(TF1 == 0)	            //正常测量范围							
	{
		time = TH1;									
		time = (time << 8) | TL1;		
		distance = ((time / 10) * 17) / 100 + 3;
	}
	else                        //超出测量范围			
	{
		TF1 = 0;
		distance = 999;
	}
}
void display_h()
{
	mode_k=0;
	shumaguan_zimu(0,9);
	shumaguan_shuzi(6,high/10);
	shumaguan_shuzi(7,high%10);
	ledlight(0);
}
void display_l()
{
	mode_k=1;
	shumaguan_zimu(0,10);
	shumaguan_shuzi(6,low/10);
	shumaguan_shuzi(7,low%10);
	ledlight(1);
}
void select_mode()
{
	switch(mode)
	{
		case(0):display_d();break;
		case(1):display_h();break;
		case(2):display_l();break;
	}
}
void alarm()
{
	if(distance<=low||distance>=high)
	{
		P2 = ((P2 & 0x1F) | 0xA0);
		Buzz=1;
		L3_blink();
	}
	else
	{
	P2 = ((P2 & 0x1F) | 0xA0);
		Buzz=0;
	}
}
void Scan_S4()
{
	R1=1;R2=1;R3=1;R4=0;
	C2=1;C3=1;C4=1;
	if(C1==0)
	{
		while(C1==0);
		mode++;
		if(mode==3) mode=0;
	}
}
void Scan_S8()
{
	R1=1;R2=1;R3=1;R4=0;
	C3=1;C4=1;C1=1;
	if(C2==0)
	{
		while(C2==0);
		if(mode_k==0)
		{
			high=high+10;
		}
		if(mode_k==1)
		{
			low=low+10;
		}
	}
}
void Scan_S12()
{
	R1=1;R2=1;R3=1;R4=0;
	C4=1;C1=1;C2=1;
	if(C3==0)
	{
		while(C3==0);
		if(mode_k==0)
		{
			high=high-10;
		}
		if(mode_k==1)
		{
			low=low-10;
		}
	}
}
void main()
{
	Init_Keys();
	Init_timer0();
	while(1)
	{
		Measure_Distance();
		select_mode();
		Scan_S12();
		Scan_S8();
		Scan_S4();
		alarm();
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Sol-itude

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

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

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

打赏作者

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

抵扣说明:

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

余额充值