第八届省赛程序设计题--电子钟程序设计蓝桥杯真题—03

Posted 谏书稀

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第八届省赛程序设计题--电子钟程序设计蓝桥杯真题—03相关的知识,希望对你有一定的参考价值。

初始化
  1. 关闭蜂鸣器、继电器等无关外设;
  2. 设备初始化时钟为 23 时 59 分 50 秒,闹钟提醒时间 0 时 0 分 0 秒。
显示功能
  1. 时间显示格式

  2. 温度显示格式

按键功能
  1. 按键 S7 定义为“时钟设置”按键,通过该按键可切换选择待调整的
    时、分、秒,当前选择的显示单元以 1 秒为间隔亮灭,时、分、秒的调整需注意数据边界属性。

  2. 按键 S6 定义为“闹钟设置”按键,通过该按键可进入闹钟时间设置
    功能,数码管显示当前设定的闹钟时间。

  3. 按键 S5 定义为“加”按键,在“时钟设置”或“闹钟设置”状态下,
    每次按下该按键当前选择的单元(时、分或秒)增加 1 个单位。

  4. 按键 S4 定义为“减”按键,在“时钟设置”或“闹钟设置”状态下,

  5. 按键功能说明:
    按键 S4、S5 的“加”、“减”功能只在“时钟设置”或“闹钟设置”
    状态下有效;
    在 “时钟显示”状态下,按下 S4 按键,显示温度数据,松开按键,
    返回“时钟显示”界面。

闹钟提示功能
  1. 指示灯 L1 以 0.2 秒为间隔闪烁,持续 5 秒钟。
  2. 闹钟提示状态下,按下任意按键,关闭闪烁提示功能。
#include <STC15F2K60S2.H>
#include <DS1302.H>
#include <onewire.h>

void delay_ms(int n);

sbit s7=P3^0;
sbit s6=P3^1;
sbit s5=P3^2;
sbit s4=P3^3;
sbit L1=P0^0;
unsigned char table[]=0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xc6;
unsigned char Write_ds1302[7]=0x80,0x82,0x84,0x86,0x88,0x8a,0x8c;
unsigned char Read_ds1302[7]=0x81,0x83,0x85,0x87,0x89,0x8b,0x8d;
unsigned char timer[3]=0x50,0x59,0x23;  //50秒 59分 23时  19日 2月  周五 21年	0x19,0x02,0x05,0x21
unsigned char clock[3]=0x00,0x00,0x00;  //存放闹钟的时间														#include <STC15F2K60S2.H>

unsigned char flag_smg=1;  //控制数码管选中显示闪烁的标志变量,使用定时器空控制其闪烁
unsigned char flag_s7 = 0; //记录S7的当前状态,0为时钟显示,1为设置时钟
unsigned char flag_s6 = 0; //记录S6的当前状态,0为S6未按下,1为设置闹钟的时间
unsigned char count=0; //定时器定时变量
unsigned char temp=0;  //存放温度的值
unsigned char led_c = 0;							   //控制LED的计数变量变量
unsigned char led_f = 0;							   //控制LED闪烁的标志变量
unsigned char led_k = 0;							   //控制led的开关变量,0为关


//===========================定时器0初始化以及服务函数=============================
void Init_timer()

	TMOD=0x01;//定时器0/16位定时器
	TH0=(65536-10000)/256;
	TL0=(65536-10000)%256;
	ET0=1;
	TR0=1;
	EA=1;

void service_timer0() interrupt 1

	TH0=(65536-10000)/256;
	TL0=(65536-10000)%256;
	count++;
	if(count==100) //10ms*100=1s,控制选中的数码管进行闪烁
	
		flag_smg=~flag_smg;
		count=0;
	

	if(led_k==1) //表示打开LED闪烁功能
	
		led_c++; //计算0.2S闪烁
		if(led_c%20==0)	//10ms*20=0.2s,LED闪烁间隔
		
			led_f=~led_f; //闪速标志位取反,达到闪烁
			if(led_c>=500) //闪烁到了5s,停止闪烁
			
				led_k=0;
			    led_c=0;
				led_f=0;
			
		
	


//================================时钟初始化和时间读取函数==================================
void DS1302_Config()

     unsigned char i;
	 Write_Ds1302(0x8e,0x00);
	 for(i=0;i<3;i++)
	 
	 	Write_Ds1302( Write_ds1302[i],timer[i] );
	 
	 Write_Ds1302(0x8e,0x80);

void Read_DS1302_Timer()

	unsigned char j;
	for(j=0;j<3;j++)
	
		timer[j] = Read_Ds1302 ( Read_ds1302[j] );
	


//=================================温度读取函数===================================
void read_temp()

	unsigned char LSB;//温度的低八位
	unsigned char MSB;//温度的高八位
	Init_DS18B20();//1.DS18B20复位
	Write_DS18B20(0xcc);//2.写入字节0XCC,跳过ROM指令
	Write_DS18B20(0x44);//3.写入字节0X44,开始温度转换
    delay_ms(800);		//4.延时700~900ms

	Init_DS18B20();		//5.DS18B20复位
	Write_DS18B20(0xcc);//6.写入字节0XCC,跳过ROM指令
	Write_DS18B20(0xbe);//7.写入字节0XBE,读取温度
    
  	LSB=Read_DS18B20();  //8.读取暂存器的第0字节,即温度数据的LSB
   	MSB=Read_DS18B20();  //9.读取暂存器的第1字节,即温度数据的MSB
    Init_DS18B20();	     //10.DS18B20复位。表示读取数据结束

	temp=MSB;
	temp=(temp<<8)|LSB;
	temp>>=4;


