【蓝桥杯】第十三届蓝桥杯单片机国赛 代码程序

第十三届蓝桥杯单片机国赛 程序

题目

历届的省赛和国赛的题目我已经在前面的文章(点击查看)里给大家分享了(网盘资源),需要的话,直接去下载,我在这里就不再赘述了。

hex文件

读者下载这个文件然后用烧录软件直接烧入单片机就可以用了!

有问题直接找我哟。

链接: https://pan.baidu.com/s/1wrezt8BLjP6Uonz5W0NFbQ?pwd=f4cr
提取码: f4cr

代码

main.c

#include "stc15.h"
#include "iic.h"
#define u8 unsigned char
#define u16 unsigned int


//			12:F				13:H			14:A			15:P
u8 code Tab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xbf,0xff,0x8e,0x89,0x88,0x8c};
u8 smg_cnt=0;
u8 disbuff[9];


u8	 key_buf=0;

u16 fre;
u16 fre_tt=0;

u8 mode=1;

u8 dat_rb2=0;


sbit TX=P1^0;
sbit RX=P1^1;
u16 distance=0;
u16 wave_tt=0;
bit wave_flag=1;


u8 fre_canshu=90;
u8 d_canshu=6;
u8 rb2_canshu=40;

u8 fre_canshu_temp=90;
u8 d_canshu_temp=6;
u8 rb2_canshu_temp=40;


u8 set_p=1;


bit set_a=0;
bit set_f=0;


u8 beep_state=0x00;


u8 dis_cnt=0;

u8 pwm=0;
u8 pwm_duty=8;
u8 led_state=0xff;

u8 change=0;

bit d_flag=0;


bit down_long1=0;

u16 down_tt1=0;


bit L1_flag=0;
u16 L1_tt=0;
bit L2_flag=0;
u16 L2_tt=0;
bit L3_flag=0;
u16 L3_tt=0;
//************************ 初始化 程序 ********************************************
void Delay5ms()		//@12.000MHz
{
	unsigned char i, j;

	i = 59;
	j = 90;
	do
	{
		while (--j);
	} while (--i);
}
void Init_System()
{
	P2&=0x1f;
	P0=0xff;
	P2|=0x80;
	P2&=0x1f;

   	P0=0x00;
	P2|=0xa0;
	P2&=0x1f;

	P0=0xff;
	P2|=0xc0;
	P2&=0x1f;

	P0=0xff;
	P2|=0xe0;
	P2&=0x1f;

}
//************************ 数码管 程序 ********************************************
void Timer2Init(void)		//100微秒@12.000MHz
{
	AUXR |= 0x04;		//定时器时钟1T模式
	T2L = 0x50;		//设置定时初值
	T2H = 0xFB;		//设置定时初值
	AUXR |= 0x10;		//定时器2开始计时
	IE2|=0x04;
	EA=1;
}


