蓝桥杯单片机4T平台模拟试题解析

个人感觉比往届的试题都难一点,且两套都涉及了串口,这里先传第一套

 

 

 

#include <STC15F2K60S2.H>
#include <intrins.h>
#include <stdio.h>
code unsigned char number[28] = 
{
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,
0xbf,0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,	// - 0.
0xc1
};//+17后为带.字 48 65 97
unsigned char uc_mod1,uc_value_distence = 30,uc_led = 0xff,uc_10ms;
unsigned int ui_distence;
sbit TX = P1^0;
sbit RX = P1^1;
bit b_200ms;
bit flag_10ms; 
void smg_led();
void Timer2Init(void)		//10毫秒@12.000MHz
{
	AUXR &= 0xFB;		//定时器时钟12T模式
	T2L = 0xF0;		//设置定时初值
	T2H = 0xD8;		//设置定时初值
	AUXR |= 0x10;		//定时器2开始计时
	
	EA = 1;
	IE2 = IE2 | 0x04;	//用于计时,开关没有按位寻址,所以需要自己翻手册开启
}

void timer2()	interrupt 12
{
	uc_10ms++;		//计时中断
	if(uc_10ms == 20)
	{
		b_200ms = ~b_200ms;
		uc_10ms = 0;
	}
}

void Timer0Init(void)		//超声波测距用
{
	AUXR &= 0x7F;		
	TMOD &= 0xF0;		
	TL0 = 0x00;		
	TH0 = 0x00;		
	TF0 = 0;		
	TR0 = 0;		
}
void UartInit(void)		//9600bps@12.000MHz
{
	SCON = 0x50;		//8位数据,可变波特率
	AUXR &= 0xBF;		//定时器1时钟为Fosc/12,即12T
	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
	TMOD &= 0x0F;		//设定定时器1为16位自动重装方式
	TL1 = 0xE6;		//设定定时初值
	TH1 = 0xFF;		//设定定时初值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
	
	TI = 1;			//注意,这里因为只要求了uart送,所以用这种写法
}					//否则是需要开中断的

