第十二届蓝桥杯单片机国赛真题

有问题欢迎大家指出,共同交流学习进步

#include <STC15F2K60S2.H>
#include "ds1302.h"
#include "intrins.h"
#include "iic.h"
#define TSMG 500
sbit TX = P1^0;
sbit RX = P1^1;
sbit h3 = P3^2;
sbit h4 = P3^3;
sbit s1 = P4^4;
sbit s2 = P4^2;
code unsigned char Seg_dot[] = {0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
code unsigned char Seg_Table[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
code unsigned char read_addre[] = {0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
code unsigned char write_addre[] = {0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
code unsigned char INIT_timer[] = {0x01,0x20,0x20,0x08,0x05,0x03,0x24};
unsigned char t_h = 0;
unsigned char t_m = 0;
unsigned char t_s = 0;
unsigned int distance = 0;
unsigned char UI = 0;//0-数据显示界面 1-参数显示界面
unsigned char UI_data = 0;//0-时间显示 1-距离显示 2-数据记录
unsigned char UI_param = 0;//0-采集时间参数 1-距离参数
unsigned char stat_value = 0;//0-最大值 1-最小值 2-平均值
unsigned char max_value = 0;
unsigned char min_value = 0;
float aver_value = 0;
unsigned char timer_param = 2;
unsigned char dis_param = 20;
unsigned char dis_mode = 0;//0-触发模式 1-定时模式
unsigned char adc_value = 0;
unsigned char old_value = 0;
unsigned int aver_smg = 0;
unsigned char Sec = 0;
unsigned char stat_old = 0;
unsigned stat_Sec = 0;
unsigned char warn = 0;
unsigned char num = 0;
unsigned char stat_led = 0xff;
unsigned char count_200ms = 0;
unsigned char adc_value1 = 0;
void Delay20ms()		//@12.000MHz
{
	unsigned char i, j, k;

	_nop_();
	_nop_();
	i = 1;
	j = 234;
	k = 113;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

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

	_nop_();
	_nop_();
	i = 33;
	while (--i);
}
unsigned char read_myadc()
{
	unsigned char adc_dat;
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(0x41);
	I2CWaitAck();
	I2CStop();
	
	I2CStart();
	I2CSendByte(0x91);
	I2CWaitAck();
	adc_dat = I2CReceiveByte();
	I2CSendAck(1);
	I2CStop();
	return adc_dat;
}
void set_mydac(unsigned char value)
{
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(0x41);
	I2CWaitAck();
	I2CSendByte(value);
	I2CWaitAck();
	I2CStop();
}
void send_Wave()
{
	unsigned char i;
	for(i = 0;i < 8;i++)
	{
		TX = 1;
		Delay12us();
		TX = 0;
		Delay12us();
	}
}
void measure_distan()
{
	unsigned int timer;
	CMOD = 0x00;
	CCON = 0x00;
	CL = CH = 0;
	send_Wave();
	CR = 1;
	while((RX == 1) && (CF == 0));
	CR = 0;
	if(CF == 0)
	{
		timer = (CH << 8) | CL;
		distance = timer * 0.0172;
	}
	else
	{
		CF = 0;
		distance = 999;
	}
}
void Init_mytimer()
{
	unsigned char i;
	Write_Ds1302_Byte(0x8e,0x00);
	for(i == 0;i < 7;i++)
	{
		Write_Ds1302_Byte(write_addre[i],INIT_timer[i]);
	}
	Write_Ds1302_Byte(0x8e,0x80);
}
void read_mytimer()
{
	t_h = Read_Ds1302_Byte(0x85);
	t_m = Read_Ds1302_Byte(0x83);
	t_s = Read_Ds1302_Byte(0x81);
}
void SelectHC573(unsigned char channel,unsigned char dat)
{
	P2 = (P2 & 0x1f) | 0x00;
	P0 = dat;
	switch(channel)
	{
		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;
		case 0:
			P2 = (P2 & 0x1f) | 0x00;
		break;
	}
	P2 = (P2 & 0x1f) | 0x00;
}
void DelaySMG(unsigned int t)
{
	while(t--);
}
void DisplaySMG_Bit(unsigned char pos,unsigned char value)
{
	SelectHC573(6,0x01 << pos);
	SelectHC573(7,value);
	DelaySMG(TSMG);
	SelectHC573(6,0x01 << pos);
	SelectHC573(7,0xff);
}
void DisplaySMG_All(unsigned char value)
{
	SelectHC573(6,0xff);
	SelectHC573(7,value);
}
void DisplaySMG_Info()
{
	if(UI == 0)
	{
		switch(UI_data)
		{
			case 0:
				DisplaySMG_Bit(0,Seg_Table[t_h >> 4]);
				DisplaySMG_Bit(1,Seg_Table[t_h & 0x0f]);
				DisplaySMG_Bit(2,0xbf);
				DisplaySMG_Bit(3,Seg_Table[t_m >> 4]);
				DisplaySMG_Bit(4,Seg_Table[t_m & 0x0f]);
				DisplaySMG_Bit(5,0xbf);
				DisplaySMG_Bit(6,Seg_Table[(t_s & 0x7f) >> 4]);
				DisplaySMG_Bit(7,Seg_Table[t_s & 0x0f]);
			break;
			case 1:
				DisplaySMG_Bit(0,0xc7);
				if(dis_mode == 0)
				{
					DisplaySMG_Bit(1,0xc6);
				}
				else if(dis_mode == 1)
				{
					DisplaySMG_Bit(1,0x8e);
				}
			    if(distance > 99)
				DisplaySMG_Bit(5,Seg_Table[distance / 100]);
				if(distance > 9) 
				DisplaySMG_Bit(6,Seg_Table[distance / 10 % 10]);
				DisplaySMG_Bit(7,Seg_Table[distance % 10]);
			break;
			case 2:
				DisplaySMG_Bit(0,0x89);
				switch(stat_value)
				{
					case 0:
						DisplaySMG_Bit(1,0xfe);
						if(max_value > 999)
						DisplaySMG_Bit(4,Seg_Table[max_value / 1000]);
						if(max_value > 99)
						DisplaySMG_Bit(5,Seg_Table[max_value / 100 % 10]);
						if(max_value > 9)
						DisplaySMG_Bit(6,Seg_Table[max_value / 10 % 10]);
						DisplaySMG_Bit(7,Seg_Table[max_value % 10]);
					break;
					case 1:
					    DisplaySMG_Bit(1,0xbf);
						if(aver_smg > 999)
						DisplaySMG_Bit(4,Seg_Table[aver_smg / 1000]);
						if(aver_smg > 99)
						DisplaySMG_Bit(5,Seg_Table[aver_smg / 100 % 10]);
						DisplaySMG_Bit(6,Seg_dot[aver_smg / 10 % 10]);
						DisplaySMG_Bit(7,Seg_Table[aver_smg % 10]);
					break;
					case 2:
						DisplaySMG_Bit(1,0xf7);
						if(min_value > 999)
						DisplaySMG_Bit(4,Seg_Table[min_value / 1000]);
						if(min_value > 99)
						DisplaySMG_Bit(5,Seg_Table[min_value / 100 % 10]);
						if(min_value > 9)
						DisplaySMG_Bit(6,Seg_Table[min_value / 10 % 10]);
						DisplaySMG_Bit(7,Seg_Table[min_value % 10]);
					break;
				}
			break;
		}
		
	}
	else
	{
		if(UI_param == 0)
		{
			DisplaySMG_Bit(0,0x8c);
			DisplaySMG_Bit(1,Seg_Table[1]);
			DisplaySMG_Bit(6,Seg_Table[timer_param / 10]);
			DisplaySMG_Bit(7,Seg_Table[timer_param % 10]);
		}
		else if(UI_param == 1)
		{
			DisplaySMG_Bit(0,0x8c);
			DisplaySMG_Bit(1,Seg_Table[2]);
			DisplaySMG_Bit(6,Seg_Table[dis_param / 10]);
			DisplaySMG_Bit(7,Seg_Table[dis_param % 10]);
		}
	}
}
void Scan_key()
{
	h3 = 0;
	h4 = s1 = s2 = 1;
	if(s1 == 0)//s5
	{
		Delay20ms();
		if(s1 == 0)
		{
			if(UI == 0)
			{
				if(UI_data == 0)
				{
					UI_data = 1;
				}
				else if(UI_data == 1)
				{
					stat_value = 0;
					UI_data = 2;
				}
				else if(UI_data == 2)
				{
					UI_data = 0;
				}
			}
			if(UI == 1)
			{
				if(UI_param == 0)
				{
					UI_param = 1;
				}
				else if(UI_param == 1)
				{
					UI_param = 0;
				}
			}
			while(s1 == 0);
		}
	}
	else if(s2 == 0)//s9
	{
		Delay20ms();
		if(s2 == 0)
		{
			if((UI == 1) && (UI_param == 0))
			{
				if(timer_param == 2)
				{
					timer_param = 3;
				}
				else if(timer_param == 3)
				{
					timer_param = 5;
				}
				else if(timer_param == 5)
				{
					timer_param = 7;
				}
				else if(timer_param == 7)
				{
					timer_param = 9;
				}
				else if(timer_param == 9)
				{
					timer_param = 2;
				}
			}
			if((UI == 1) && (UI_param == 1))
			{
				if(dis_param == 80)
				{
					dis_param = 10;
				}
				else
				{
					dis_param += 10;
				}
			}
			while(s2 == 0);
		}
	}
	
	h4 = 0;
	h3 = s1 = s2 = 1;
	if(s1 == 0)//s4
	{
		Delay20ms();
		if(s1 == 0)
		{
			if(UI == 0)
			{
				UI_param = 0;
				UI = 1;
			}
			else
			{
				UI_data = 0;
				UI = 0;
			}
			while(s1 == 0);
		}
	}
	else if(s2 == 0)//s8
	{
		Delay20ms();
		if(s2 == 0)
		{
			if((UI == 0) && (UI_data == 2))
			{
				if(stat_value == 0)
				{
					stat_value = 1;
				}
				else if(stat_value == 1)
				{
					stat_value = 2;
				}
				else if(stat_value == 2)
				{
					stat_value = 0;
				}
			}
			if((UI == 0) && (UI_data == 1))
			{
				if(dis_mode == 0)
				{
					dis_mode = 1;
				}
				else if(dis_mode == 1)
				{
					dis_mode = 0;
				}
			}
			while(s2 == 0);
		}
	}
}
void deal_distance()
{
	static unsigned char i = 0;
	if(dis_mode == 0)//触发模式
	{
		adc_value = read_myadc();
		if((old_value > 50) && (adc_value < 50))
		{
			measure_distan();
			if(stat_old == 0)
			{
				min_value = distance;
				stat_old = 1;
			}
			i++;
			aver_value = (aver_value * (i-1) + distance) / i;
		}
		old_value = adc_value;
	}
	else if(dis_mode == 1)//定时模式
	{
		Sec = (t_s / 16) * 10 + t_s % 16;
		
		if((Sec % timer_param) == 0)
		{
			if(stat_Sec != Sec)
			{
				stat_Sec = Sec;//防止多次测量
				measure_distan();
				if(stat_old == 0)
				{
					min_value = distance;
					stat_old = 1;
				}
				i++;
				aver_value = (aver_value * (i-1) + distance) / i;
				if(((dis_param + 5) >= distance)&& (distance >= (dis_param - 5)))
				{
					num++;
					if(num == 3)
					{
						num = 0;
						warn = 1;
					}
				}
				else
				{
					warn = 0;
				}
			}
		}			
	}
	if(distance > max_value)
	{
		max_value = distance;
	}
	if(distance < min_value)
	{
		min_value = distance;
	}
	aver_smg = aver_value * 10;
	if(i == 5)
	{
		i = 0;
	}
}
void led_control()
{
	if((UI == 0) && (UI_data == 0))
	{
		stat_led |= 0x04;
		stat_led &= 0xfe;
	}
	if((UI == 0) && (UI_data == 1))
	{
		stat_led |= 0x01;
		stat_led &= 0xfd;
	}
	if((UI == 0) && (UI_data == 2))
	{
		stat_led |= 0x02;
		stat_led &= 0xfb;
	}
	if(dis_mode == 0)
	{
		stat_led &= 0xf7;
	}
	else
	{
		stat_led |= 0x08;
	}
	if(warn == 1)
	{
		stat_led &= 0xef;
	}
	else
	{
		stat_led |= 0x10;
	}
	if(adc_value1 > 50)
	{
		stat_led &= 0xdf;
	}
	else
	{
		stat_led |= 0x20;
	}
	SelectHC573(4,stat_led);
}
void dac_output()
{
	unsigned char dac_value;
	if(distance < 10)
	{
		set_mydac(51);
	}
	else if(distance <= 80)
	{
		dac_value = (((4.0/70) * distance + (3.0 / 7)) / (5.0 / 255));
		set_mydac(dac_value);
	}
	else
	{
		set_mydac(255);
	}
}
void Timer0Init(void)		//10毫秒@12.000MHz
{
	AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x01;		//设置定时器模式
	TL0 = 0xF0;		//设置定时初值
	TH0 = 0xD8;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0 = 1;
	EA = 1;
}
void sevice_timer0() interrupt 1
{
	TL0 = 0xF0;		//设置定时初值
	TH0 = 0xD8;		//设置定时初值
	DisplaySMG_Info();
	read_mytimer();
	count_200ms++;
	if(count_200ms == 20)
	{
		count_200ms = 0;
		adc_value1 = read_myadc();
	}
}
void main()
{
	Timer0Init();
	Init_mytimer();
	DisplaySMG_All(0xff);
	SelectHC573(4,0xff);
	SelectHC573(5,0x00);
	while(1)
	{
		
		Scan_key();
		deal_distance();
		led_control();
		dac_output();
	}
}

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值