void Sevice_Timer2() interrupt 12
{
	 P2&=0x1f;
	if(++dis_cnt>=20)
	{
		dis_cnt=0;
	 P0=0xff;
	P2|=0xe0;
	P2&=0x1f;

	P0=1<<smg_cnt;
	P2|=0xc0;
	P2&=0x1f;
	if(mode==4&&set_p==1&&smg_cnt==6)
	  P0=Tab[disbuff[smg_cnt+1]]&0x7f;
	else if(mode==4&&set_p==3&&smg_cnt==6)
	  P0=Tab[disbuff[smg_cnt+1]]&0x7f;
	else if(mode==3&&set_a&&smg_cnt==5)
	  P0=Tab[disbuff[smg_cnt+1]]&0x7f;
	else if(mode==1&&set_f&&smg_cnt==6)
	  P0=Tab[disbuff[smg_cnt+1]]&0x7f;
	else
		P0=Tab[disbuff[smg_cnt+1]];

	P2|=0xe0;
	P2&=0x1f;

	if(++smg_cnt>=8)
	smg_cnt=0;
	}
	
	
	if(!down_long1&&mode==2&&key_buf==0x0e&&++down_tt1>=1000)
	{
		down_tt1=0;
		down_long1=1;
	}

if(++fre_tt>=10000)
	{
		TR0=0;
		fre_tt=0;
		fre=(TH0<<8)+TL0;
	   	TL0 = 0;		//设置定时初值
		TH0 = 0;		//设置定时初值		
		TR0 = 1;		//定时器0开始计时

	}

	if(++wave_tt>=2000)
	{
		wave_tt=0;
		wave_flag=1;
	}
	
	beep_state=0x00;
	
	pwm++;
	if(pwm<=pwm_duty)
	{
		beep_state|=0x20;
		
	}
	else if(pwm<=10)
	{
		
	}
	else
	{
		pwm=1;
		beep_state|=0x20;
	
	}
	if(mode==1)
	{
		if(++L1_tt>=1000)
		{
			L1_tt=0;
			L1_flag=!L1_flag;
		}
	}
	else
	{
		L1_tt=0;
		L1_flag=0;
		
	}
	if(mode==2)
	{
		if(++L2_tt>=1000)
		{
			L2_tt=0;
			L2_flag=!L2_flag;
		}
	}
	else
	{
		L2_tt=0;
		L2_flag=0;
		
	}
	if(mode==3)
	{
		if(++L3_tt>=1000)
		{
			L3_tt=0;
			L3_flag=!L3_flag;
		}
	}
	else
	{
		L3_tt=0;
		L3_flag=0;
		
	}
	
		
		if(distance>d_canshu_temp*10)
		{
			beep_state|=0x10;
			d_flag=1;
		}
		else
		{
			if(d_flag)
			{
				d_flag=0;
				if(change<=255)
					change++;
				
			}
			
		}
		
		P0=beep_state;P2|=0xa0;P0=beep_state;P2&=0x1f;	
	
}
//************************ 频率 程序 ********************************************
void Timer0Init(void)		//1毫秒@12.000MHz
{

	TMOD &= 0xF0;		//设置定时器模式
	TMOD |=0x04;

	TL0 = 0;		//设置定时初值
	TH0 = 0;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
}