void Delay30ms()		//@12.000MHz
{
	unsigned char i, j, k;

	_nop_();
	_nop_();
	i = 2;
	j = 95;
	k = 43;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void Delay600us()		//@12.000MHz
{
	unsigned char i, j;

	i = 7;
	j = 254;
	do
	{
		while (--j);
	} while (--i);
}

void Delay14us()		//@12.000MHz
{
	unsigned char i;

	_nop_();
	_nop_();
	i = 39;
	while (--i);
}

void send_wave()		//发送超声波
{
	unsigned char i;
	for(i = 1;i<=8;i++)
	{
		TX = 1;
		Delay14us();
		TX = 0;
		Delay14us();
	}
}
void HC138_choose(unsigned char l)
{
	switch(l)
	{
		case 0:
		{
			P2 = (P2 & 0x1f) | 0x00;
			break;
		}
		case 4:
		{
			P2 = (P2 & 0x1f) | 0x80;
			break;
		}
		case 5:
		{
			P2 = (P2 & 0x1f) | 0xa0;
			break;
		}
		case 6:
		{
			P2 = (P2 & 0x1f) | 0xc0;
			break;
		}
		case 7:
		{
			P2 = (P2 & 0x1f) | 0xe0;
			break;
		}
	}	
}
void celiang()
{
	unsigned int ui_time;
	RX = 1;
	TF0 = 0;
	TL0 = 0x00;
	TH0 = 0x00;
	send_wave();
	TR0 = 1;
	while(TF0 == 0 && RX == 1)
	{
		if(ui_distence == 255)
		{
			smg_led();
		}
	}
	TR0 = 0;
	if(RX == 0 && TF0 == 0)
	{
		ui_time = (TH0 << 8) | TL0;
		ui_distence = ui_time * 0.017;
	}
	else
	{
		ui_distence = 255;		//超出设置为最大值
	}
	smg_led();
	smg_led();
	smg_led();
}
void smg_show(unsigned char wei,duan)
{
	HC138_choose(6);
	P0 = 0x01 << (wei - 1);
	HC138_choose(7);
	P0 = number[duan];
	Delay600us();
	P0 = 0xff;
}
void smg_led()
{
	switch(uc_mod1)
	{
		case 0:
		{
			smg_show(6,ui_distence / 100);
			smg_show(7,ui_distence / 10 % 10);
			smg_show(8,ui_distence % 10);
			smg_show(1,27);
			smg_show(2,1);
			HC138_choose(4);
			P0 = uc_led;
			P01 = 1;
			P00 = 0;
			uc_led = P0;
			break;
		}
		case 1:
		{
			smg_show(6,uc_value_distence / 100);
			smg_show(7,uc_value_distence / 10 % 10);
			smg_show(8,uc_value_distence % 10);
			smg_show(1,27);
			smg_show(2,2);
			HC138_choose(4);
			P0 = uc_led;			//led点灯
			P00 = 1;
			P01 = 0;
			uc_led = P0;			//记录LED状态
			break;
		}
	}
	if(ui_distence > uc_value_distence)		//超出距离LED闪烁
	{
		if(flag_10ms == 0)
		{
			uc_10ms = 0;
			flag_10ms = 1;
		}
		HC138_choose(4);
		P0 = uc_led;
		P02 = b_200ms;
		uc_led = P0;
	}
	else		//未超,关灯
	{
		flag_10ms = 0;
		HC138_choose(4);
		P0 = uc_led;
		P02 = 1;
		uc_led = P0;
	}
}
void init()
{
	HC138_choose(7);
	P0 = 0xff;
	HC138_choose(6);
	P0 = 0x00;
	HC138_choose(4);
	P0 = 0xff;
	HC138_choose(5);
	P0 = 0x00;
}
void scan_key()
{
	P44 = 1;		
	P33 = 0;
	P30 = 1;		//关闭相关干扰项
	P31 = 1;
	P32 = 1;
	if(P44 == 0)
	{
		while(P44 == 0)
		{
			celiang();
			smg_led();
		}
		Delay30ms();
		uc_mod1++;
		uc_mod1 %= 2;
	}
	
	P33 = 0;
	P30 = 1;
	P31 = 1;			//关闭相关干扰项
	P32 = 1;
	P44 = 1;
	
	P35 = 1;
	P34 = 1;
	P42 = 1;
	if(uc_mod1 == 0)
	{
		if(P42 == 0)
		{
			while(P42 == 0)
			{
				celiang();
				smg_led();
			}
			Delay30ms();
			if(ui_distence != 255)
			{
				uc_value_distence = ui_distence;
			}
		}
	}
	else if(uc_mod1 == 1)
	{
		if(P35 == 0)
		{
			while(P35 == 0)
			{
				celiang();
				smg_led();
			}
			Delay30ms();
			uc_value_distence += 10;
		}	
		if(P34 == 0)
		{
			while(P34 == 0)
			{
				celiang();
				smg_led();
			}
			Delay30ms();
			uc_value_distence -= 10;
		}	
	}
	
	P32 = 1;
	
	P34 = 0;
	P35 = 0;		//关闭相关干扰项
	P44 = 0;
	
	P42 = 0;
	if(P32 == 0)
	{
		while(P32 == 0)
		{
			celiang();
			smg_led();
		}
		printf("Distance:%dcm\n",ui_distence);		//利用了stdio.h的printf 具体用法可以站内搜索看看
		Delay30ms();
	}
}
void main()
{
	init();
	Timer0Init();
	UartInit();
	Timer2Init();
	while(1)
	{
		scan_key();
		celiang();
		smg_led();
	}
}

以上,感谢阅读,如有错误恳请指正,我会及时修改。

作者:linni_

物联沃分享整理
物联沃-IOTWORD物联网 » 蓝桥杯单片机4T平台模拟试题解析

发表评论