蓝桥杯单片机第十一届国赛程序设计题--温度时钟【国赛】

第十一届蓝桥杯单片机国赛题(带源码、注释)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#include <STC15F2K60S2.H>
#include <ds1302.h>
#include <IIC.h>
#include <onewire.h>

sbit r1=P3^0;
sbit r2=P3^1;
sbit r3=P3^2;
sbit r4=P3^3;

sbit c1=P3^4;
sbit c2=P3^5;
sbit c3=P4^2;
sbit c4=P4^4;

sbit l1=P0^0;
sbit l2=P0^1;
sbit l3=P0^2;
sbit l4=P0^3;
sbit l5=P0^4;
sbit l6=P0^5;
sbit l7=P0^6;
sbit l8=P0^7;
void read_an3();
unsigned char table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned char Write_ds1302[3]={0x80,0x82,0x84};
unsigned char Read_ds1302[3]={0x81,0x83,0x85};
unsigned char time[3]={0x01,0x20,0x20};
unsigned int key_num=0; //存放按键值

unsigned int temp=0; //存放温度读取值
unsigned char dat=0;  //存放光敏电阻电压值

unsigned char ld_state=0; //亮暗状态标志 0表示亮  1表示暗
unsigned char flag_s4=0; //0显示数据 1显示参数
unsigned char flag_s5=1; //参数显示切换标志  1表示时间 2表示温度 3表示指示灯
unsigned char flag=0; //读取当前小时标志位  

unsigned char h=23; //17的BCD码
unsigned int t=25;  //温度参数设置
unsigned int LED_count=4; //LED参数设置
unsigned int count=0; //定时器计数
unsigned char  flag1_s3=0; //暗状态 超过三秒至1
unsigned char  flag2_s3=0; //亮状态 超过三秒至1


unsigned char f=0;//表示 s4是不是首次按下  1首次按下

/*============================================================
锁存器选择  延时函数
============================================================*/
void delay_ms(int n)
{
	int i,j;
	for(i=n;i>0;i--)
	for(j=110;j>0;j--);
}
void selectHC(unsigned char n)
{
	switch(n)
	{
		case 0: P2=(P2&0x1f)|0x00; break;
		case 4: P2=(P2&0x1f)|0x80; break; //选择LED灯
		case 5: P2=(P2&0x1f)|0xa0; break; //选择蜂鸣器 继电器
		case 6: P2=(P2&0x1f)|0xc0; break; //选择数码管位选
		case 7: P2=(P2&0x1f)|0xe0; break; //选择数码管段选
	}
}

/*============================================================
BCD码加减函数
============================================================*/
unsigned char add(unsigned char dat)
{
	dat = dat + 1;
	switch(dat)
	{
		case 10:
			dat = 16;break;			 //BCD的10
		case 26:
			dat = 32;break;			 //BCD的20
		case 42:
			dat = 48;break;			 //BCD的30
		case 58:
			dat = 64;break;			 //BCD的40
		case 74:
			dat = 80;break;			 //BCD的50
		case 90:
			dat = 96;break;			 //BCD的60
	}
	return dat;
}
unsigned char minus(unsigned char dat)
{
	dat = dat - 1;
	switch(dat)
	{
		case 79:
			dat = 73;break;	   
		case 63:
			dat = 57;break;
		case 47:
			dat = 41;break;
		case 31:
			dat = 25;break;
		case 15:
			dat = 9;break;
		case -1:
			dat = 89;break;		
	}
	return dat;
}