void Show_SMG_11()
{
	disbuff[1]=11;
	disbuff[2]=11;
	disbuff[3]=11;
	disbuff[4]=11;
	disbuff[5]=11;
	disbuff[6]=11;
	disbuff[7]=11;
	disbuff[8]=11;
}
void Show_SMG_F()
{
	disbuff[1]=12;
	disbuff[2]=11;
	disbuff[3]=11;
	if(set_f)
	{
		
		
		disbuff[4]=11;
	disbuff[5]=11;
		
		if(fre>=10000)
		disbuff[6]=fre/10000%10;
		else
		disbuff[6]=11;
		
		disbuff[7]=fre/1000%10;
		
		
		disbuff[8]=fre/100%10;
		
		
	}
	else
	{
		if(fre>=10000)
		disbuff[4]=fre/10000%10;
		else
		disbuff[4]=11;
		 if(fre>=1000)
		disbuff[5]=fre/1000%10;
		else
		disbuff[5]=11;
		if(fre>=100)
		disbuff[6]=fre/100%10;
		else
		disbuff[6]=11;
		if(fre>=10)
		disbuff[7]=fre/10%10;
		else
		disbuff[7]=11;
		disbuff[8]=fre%10;
	}
}
void Show_SMG_H()
{
	disbuff[1]=13;
	disbuff[2]=11;
	disbuff[3]=11;
	disbuff[4]=11;
	disbuff[5]=11;
	disbuff[6]=11;
	disbuff[7]=dat_rb2/10%10;
	disbuff[8]=dat_rb2%10;
}
void Show_SMG_A()
{
	disbuff[1]=14;
	disbuff[2]=11;
	disbuff[3]=11;
	disbuff[4]=11;
	disbuff[5]=11;
	if(set_a==0)
	{
	if(distance>=100)
	disbuff[6]=distance/100%10;
	else
	disbuff[6]=11;
	if(distance>=10)
	disbuff[7]=distance/10%10;
	else
	disbuff[7]=11;
	disbuff[8]=distance%10;
	}
	else
	{
		
	disbuff[6]=distance/100%10;
	
	disbuff[7]=distance/10%10;
	
	disbuff[8]=distance%10;
	}
}
void Show_SMG_B()
{
	disbuff[1]=11;
	disbuff[2]=11;
	disbuff[3]=11;
	disbuff[4]=11;
	disbuff[5]=11;
	disbuff[6]=11;
	disbuff[7]=change/10%10;
	disbuff[8]=change%10;
}
void Show_SMG_P()
{
	disbuff[1]=15;
	disbuff[2]=set_p;
	if(set_p==1)
	{
	disbuff[3]=11;
	disbuff[4]=11;
	disbuff[5]=11;
	if(fre_canshu>=100)
	disbuff[6]=fre_canshu/100%10;
	else
	disbuff[6]=11;
	disbuff[7]=fre_canshu/10%10;
	disbuff[8]=fre_canshu%10;
	}
	else if(set_p==2)
	{
	disbuff[3]=11;
	disbuff[4]=11;
	disbuff[5]=11;
	disbuff[6]=11;
	disbuff[7]=rb2_canshu/10%10;
	disbuff[8]=rb2_canshu%10;
	}
	else if(set_p==3)
	{
	disbuff[3]=11;
	disbuff[4]=11;
	disbuff[5]=11;
	disbuff[6]=11;
	disbuff[7]=d_canshu/10%10;
	disbuff[8]=d_canshu%10;
	}
}
void Show_SMG()
{
	if(mode==1)
		Show_SMG_F();
	else if(mode==2)
		Show_SMG_H();
	else if(mode==3)
		Show_SMG_A();
	else if(mode==4)
		Show_SMG_P();
}
//************************ 按键 程序 ********************************************
void Scan_Key()
{
	u8 key_temp;
	key_temp=P3&0x0f;
	if(key_temp!=0x0f&&!key_buf)
	{
		Delay5ms();
		key_temp=P3&0x0f;
		if(key_temp!=0x0f&&!key_buf)
		{
			  key_buf=key_temp;
		}	
	}
	else if(key_temp==0x0f&&key_buf)
	{
		Delay5ms();
		key_temp=P3&0x0f;
		if(key_temp==0x0f&&key_buf)
		{
			  switch(key_buf)
			  {
			  	case 0x07:
						if(mode<=4)
						{
							if(++mode>=5)
							{
								mode=1;
								
								
							}
							if(mode==4)
							{
								set_p=1;
							}
						}
						break;//S4
				case 0x0b:
					if(mode==4)
					{
						if(++set_p>=4)
							set_p=1;
					}
					break;//S5
				case 0x0d:
					if(mode==4)
					{
						if(set_p==1)
						{
							
							fre_canshu+=5;
							if(fre_canshu>120)
								fre_canshu=10;
						}
						else if(set_p==2)
						{
							
							rb2_canshu+=10;
							if(rb2_canshu>60)
								rb2_canshu=10;
						}
						else if(set_p==3)
						{
							
							d_canshu+=1;
							if(d_canshu>12)
								d_canshu=1;
						}
					}
					else if(mode==3)
						set_a=!set_a;
					break;//S6
				case 0x0e:
					
						if(mode==4)
						{
							if(set_p==1)
							{
								
								fre_canshu-=5;
								if(fre_canshu<10)
									fre_canshu=120;
							}
							else if(set_p==2)
							{
								
								rb2_canshu-=10;
								if(rb2_canshu<10)
									rb2_canshu=60;
							}
							else if(set_p==3)
							{
								
								d_canshu-=1;
								if(d_canshu<1)
									d_canshu=12;
							}
						}
						else if(mode==1)
							set_f=!set_f;
						else if(mode==2)
						{
							if(!down_long1)
							{
							}
							else
							{
								change=0;
								Write_AT24C02(0x00,change);Delay5ms(); 
							}
									
						}
						
						
						
				
					
					down_long1=0;
					down_tt1=0;
						break;//S7
					
			}
			  key_buf=0;
		}
			
	}

}
//************************ 超声波模块 ********************************************
void Timer1Init(void)		//12微秒@12.000MHz
{
	AUXR &= 0xBF;		//定时器时钟12T模式
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0xF4;		//设置定时初值
	TH1 = 0xFF;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	TR1 = 0;		//定时器1开始计时
}

