蓝桥杯单片机第十一届国赛程序设计题--温度时钟国赛
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);
/*========================================================以上是关于蓝桥杯单片机第十一届国赛程序设计题--温度时钟国赛的主要内容,如果未能解决你的问题,请参考以下文章