/*============================================================
按键扫描  按键处理
============================================================*/
void scan_key()
{
	//第三行置零 扫描每一列
	r3=0;
	r1=r2=r4=1;
	c1=c2=c3=c4=1;
	if(c4==0) //S5按下
	{
		while(c4==0);
		flag_s5++;
		if(flag_s5>3)
		{
			flag_s5=1;
		}
	}
	else if(c3==0) //s9按下
	{
		while(c3==0);
		if(flag_s5==1&&flag_s4==1)
		{
			h=add(h);
			if(h>35)
			{
				h=0;
			}
		}
		else if(flag_s5==2&&flag_s4==1)
		{
			t++;
			if(t>99)
			{
				t=0;
			}
		}
		else if(flag_s5==3&&flag_s4==1)
		{
			LED_count++;
			if(LED_count>8)
			{
				LED_count=4;
			} 
		}
	}
	
	//第四行置零 扫描每一列
	r4=0;
	r1=r2=r3=1;
	c1=c2=c3=c4=1;
	if(c4==0) //s4按下
	{
		while(c4==0);
		flag_s4++;
		flag_s5=1;
		f++;

		if(flag_s4>1)
		{
			flag_s4=0;
		}
	}
	else if(c3==0) //s8按下
	{
		while(c3==0);
		if(flag_s5==1&&flag_s4==1)
		{
			h=minus(h);
			if(h==0)
			{
				h=0;
			}
		}
		else if(flag_s5==2&&flag_s4==1)
		{
			t--;
			if(t<=0)
			{
				t=0;
			}
		}
		else if(flag_s5==3&&flag_s4==1)
		{
		
			LED_count--;
			if(LED_count<4)
			{
				LED_count=4;
			}
		}
	}
}

/*============================================================
LED显示函数
============================================================*/
void led()
{
	selectHC(4);
	P0=0xff;
	if(flag_s5==1)
	{
		if(h<9)
		{
			selectHC(4);
			if(h/16<time[2]/16<8)
			{
				l1=0;
			}
			else 
			{
				l1=1;
			}
		}
	}
	if(flag_s5==2)
	{
		if(temp<t*10)
		{
			selectHC(4);
			l2=0;
		}
		else
		{
			selectHC(4);
			l2=1;
		}
	}
	if(flag_s5==3)
	{
		read_an3();
		if(ld_state==1)
		{
			selectHC(4);
			TR0=1;
			if(flag1_s3==1)  //超过3秒  定时器计时50ms,60个50ms为3000ms 3S
			{
				l3=0;
				TR0=0;
				//count=0;
			}	
			switch(LED_count)
			{
				case 4:l4=0; break;
				case 5:l5=0; break;
				case 6:l6=0; break;
				case 7:l7=0; break;
				case 8:l8=0; break;
			}
		}
		if(ld_state==0)
		{
			selectHC(4);
			TR0=1;
			if(flag2_s3==1)  //超过3秒  定时器计时50ms,60个50ms为3000ms 3S
			{
				l3=1;
				TR0=0;
				//count=0;
			}	
			l4=l5=l6=l7=l8=1;
		}
	}
}
/*============================================================
定时器相关函数
============================================================*/
void init_timer()
{
	TMOD=0X01;
  TH0=(65536-50000)/256;   
	TL0=(65536-50000)%256;
	ET0=1;
	EA=1;            
	TR0=0;
}
void seviceTimer() interrupt 1
{
	 TH0=(65536-50000)/256;    
	 TL0=(65536-50000)%256;
	 count++;
		if(count==60)  //超过3秒  定时器计时50ms,60个50ms为3000ms 3S
		{
			if(ld_state==0)
			{
				flag1_s3=1;
				count=0;
			}
			if(ld_state==1)
			{
				flag2_s3=1;
				count=0;
			}
    }		
}
/*============================================================
数码管显示相关函数
============================================================*/
void show_bit(unsigned char w,unsigned char n)
{
	selectHC(7);
	P0=0xff;
	selectHC(6);
	P0=0x01<<w-1;
	selectHC(7);
	P0=n;
	delay_ms(1);
}
void show_all(unsigned char n)
{
	selectHC(6);
	P0=0xff;
	selectHC(7);
	P0=n;
	delay_ms(1);
} 
/*============================================================
DS1302时钟显示相关函数
============================================================*/
void init_ds1302()
{
	unsigned char i;
	Write_Ds1302(0x8e,0x00);
	for(i=0;i<3;i++)
	{
		Write_Ds1302(Write_ds1302[i],time[i]);
	}
	Write_Ds1302(0x8e,0x80);
}
void reads_ds1302()
{
	unsigned char j;
	for(j=0;j<3;j++)
	{
		time[j]=Read_Ds1302(Read_ds1302[j]);
	}
}
/*============================================================
温度读取函数
============================================================*/
void read_temp()
{
	unsigned char LSB;
	unsigned char MSB;
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	delay_ms(1);
	
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	
	LSB=Read_DS18B20();
	MSB=Read_DS18B20();
	
	temp=(MSB<<8)|LSB;
	temp=temp*0.0625*10;
}