void Wave_Distance()
{
	u8 num=10;
	TX=0;
	TL1 = 0xF4;		//设置定时初值
	TH1 = 0xFF;		//设置定时初值
	TR1=1;
	while(num--)
	{
		 while(TF1==0);
		 TF1=0;
		 TX^=1;
	}
	TR1=0;
	TH1=0;
	TL1=0;
	TR1=1;
	while(RX && !TF1);
   	TR1=0;
	if(TF1)
	{
		TF1=0;
		distance=999;
	}
	else
	{
		distance=((TH1<<8)+TL1)*0.017;	
		
	}


}
//************************ 主函数 程序 ********************************************
void main()
{
	Init_System();

	Timer2Init();
	Timer1Init();
	Timer0Init();
	 if(Read_AT24C02(0x3f)!=123)
	{

	
	Write_AT24C02(0x3f,123);Delay5ms(); 
		change=0;
		Write_AT24C02(0x00,change);Delay5ms(); 
 }
	else
	{
		change=Read_AT24C02(0x00);
	}
	
	while(1)
	{
		if(wave_flag)
	{
		wave_flag=0;
		Wave_Distance();
	}
	
		dat_rb2=Read_PCF8591(3)/255.0*5*20;
		dat_rb2=Read_PCF8591(3)/255.0*5*20;
		if(dat_rb2>=99)
			dat_rb2=99;
		
		
		Scan_Key();
		Show_SMG();
		
		if(fre>fre_canshu_temp*1000)
		{
			pwm_duty=8;
		}
		else
			pwm_duty=2;
		Write_AT24C02(0x00,change);Delay5ms(); 
		
		
		if(dat_rb2<=rb2_canshu_temp)
		{
			Write_PCF8591(51);
		}
		else if(dat_rb2<=80)
		{
			
			Write_PCF8591((4.0/(80.0-rb2_canshu_temp)*(dat_rb2-80.0)+5)/5.0*255);
		}
		else
		{
			Write_PCF8591(255);
		}
		
		
		
		led_state=0xff;
		if(L1_flag)
		{
			led_state&=0xfe;
		}
		if(L2_flag)
		{
			led_state&=0xfd;
		}
		if(L3_flag)
		{
			led_state&=0xfb;
		}
		if(fre>fre_canshu_temp*1000)
			led_state&=0xf7;
		
		
		
		if(dat_rb2>rb2_canshu_temp)
			led_state&=0xef;
		if(distance>d_canshu_temp*10)
			led_state&=0xdf;
		P0=led_state;P2|=0x80;P0=led_state;P2&=0x1f;
	}
}

iic.h

#ifndef _IIC_H
#define _IIC_H

#include "stc15.h"
#include "intrins.h"

sbit SDA = P2^1;
sbit SCL = P2^0;

void IIC_Start(void); 
void IIC_Stop(void);  
bit IIC_WaitAck(void);  
void IIC_SendAck(bit ackbit); 
void IIC_SendByte(unsigned char byt); 
unsigned char IIC_RecByte(void); 
unsigned char Read_PCF8591(unsigned char channel);
void Write_AT24C02(unsigned char addr,unsigned char dat);
unsigned char Read_AT24C02(unsigned char addr);
void Write_PCF8591(unsigned char dat);
#endif

