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

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

题目

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

hex文件

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

有问题直接找我哟。

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

代码

main.c

#include "stc15.h"
#include "ds1302.h"
#include "iic.h"

#define get() (P3&0x3f)|((P4&0x10)<<3)|((P4&0x04)<<4)|0x33
#define u8 unsigned char
#define u16 unsigned int


//			L:12			C:13		F:14		H:15    -:16,17,18			P:19
u8 code Tab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xbf,0xff,
0xc7,0xc6,0x8e,0x89,0xfe,0xbf,0xf7,0x8c};

u8 smg_cnt=0;
u8 disbuff[9];


u8	 key_buf=0;


extern u8 TIME[];


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

u8 time_a[6]={0,2,3,5,7,9};

u8 mode=1;


u8 set_a=1; //


u16 d_max=0;
u16 d_min=0;
u16 d_pingjun=0;


u8 set_c=1;


u8 distance_canshu=20;
u8 set_c_temp=1;


u8 distance_canshu_temp=20;

bit s8_flag=0;//0:触发   1:定时


u8 sec=0;


bit count_first=0;


u8 num=0;

u8 dat_rd1=0;

bit count_first2=0;
bit count_flag2=0;
bit count_flag1=0;

u8 led_state=0xff;


bit rd1_flag=0;


u8 lianxu=0;