//================================寄存器选择函数==================================
void selectHC(unsigned char n)

	switch(n)
	
		case 4: P2=(P2&0X1f)|0x80; break;
		case 5: P2=(P2&0X1f)|0xa0; break;
		case 6: P2=(P2&0X1f)|0xc0; break;
		case 7: P2=(P2&0X1f)|0xe0; break;
		case 0: P2=(P2&0x1f)|0x00;break;
	


//================================第w个数码管显示n==================================
void show(unsigned char w,unsigned char n)

	selectHC(6);
	P0=0X01<<w;
	selectHC(7);
	P0=table[n];
	delay_ms(5);
	P0=0xff;
	P2&=0x1f;

void allsmg(unsigned char dat)

	selectHC(6);
	P0 = 0xff;
	selectHC(7);
	P0 = dat;
	selectHC(0);	

//================================延时函数==================================
void delay_ms(int n)

	int i,j;
	for(i=n;i>0;i--)
		for(j=110;j>0;j--);


void delay(unsigned int t)

	while(t--);

//================================显示时钟和闹钟函数==================================
void show_timer_clock()

    if(flag_s6==0) //s6未按下,显示的是时钟
	
		if(((flag_smg==1)&&(flag_s7==1))|flag_s7==0|flag_s7==2|flag_s7==3) //
		
			show(1,timer[2]%16); //显示时
			show(0,timer[2]/16);
		
		show(2,10);//显示——
		if(((flag_smg==1)&&(flag_s7==2))|flag_s7==0|flag_s7==1|flag_s7==3)
		
			show(4,timer[1]%16);	//显示分
			show(3,timer[1]/16);
		
		show(5,10);//显示——	
		if(((flag_smg==1)&&(flag_s7==3))|flag_s7==0|flag_s7==2|flag_s7==1)
		
			show(7,timer[0]%16);	//显示秒
			show(6,timer[0]/16);
		
		allsmg(0xff);
	
	else if(flag_s6!=0) //显示闹钟
	
		if(((flag_s6==1)&(flag_smg==1))|(flag_s6==0)|(flag_s6==2)|(flag_s6==3))
		
			show(0,clock[2]/10);
			show(1,clock[2]%10);
		
		show(2,10);
		if(((flag_s6==2)&(flag_smg==1))|(flag_s6==0)|(flag_s6==1)|(flag_s6==3))
		
			show(3,clock[1]/10);
			show(4,clock[1]%10);
		
		show(5,10);
		if(((flag_s6==3)&(flag_smg==1))|(flag_s6==0)|(flag_s6==2)|(flag_s6==1))
		
			show(6,clock[0]/10);
			show(7,clock[0]%10);;
		
		allsmg(0xff);
		


//================================LED灯显示函数==================================
void led_runing()

	if((clock[0]==timer[0]/16)&&(clock[1]==timer[1]/16)&&(clock[2]==timer[2]/16))
	
		led_k=1;
	
	if(led_f==1)
	
		selectHC(4);
		L1=0;  //亮
		selectHC(0);
	  	
	else if(led_f==1)
	
		selectHC(4);
		L1=1; //熄
		selectHC(0);
	


//================================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 show_temp()

	show(5,temp/10);
	delay_ms(1);
	show(6,temp%10);
	delay_ms(1);
	show(7,11);
	delay_ms(1);


//================================按键扫描函数==================================
void keys()

	if(s7==0)
		
		delay(200);
		if (s7==0)
		
			while (s7 == 0)
			
				show_timer_clock();
				led_runing();
				Read_DS1302_Timer();	
			
			if (led_k == 1)
			
				led_k = 0;
				led_c = 0;
				led_f = 0;
			 
			flag_s7++; //flag_s7默认0,0为正常显示时钟
			if (flag_s7 >= 4)
			
				flag_s7 = 0;
			
		
	

	if(s6==0)
		
		delay(200);
		if (s6==0)
		
			while (s6 == 0)
			
				show_timer_clock();
				led_runing();
				Read_DS1302_Timer();	
			
			if (led_k == 1)
			
				led_k = 0<

以上是关于第八届省赛程序设计题--电子钟程序设计蓝桥杯真题—03的主要内容,如果未能解决你的问题,请参考以下文章

第七届省赛程序设计题--模拟风扇控制系统蓝桥杯真题—04

第九届省赛程序设计题--彩灯控制器蓝桥杯真题—02

第八届蓝桥杯(2017年)JavaA组省赛真题解析

第八届蓝桥杯省赛B组 做题记录(python)

第八届蓝桥杯省赛B组 做题记录(python)

第八届蓝桥杯省赛B组 做题记录(python)