第十届蓝桥杯单片机国赛题代码

本人近期会分享蓝桥杯单片机各届的代码,希望能给新手朋友一些思路和参考,也请各位高手朋友指正批评,这是本人完成的第十届代码参考,本人代码风格是师从电子设计工坊,谢谢。

#include "STC15F2K60S2.H"
#include "iic.h"
#include "intrins.h"
#include "onewire.h"
#include "string.h"
#include "math.h"

#define u8 unsigned char
#define u16 unsigned int
	
u8 code smg_du[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00};
u8 code smg_wei[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

#define key_state0 0
#define key_state1 1
#define key_state2 2


//超声波
sbit TX=P1^0;
sbit RX=P1^1;
bit display_distance=0;
u16 timer,distance;

bit key_flag;
u8 j=0;//实现定时长按时间,要在全局定义
u8 z=0;
bit s8_flag;
bit s9_flag;

//串口通信
u8 Rdat[10];
u8 recv=0;//Rdat[recv]
u8 len=0;//设置数组的长度



u8 smg1[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
u8 smg2[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
u8 smg3[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
u8 smg4[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
u8 smg5[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
u16 pinlv=0;

bit xs_mode;//0是数据界面,1是参数界面
bit xs_cs_mode=0;//0是温度参数,1是距离参数
u8 xianshi_mode=0;//0是温度界面,1是距离界面,2是变更次数显示界面
u16 wendu_zhi;
u16 biangeng_cs=2;//变更次数
u8 wendu_cs=30;
u8 juli_cs=35;
bit dac_shuchu1=0;//开启和关闭dac,0是开启,1是关闭




void Timer0Init(void);
void Device(u8 p2,u8 p0);
void system_init();
u8 read_kbd();
void key_use();
void Delay12us();
void smg_xs();
void csb_hs();
void Delay10ms();
void send_wave(void);
void csb_distance1(void);
void timer00();
void UartInit(void);
void chuankou();
void clear_Rdat();
void wendu_hs();
void dac_hs();
void Delay5ms();
void led_hs();
void led_Device(u8 p3);

void main()
{
	Timer0Init();
	system_init();
	UartInit();
	biangeng_cs=read_24c02(0x00);
	
	while(1)
	{
		key_use();
		smg_xs();
		wendu_hs();
		csb_hs();
		chuankou();
		dac_hs();
		led_hs();
	}
}

void time0() interrupt 1   //定时器0是中断1,定时器是中断号3
{
	static int smg_count,key_count,i=0;
	u16 a0;
	
//	if(++count_f==500)
//	{
//		count_f=0;
//		TR0=0;
//		pinlv=(TH0*256+TL0)*2.3;
//		TH0=0X00;TL0=0X00;
//		TR0=1;
//	}
	
	if(++a0==350)
	{
		display_distance=1;
		a0=0;
	}
	
	
	if(++key_count==12)
	{
		key_count=0;
		key_flag=1;
	}
	
	if(++smg_count==2)
	{
		smg_count=0;
		Device(0xc0,0x00);
		
		if(xs_mode==0)//数据界面
		{
				if(xianshi_mode==0)
			{
				Device(0xe0,~smg1[i]);
			}
			else if(xianshi_mode==1)
			{
				Device(0xe0,~smg2[i]);
			}
			else if(xianshi_mode==2)
			{
				Device(0xe0,~smg3[i]);
			}
		}
		else //参数界面
		{
			if(xs_cs_mode==0)//温度
			{
				Device(0xe0,~smg4[i]);
			}
			else //距离参数
			{
				Device(0xe0,~smg5[i]);
			}
		}
		
		Device(0xc0,smg_wei[i]);
		i++;
		if(i==8) i=0;
	}
}

void key_use()
{
	u8 key_val_zhi=0;
	
	
	if(key_flag)
	{
		key_flag=0;
		key_val_zhi=read_kbd();
		
		switch(key_val_zhi)
		{

			
			case 12:
				z=100;
				j=0;
			if(xs_mode==0)
			{
				xianshi_mode++;
				if(xianshi_mode==3)
					xianshi_mode=0;
			}
			else
			{
				xs_cs_mode=~xs_cs_mode;
			}
			break;
			
			case 13:
				j=100;
				z=0;
			xs_mode=~xs_mode;
			break;
			
			case 16:
				if(xs_mode==1)
				{
					if(xs_cs_mode==0)
				{
					biangeng_cs++;
					write_24c02(0x00,biangeng_cs);
					if(biangeng_cs>65535)
						biangeng_cs=0;
					if(wendu_cs>1)
						wendu_cs-=2;
				}
				else
				{
					biangeng_cs++;
					write_24c02(0x00,biangeng_cs);
					if(biangeng_cs>65535)
						biangeng_cs=0;
					if(juli_cs>4)
						juli_cs-=5;
				}
				}
			break;
				
			case 17:
			
				if(xs_mode==1)
				{
					if(xs_cs_mode==0)
				{
					biangeng_cs++;
					write_24c02(0x00,biangeng_cs);
					if(biangeng_cs>65535)
						biangeng_cs=0;
					if(wendu_cs<99)
						wendu_cs+=2;
					if(wendu_cs>99)
						wendu_cs=99;
		
				}
				else
				{
						biangeng_cs++;
					write_24c02(0x00,biangeng_cs);
					if(biangeng_cs>65535)
						biangeng_cs=0;
					if(juli_cs<99)
						juli_cs+=5;
					if(juli_cs>99)
						juli_cs=99;
				}
			}
			break;
		}
	}
	

	
}

void smg_xs()
{
	if(xs_mode==0)//数据界面
	{
			if(xianshi_mode==0)//温度
	{
		smg1[0]=0x39;
		smg1[4]=smg_du[wendu_zhi/1000];smg1[5]=smg_du[wendu_zhi/100%10]|0x80;
		smg1[6]=smg_du[wendu_zhi/10%10];smg1[7]=smg_du[wendu_zhi%10];
	}
	else if(xianshi_mode==1)//距离
	{
		smg2[0]=0x38;
		smg2[6]=smg_du[distance/10];smg2[7]=smg_du[distance%10];
	}
	else if(xianshi_mode==2)//变更参数
	{
		if(biangeng_cs>9999)
		{
			smg3[0]=0xbf;
			smg3[3]=smg_du[biangeng_cs/10000];smg3[4]=smg_du[biangeng_cs/1000%10];
			smg3[5]=smg_du[biangeng_cs/100%10];smg3[6]=smg_du[biangeng_cs/10%10];
			smg3[7]=smg_du[biangeng_cs%10];
		}
		else if(biangeng_cs>999)
		{
			smg3[0]=0xbf;
			smg3[3]=0x00;smg3[4]=smg_du[biangeng_cs/1000];
			smg3[5]=smg_du[biangeng_cs/100%10];smg3[6]=smg_du[biangeng_cs/10%10];
			smg3[7]=smg_du[biangeng_cs%10];
		}
		else if(biangeng_cs>99)
		{
			smg3[0]=0xbf;
			smg3[3]=0x00;smg3[4]=0x00;
			smg3[5]=smg_du[biangeng_cs/100];smg3[6]=smg_du[biangeng_cs/10%10];
			smg3[7]=smg_du[biangeng_cs%10];
		}
		else if(biangeng_cs>9)
		{
			smg3[0]=0xbf;
			smg3[3]=0x00;smg3[4]=0x00;
			smg3[5]=0x00;smg3[6]=smg_du[biangeng_cs/10];
			smg3[7]=smg_du[biangeng_cs%10];
		}
		else if(biangeng_cs<=9)
		{
			smg3[0]=0xbf;
			smg3[3]=0x00;smg3[4]=0x00;
			smg3[5]=0x00;smg3[6]=0x00;
			smg3[7]=smg_du[biangeng_cs%10];
		}
		
	}
	
	}
	else // 参数界面
	{
		if(xs_cs_mode==0)//温度参数
		{
			smg4[0]=0x73;
			smg4[3]=smg_du[1];
			smg4[6]=smg_du[wendu_cs/10];
			smg4[7]=smg_du[wendu_cs%10];
		}
		else // 距离参数
		{
			smg5[0]=0x73;
			smg5[3]=smg_du[2];
			smg5[6]=smg_du[juli_cs/10];
			smg5[7]=smg_du[juli_cs%10];
		}
	}

	
}

void send_byte(u8 dat)
{
	SBUF=dat;
	while(TI==0);//等待发送标志位置1
	TI=0;
}

void sendstring(u8 *s)
{
	while(*s!='\0')
	{
		send_byte(*s++);
	}
}

void timer2() interrupt 4
{

	//发送字符串
	if(RI==1)
	{
		Rdat[recv]=SBUF;
		RI=0;
		recv++;
	}
		
	
	
}

//数字变字符在后面加 ’0‘
void chuankou()
{
	if(Rdat[0]=='S')
	{
		len=3;
	}
	else if(Rdat[0]=='P')
	{
		len=5;
	}
	
	while(Rdat[len]!='\0')
	{
		if(strcmp(Rdat,"ST\r\n")==0)
	{
		send_byte('$');
		send_byte((distance/10)+'0');
		send_byte((distance%10)+'0');
		send_byte(',');
		send_byte((wendu_zhi/1000)+'0');
		send_byte((wendu_zhi/100%10)+'0');
		send_byte('.');
		send_byte((wendu_zhi/10%10)+'0');
		send_byte((wendu_zhi%10)+'0');
		sendstring("\r\n");
		
	}
	else if(strcmp(Rdat,"PARA\r\n")==0)
	{
		send_byte('#');
		send_byte((juli_cs/10)+'0');
		send_byte((juli_cs%10)+'0');
		send_byte(',');
		send_byte((wendu_cs/10)+'0');
		send_byte((wendu_cs%10)+'0');
		sendstring("\r\n");
	}
	else
	{
		sendstring("ERROR");
		sendstring("\r\n");
	}
	
	
	
	clear_Rdat();
	len=0;
	recv=0;
	}
}


void wendu_hs()
{
	wendu_zhi=ra_temprature();
}

void dac_hs()
{
	if(dac_shuchu1)
	{
		write_dac(21);
	}
	else
	{
		if(distance<=juli_cs)
		{
			write_dac(102);
		}
		else
		{
			write_dac(255);
		}
			
	}

}

void led_hs()
{
	
	
	if((wendu_zhi/100)>wendu_cs)
	{
		led_Device(~0x01);
	}
	else
	{led_Device(~0x00);}
	
	Delay5ms();
	Delay12us();
	Delay12us();
	Delay12us();
	Delay12us();
	
	if(distance<juli_cs)
	{
		led_Device(~0x02);
	}
	else
	{led_Device(~0x00);}
	
	Delay5ms();
	Delay12us();
	Delay12us();
	Delay12us();
	Delay12us();
	
	if(dac_shuchu1)
	{
		led_Device(~0x00);
	}
	else
	{
		led_Device(~0x04);
	}
	
}

void clear_Rdat()//清除数组函数
{
	u8 i;
	for(i=0;i<9;i++)
	{
		Rdat[i]='\0';
	}
}


void send_wave()
{
	u8 i;
	for(i=0;i<10;i++)
	{
		TX=1;
		Delay12us();
		TX=0;
		Delay12us();
	}
}

void csb_distance1()
{
	AUXR &= 0xBF;		//定时器时钟12T模式
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0x00;		//设置定时初值
	TH1 = 0x00;		//设置定时初值
	TF1 = 0;		//清除TF0标志
	TR1=0;		//定时器1开始计时
	send_wave();
	TR1=1;
	while(RX==1&&TF1==0);//破案了,这里要加;号,注意注意!
	TR1 = 0;
	
	if(TF1==0)
	{
		timer=(TH1<<8)|TL1;
		distance=timer*0.017;
	}
	else
	{
		TF1=0;
		distance=99;
	}
}

void csb_hs()
{
	if(display_distance==1)
	{
		csb_distance1();
		display_distance=0;
	}
	
	if(distance>99)
		distance=99;
}

u8 read_kbd()
{
	static char key_state=0;
	u8 key_val=0,key_press;
	u8 key1,key2;
	
	P44=1;P42=1;P35=1;P34=1;
	P33=0;P32=0;P31=0;P30=0;
	if(P44==0) key1=0x70;
	else if(P42==0) key1=0xb0;
	else if(P35==0) key1=0xd0;
	else if(P34==0) key1=0xe0;
	else key1=0xf0;
	
	P44=0;P42=0;P35=0;P34=0;
	P33=1;P32=1;P31=1;P30=1;
	if(P33==0) key2=0x07;
	else if(P32==0) key2=0x0b;
	else if(P31==0) key2=0x0d;
	else if(P30==0) key2=0x0e;
	else key2=0x0f;
	
	key_press=key1|key2;
	
	switch(key_state)
	{
		case key_state0:
			if(key_press!=0xff)
				key_state=key_state1;
			break;
			
		case key_state1:
			if(key_press!=0xff)
			{
				if(key_press==0x77) key_val=4;
				else if(key_press==0x7b) key_val=5;
				else if(key_press==0x7d) key_val=6;
				else if(key_press==0x7e) key_val=7;
				
				else if(key_press==0xb7) key_val=8;
				else if(key_press==0xbb) key_val=9;
				else if(key_press==0xbd) key_val=10;
				else if(key_press==0xbe) key_val=11;
				
				else if(key_press==0xd7) key_val=12;
				else if(key_press==0xdb) key_val=13;
				else if(key_press==0xdd) key_val=14;
				else if(key_press==0xde) key_val=15;
				
				else if(key_press==0xe7) key_val=16;
				else if(key_press==0xeb) key_val=17;
				else if(key_press==0xed) key_val=18;
				else if(key_press==0xee) key_val=19;
				
				key_state=key_state2;
			}
			else
				key_state=key_state0;
			break;
			
		case key_state2:
			if(key_press==0xff)
			
			
				key_state=key_state0;
				
				//可以在这里做手脚,实现松开按住显示界面
				
			
				if(j<100)
				j++;
			
				if(j==99)//实现定时长按操作
				{
					biangeng_cs=0;
					j++;
				}
				
				if(z<100)
				z++;
			
				if(z==99)//实现定时长按操作
				{
					dac_shuchu1=~dac_shuchu1;
					z++;
				}

			break;
		}
	return key_val;
}


void Device(u8 p2,u8 p0)
{
	P2=(P2&0X1F)|p2;
	P0=p0;
	P2=P2&0X1F;
}


void led_Device(u8 p3)
{
	P0=0xff;
	Device(0x80,p3);
}
void system_init()
{
	Device(0x80,0xff);
	Device(0xa0,0x00);
	Device(0xc0,0x00);
	Device(0xe0,0xff);
}

void Timer0Init(void)		//1毫秒@11.0592MHz
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0xCD;		//设置定时初值
	TH0 = 0xD4;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0=1;
	EA=1;
}

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

	_nop_();
	_nop_();
	i = 33;
	while (--i);
}
void Delay10ms()		//@12.000MHz
{
	unsigned char i, j;

	i = 117;
	j = 184;
	do
	{
		while (--j);
	} while (--i);
}

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

	i = 59;
	j = 90;
	do
	{
		while (--j);
	} while (--i);
}

void timer00()//ne555定时0的操作
{
	TMOD=0X04;
	TL0=0X00;
	TH0=0X00;
	TF0=0;
	ET0=0;
}

void UartInit(void)		//4800bps@11.0592MHz
{
	SCON = 0x50;		//8位数据,可变波特率
	AUXR |= 0x01;		//串口1选择定时器2为波特率发生器
	AUXR |= 0x04;		//定时器2时钟为Fosc,即1T
	T2L = 0xC0;		//设定定时初值
	T2H = 0xFD;		//设定定时初值
	AUXR |= 0x10;		//启动定时器2
	ES=1;
}

请大家指点批评,谢谢。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值