bit L5_flag=0;
//************************ 超声波模块 ********************************************
void Timer0Init(void)		//12微秒@12.000MHz
{
	AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0xF4;		//设置定时初值
	TH0 = 0xFF;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 0;		//定时器0开始计时
}
void Wave_Distance()
{
	u8 num=10;
	TX=0;
	TL0 = 0xF4;		//设置定时初值
	TH0 = 0xFF;		//设置定时初值
	TR0=1;
	while(num--)
	{
		 while(TF0==0);
		 TF0=0;
		 TX^=1;
	}
	TR0=0;
	TH0=0;
	TL0=0;
	TR0=1;
	while(RX && !TF0);
   	TR0=0;
	if(TF0)
	{
		TF0=0;
		distance=255;
	}
	else
	{
		distance=((TH0<<8)+TL0)*0.017;	
		
	}


}
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)		//1毫秒@12.000MHz
{
	AUXR |= 0x04;		//定时器时钟1T模式
	T2L = 0x20;		//设置定时初值
	T2H = 0xD1;		//设置定时初值
	AUXR |= 0x10;		//定时器2开始计时
	IE2|=0x04;
	EA=1;
}
void Sevice_Timer2() interrupt 12
{
	 P2&=0x1f;

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

	P0=1<<smg_cnt;
	P2|=0xc0;
	P2&=0x1f;

	if(mode==3&&set_a==3&&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(++wave_tt>=200)
{
	wave_tt=0;
	wave_flag=1;
}



}

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_T()
{
	disbuff[1]=TIME[2]/16;
	disbuff[2]=TIME[2]%16;
	disbuff[3]=10;
	disbuff[4]=TIME[1]/16;
	disbuff[5]=TIME[1]%16;
	disbuff[6]=10;
	disbuff[7]=TIME[0]/16;
	disbuff[8]=TIME[0]%16;
}
void Show_SMG_L()
{
	disbuff[1]=12;
	if(s8_flag==0)
		disbuff[2]=13;
	else if(s8_flag==1)
		disbuff[2]=14;

	disbuff[3]=11;
	disbuff[4]=11;
	disbuff[5]=11;
	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;
}
void Show_SMG_H()
{
	disbuff[1]=15;
	if(set_a==1)
	{
		disbuff[2]=16;
		disbuff[3]=11;
		disbuff[4]=11;

		if(d_max>=1000)
			disbuff[5]=d_max/1000%10;
		else
			disbuff[5]=11;

		if(d_max>=100)
			disbuff[6]=d_max/100%10;
		else
			disbuff[6]=11;
	   	
		 if(d_max>=10)
			disbuff[7]=d_max/10%10;
		 else
			disbuff[7]=11;

		disbuff[8]=d_max%10;

	}

	else if(set_a==2)
	{
		disbuff[2]=18;
		disbuff[3]=11;
		disbuff[4]=11;

		if(d_min>=1000)
			disbuff[5]=d_min/1000%10;
		else
			disbuff[5]=11;

		if(d_min>=100)
			disbuff[6]=d_min/100%10;
		else
			disbuff[6]=11;
	   	
		 if(d_min>=10)
			disbuff[7]=d_min/10%10;
		 else
			disbuff[7]=11;

		disbuff[8]=d_min%10;

	 }
	else if(set_a==3)
	{
		disbuff[2]=17;
		disbuff[3]=11;
		disbuff[4]=11;

		if(d_pingjun>=1000)
			disbuff[5]=d_pingjun/1000%10;
		else
			disbuff[5]=11;

		if(d_pingjun>=100)
			disbuff[6]=d_pingjun/100%10;
		else
			disbuff[6]=11;
	   	
		 if(d_pingjun>=10)
			disbuff[7]=d_pingjun/10%10;
		 else
			disbuff[7]=11;

		disbuff[8]=d_pingjun%10;

	 }


}

void Show_SMG_P()
{
	disbuff[1]=19;
	disbuff[2]=mode-3;
	disbuff[3]=11;
	disbuff[4]=11;
	disbuff[5]=11;
	disbuff[6]=11;
	if(mode==4)
	{
	disbuff[7]=time_a[set_c]/10%10;
	disbuff[8]=time_a[set_c]%10;
	}
	
	else if(mode==5)
	{
	disbuff[7]=distance_canshu/10%10;
	disbuff[8]=distance_canshu%10;
	}
}
void Show_SMG()
{
	if(mode==1)
		 Show_SMG_T();
	else   if(mode==2)
		 Show_SMG_L();
	else   if(mode==3)
		 Show_SMG_H();
	else   if(mode<=5)
		 Show_SMG_P();
}

//Show_SMG()
//{
//	disbuff[1]=11;
//	disbuff[2]=11;
//	disbuff[3]=11;
//	disbuff[4]=11;
//	disbuff[5]=11;
//	disbuff[6]=dat_rd1/100%10;
//	disbuff[7]=dat_rd1/10%10;
//	disbuff[8]=dat_rd1%10;
//}
//************************ 矩阵键盘 ********************************************
void Scan_Key_B()
{
		u8 key_temp;
		P44=1;P42=1;P33=0;P32=0;
		key_temp=get();
		P44=0;P42=0;P33=1;P32=1;
		key_temp|=get();
		if(key_temp!=0xff&&!key_buf)
		{
			Delay5ms();
			P44=1;P42=1;P33=0;P32=0;
		key_temp=get();
		P44=0;P42=0;P33=1;P32=1;
		key_temp|=get();
			if(key_temp!=0xff&&!key_buf)
			{
				key_buf=key_temp;
			}
				
		}
		else if(key_temp==0xff&&key_buf)
		{
			Delay5ms();
			P44=1;P42=1;P33=0;P32=0;
		key_temp=get();
		P44=0;P42=0;P33=1;P32=1;
		key_temp|=get();
			if(key_temp==0xff&&key_buf)
			{
				switch(key_buf)
				{
				


					case 0x77:
					if(mode<=3)
					{
						mode=4;
					}
					else if(mode<=5)
					{
						mode=1;
						distance_canshu_temp=distance_canshu;
						set_c_temp=set_c;
					}
					break;//S4
					case 0x7b:
					if(mode<=3)
					{
						if(++mode>=4)
						mode=1;

						if(mode==3)
						{
							set_a=1;
						}
					}
					else if(mode==4)
					mode=5;
				   else if(mode==5)
					mode=4;
					break;//S5
					case 0xb7:
					if(mode==3)
					{
						if(++set_a>=4)
						set_a=1;
					}
					else if(mode==2)
					{
						s8_flag=!s8_flag;
					}
					break;//S8
					case 0xbb:
					if(mode==4)
					{
						if(++set_c>=6)
							set_c=1;
					}
					else  if(mode==5)
					{

						distance_canshu+=10;
						if(distance_canshu>=90)
							distance_canshu=10;
					}

					break;//S9
					

				}
				key_buf=0;
			}
				
		}

}
void main()
{
	Init_System();
	Timer0Init();
	Timer2Init();
	DS1302_Config();
	while(1)
	{
	   
			
	dat_rd1=Read_PCF8591(1);
	dat_rd1=Read_PCF8591(1);		
	if((dat_rd1>=50))
		rd1_flag=1;
	else
		rd1_flag=0;

	if(!count_first2&&(dat_rd1<=50))
	{
		  count_first2=1;
		  count_flag1=0;
		  count_flag2=1;

	}
	else if(!count_first2&&(dat_rd1>=50))
	{
		  count_first2=1;
		  count_flag1=1;
		  count_flag2=0;

	}
	
	
		
	  Read_Time();

	if(s8_flag==0)
	{
		if(!count_flag2&&(dat_rd1<=50))
		{
			 
			  count_flag1=0;
			  count_flag2=1;


			   Wave_Distance();
			   if(!count_first)
			   {
			   	   count_first=1;
	
				   d_max=distance;
				   d_min=distance;
				   d_pingjun=distance*10;
				   num=1;
			   }
			   else
			   {
			   		num++;
			   		if(d_max<distance)	
					{
						d_max=distance;
					}
					if(d_min>distance)	
					{
						d_min=distance;
					}
	
	
					d_pingjun=((d_pingjun*(num-1))+distance*10.0)/num;
			   }
			   if((distance<=(distance_canshu_temp+5))&&(distance>=(distance_canshu_temp-5)))
			   {
			   		  if(++lianxu>=3)
					  {
					  	L5_flag=1;
					  }
			   }
			   else
			   {
			   	 lianxu=0;
				 L5_flag=0;
			   }
	
	
		}
		else if(!count_flag1&&(dat_rd1>=50))
		{
			  
	
			  count_flag1=1;
			  count_flag2=0;
	
		}
	}
	else 
	{
		if(sec!=TIME[0])
		{
		   sec=TIME[0];
		  if((TIME[0]%time_a[set_c_temp]) ==0)
		  {
		  	   Wave_Distance();
			   if(!count_first)
			   {
			   	   count_first=1;
	
				   d_max=distance;
				   d_min=distance;
				   d_pingjun=distance*10;
				   num=1;
			   }
			   else
			   {
			   		num++;
			   		if(d_max<distance)	
					{
						d_max=distance;
					}
					if(d_min>distance)	
					{
						d_min=distance;
					}
	
	
					d_pingjun=((d_pingjun*(num-1))+distance*10.0)/num;
			   }
			   if((distance<=(distance_canshu_temp+5))&&(distance>=(distance_canshu_temp-5)))
			   {
			   		  if(++lianxu>=3)
					  {
					  	L5_flag=1;
					  }
			   }
			   else
			   {
			   	 lianxu=0;
				 L5_flag=0;
			   }
	
		  }
	
		}

	}  
	if(distance<=10) 
		Write_PCF8591(51);
	else if(distance<=80)
		Write_PCF8591((4/70.0*distance+3/7.0)/5.0*255);
	else
		Write_PCF8591(255);

		Scan_Key_B();
		Show_SMG();


		led_state=0xff;


	if(mode==1)
		led_state&=0xfe;
	if(mode==2)
		led_state&=0xfd;
	if(mode==3)
		led_state&=0xfb;
	if(s8_flag==0)
		led_state&=0xf7;

	if(L5_flag)
		led_state&=0xef;
	if(rd1_flag)
		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"


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_PCF8591(unsigned char dat);
#endif

iic.c

#include "iic.h"

sbit SDA = P2^1;
sbit SCL = P2^0;
#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;
}
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();

}

ds1302.h

#ifndef __DS1302_H
#define __DS1302_H

#include <stc15.h>
#include <intrins.h>

sbit SCK = P1^7;		
sbit SDA = P2^3;		
sbit RST = P1^3; 

void Write_Ds1302(unsigned char temp);
void Write_Ds1302_Byte( unsigned char address,unsigned char dat );
unsigned char Read_Ds1302_Byte( unsigned char address );
void DS1302_Config();
void Read_Time();
#endif

#include "ds1302.h"  									
unsigned char TIME[3]={0x50,0x59,0x23};

unsigned char read_addr[3]={0x81,0x83,0x85};
unsigned char write_addr[3]={0x80,0x82,0x84};
//写字节
void Write_Ds1302(unsigned  char temp) 
{
	unsigned char i;
	for (i=0;i<8;i++)     	
	{ 
		SCK = 0;
		SDA = temp&0x01;
		temp>>=1; 
		SCK=1;
	}
}   

//向DS1302寄存器写入数据
void Write_Ds1302_Byte( unsigned char address,unsigned char dat )     
{
 	RST=0;	_nop_();
 	SCK=0;	_nop_();
 	RST=1; 	_nop_();  
 	Write_Ds1302(address);	
 	Write_Ds1302(dat);		
 	RST=0; 
}

//从DS1302寄存器读出数据
unsigned char Read_Ds1302_Byte ( unsigned char address )
{
 	unsigned char i,temp=0x00;
 	RST=0;	_nop_();
 	SCK=0;	_nop_();
 	RST=1;	_nop_();
 	Write_Ds1302(address);
 	for (i=0;i<8;i++) 	
 	{		
		SCK=0;
		temp>>=1;	
 		if(SDA)
 		temp|=0x80;	
 		SCK=1;
	} 
 	RST=0;	_nop_();
 	SCK=0;	_nop_();
	SCK=1;	_nop_();
	SDA=0;	_nop_();
	SDA=1;	_nop_();
	return (temp);			
}
void DS1302_Config()
{
	unsigned char i;
	Write_Ds1302_Byte(0X8e,0X00);	
	for(i=0;i<=2;i++)
	{
		  Write_Ds1302_Byte(write_addr[i],TIME[i]);
	}
	Write_Ds1302_Byte(0X8e,0X80);	
}

void Read_Time()
{
	unsigned char i;
	
	for(i=0;i<=2;i++)
	{
		  TIME[i]=Read_Ds1302_Byte(read_addr[i]);
	}
	
}

工程文件

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

B站视频

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

更多资料

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

省赛

国赛

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值