iic.c

#include "iic.h"

#define DELAY_TIME 5

//I2C总线内部延时函数
void IIC_Delay(unsigned char i)
{
    do{_nop_();}
    while(i--);        
}

//I2C总线启动信号
void IIC_Start(void)
{
    SDA = 1;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 0;
    IIC_Delay(DELAY_TIME);
    SCL = 0;	
}

//I2C总线停止信号
void IIC_Stop(void)
{
    SDA = 0;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 1;
    IIC_Delay(DELAY_TIME);
}

//发送应答或非应答信号
void IIC_SendAck(bit ackbit)
{
    SCL = 0;
    SDA = ackbit;  					
    IIC_Delay(DELAY_TIME);
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SCL = 0; 
    SDA = 1;
    IIC_Delay(DELAY_TIME);
}

//等待应答
bit IIC_WaitAck(void)
{
    bit ackbit;
	
    SCL  = 1;
    IIC_Delay(DELAY_TIME);
    ackbit = SDA;
    SCL = 0;
    IIC_Delay(DELAY_TIME);
    return ackbit;
}

//I2C总线发送一个字节数据
void IIC_SendByte(unsigned char byt)
{
    unsigned char i;

    for(i=0; i<8; i++)
    {
        SCL  = 0;
        IIC_Delay(DELAY_TIME);
        if(byt & 0x80) SDA  = 1;
        else SDA  = 0;
        IIC_Delay(DELAY_TIME);
        SCL = 1;
        byt <<= 1;
        IIC_Delay(DELAY_TIME);
    }
    SCL  = 0;  
}

//I2C总线接收一个字节数据
unsigned char IIC_RecByte(void)
{
    unsigned char i, da;
    for(i=0; i<8; i++)
    {   
    	SCL = 1;
	IIC_Delay(DELAY_TIME);
	da <<= 1;
	if(SDA) da |= 1;
	SCL = 0;
	IIC_Delay(DELAY_TIME);
    }
    return da;    
}
unsigned char Read_PCF8591(unsigned char channel)
{
	unsigned char temp;
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x40|channel);
	IIC_WaitAck();

	IIC_Start();
	IIC_SendByte(0x91);
	IIC_WaitAck();
	temp=IIC_RecByte();
	IIC_SendAck(1);
	IIC_Stop();



	return temp;
}
unsigned char Read_AT24C02(unsigned char addr)
{
	unsigned char temp;
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(addr);
	IIC_WaitAck();

	IIC_Start();
	IIC_SendByte(0xa1);
	IIC_WaitAck();
	temp=IIC_RecByte();
	IIC_SendAck(1);
	IIC_Stop();



	return temp;
}
void Write_AT24C02(unsigned char addr,unsigned char dat)
{
	
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	IIC_SendByte(addr);
	IIC_WaitAck();
	IIC_SendByte(dat);
	IIC_WaitAck();

	IIC_Stop();

 }	
void Write_PCF8591(unsigned char dat)
{
	
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x40);
	IIC_WaitAck();
	IIC_SendByte(dat);
	IIC_WaitAck();

	IIC_Stop();

}	

工程文件

链接: https://pan.baidu.com/s/1qh6EM_gQYxan_ItxwgJ8FA?pwd=n2ts
提取码: n2ts

B站视频

我在B站发布了自己完成代码的过程,想要了解的朋友可以点击呀,第十三届蓝桥杯单片机国赛

更多资料

需要更多蓝桥杯资料的小可爱,可以关注公众号【玛德花】,回复 蓝桥杯 即可,也随时欢迎需要交流的小伙伴一起讨论呀。
蓝桥杯

省赛

国赛

  • 8
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值