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

Posted 谏书稀

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了蓝桥杯单片机第十一届国赛程序设计题--温度时钟国赛相关的知识,希望对你有一定的参考价值。

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




#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);

/*========================================================&#

以上是关于蓝桥杯单片机第十一届国赛程序设计题--温度时钟国赛的主要内容,如果未能解决你的问题,请参考以下文章

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

国赛第十一届国赛程序设计题--温度时钟

蓝桥杯单片机第九届国赛程序设计题--多功能测量仪表国赛

蓝桥杯单片机第十届国赛 部分功能解析

蓝桥杯单片机第十届国赛 部分功能解析

蓝桥杯单片机第十届国赛 部分功能解析