/*============================================================
AN3通道 光敏电阻电压读取函数
============================================================*/
void decide()
{
	if(dat>=185)
	{
		ld_state=0;
	}
	else if(dat<185)
	{
		ld_state=1;
	}
}
void read_an3()
{
	IIC_Start(); 
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x01); 
	IIC_WaitAck();
	IIC_Stop(); 
	delay_ms(2);
	IIC_Start(); 
	IIC_SendByte(0x91);
	IIC_WaitAck();
	dat=IIC_RecByte(); 
	IIC_Ack(0);
	IIC_Stop(); 
	decide();
	delay_ms(3);
}
/*============================================================
时间数据显示
============================================================*/
void show_time()
{
	reads_ds1302();
	delay_ms(1);
	show_bit(1,table[time[2]/16]);
	show_bit(2,table[time[2]%16]);
	show_bit(3,0xbf);
	show_bit(4,table[time[1]/16]);
	show_bit(5,table[time[1]%16]);
	show_bit(6,0xbf);
	show_bit(7,table[time[0]/16]);
	show_bit(8,table[time[0]%16]);
	show_all(0xff);
}

/*============================================================
温度数据显示
============================================================*/
void show_temp()
{
	  int i=2;
		show_bit(1,0xc6);
		show_bit(6,table[temp/100]);
		show_bit(7,table[temp/10%10]&0x7f);
		show_bit(8,table[temp%10]);
		show_all(0xff);
}

/*============================================================
光敏电阻电压显示函数
============================================================*/
void show_an3()
{
	read_an3();
	show_bit(1,0x86);
	show_bit(3,table[dat/100]&0x7f);
	show_bit(4,table[dat/10%10]);
	show_bit(5,table[dat%10]);
	show_bit(8,table[ld_state]);
	show_all(0xff);
}


/*============================================================
时间参数界面
============================================================*/
void show_p_time()
{
		show_bit(1,0x8c);
		show_bit(2,table[flag_s5]);
		show_bit(7,table[h/16]);
		show_bit(8,table[h%16]);
	  //show_bit(7,table[time[2]/16]);
		//show_bit(8,table[time[2]%16]);
	  show_all(0xff);
}

/*============================================================
温度参数界面
============================================================*/
void show_p_temp()
{
		show_bit(1,0x8c);
		show_bit(2,table[flag_s5]);
	
		show_bit(7,table[t/10]);
		show_bit(8,table[t%10]);
		show_all(0xff);
}

/*============================================================
指示灯参数界面
============================================================*/
void show_p_led()
{
	show_bit(1,0x8c);
	show_bit(2,table[flag_s5]);
	show_bit(8,table[LED_count]);
	show_all(0xff);
}


/*============================================================
显示数据函数
============================================================*/
void show_t_data()
{
	switch(flag_s5)
	{
		case 1:show_time(); break;
		case 2:show_temp(); break;
		case 3:show_an3(); break;
	}
}

/*============================================================
显示参数函数
============================================================*/
void show_p_data()
{
	switch(flag_s5)
	{
		case 1:show_p_time(); break;
		case 2:show_p_temp(); break;
		case 3:show_p_led();break;
	}
}


/*============================================================
数据和参数显示
============================================================*/
void show_all_data()
{
	read_temp();
	if(flag_s4==0)
	{
		show_t_data();
		if(flag==1)
		{
			  //h=time[2];
			  Write_Ds1302(0x8e,0x00);
		    Write_Ds1302(Write_ds1302[2],h);
		    Write_Ds1302(0x8e,0x80);
		}
	}
	else if(flag_s4==1)
	{
		if(flag==0)
		{
			h=time[2];
			flag=1;
		}
		show_p_data();
	}
	led();
}

/*============================================================
主函数
============================================================*/
void main()
{
	selectHC(4);
	P0=0xff;
	selectHC(5);
	P0=0xff;
	init_timer();
	init_ds1302();
	while(1)
	{
		show_all_data();	
		led();
		scan_key();		
	}
}
  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

谏书稀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值