第八届蓝桥杯省赛:电子时钟

代码错误预警(逻辑)

###在这里插入图片描述
在这里插入图片描述如果为了图方便
if(mode != 0)
set_clock_f = 1;
else
set_clock_f = 0;
插入到condition函数里面,(第一次按键时,mode++之前就执行这个,就会执行

	      if(set_time_f == 0 || set_clock_f ==1)
{
	set_clock_f = 0; //关闭闹钟设置状态
	mode = 0;
}	

从而mode 一直=0,所以在写一段代码前(特别是长长的牵连的多的)(一定三思而后行,顺序不一样导致的结果也有十分大的不同)

(具体方案是)

写代码之前脑子里就要有一个良好的构思,优化就在一定要从

  1. 功能(实现)
  2. 顺序(会不会影响其他程序)

具体代码

#include<STC15F2K60S2.h>
#include<ds1302.h>
#include<onewire.h>
#define keypress P3
typedef     unsigned char   u8;
typedef     unsigned int    u16;
sbit buzzer = P0^6;

u8 smg_count, smg_i, key_count, menu1[8], menu2[8];
u8 shi, fen, miao;
u8 mode;
u8 code T_duan[] = { 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
u8 code T_COM[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};   
u8 code T_dim[8]= {0};
u8 sshi,ffen,mmiao; //闹钟设置状态下的时间数值
u8 temp;//温度
u8 count_clock, clock_blink_start, clock_blink_time;//闹钟5s开始标志和闪烁时长
bit clock_blink;//闹钟0.2s闪烁标志
bit blink_time;//1s dim/lignt
bit key_flag;
bit set_time_f,set_clock_f;//设置闹钟,时间状态
bit show_smg2 ;
typedef unsigned char BYTE;
typedef unsigned int WORD;
void smgshow();

/* define constants */
#define FOSC 11059200L

#define T1MS (65536-FOSC/12/1000)   //1ms timer calculation method in 12T mode

/* define SFR */
sbit TEST_LED = P1^0;               //work LED, flash once per second

/* define variables */
WORD count;                         //1000 times counter

void tm0_isr() interrupt 1 using 1
{
    TL0 = T1MS;                     
    TH0 = T1MS >> 8;   

	if(count_clock-- == 0)
	{
		count_clock = 200;
		clock_blink = ~clock_blink;
	}
    	
    if (count-- == 0)               
    {
        count = 1000; 
        blink_time = ~blink_time;
			  if(clock_blink_start) 
				{
					clock_blink_time++;
					if(clock_blink_time == 5)
						clock_blink_start = 0; //关闭闹钟响的标志
				}
    }
		//smg part
		 if (smg_count-- == 0)              
    {
        smg_count = 2; 
		
      //  P2 =(P2 & 0x1f)& 0xef;
			  P2 = (P2 & 0x1F) | 0xE0;
			  if( show_smg2 == 0)
			    P0 = ~menu1[smg_i];
				else
					 P0 = ~menu2[smg_i];
			  P2 = 0;
        P2 = 0xc0; 
			  P0 = T_COM[smg_i]; P2 &= 0x1f;
        smg_i++;
        if(smg_i == 8)
 				{
					smg_i = 0;
				}					
    }
		if(key_count--==0)
		{
			key_count = 8;
			key_flag=1;//按键读取标志
			
		}
		
}

u8 trg,cont,readdat;
void keyread()  //
{
	readdat = keypress^0xff;
	trg = readdat & (cont^readdat);
	cont = readdat ;
}

//-----------------------------------------------
//函数声明
void addmode();
void readtime();
void s7condition();
void s6condition();
void add_time() ;
void subtract_time();
void r_wendu();

void main()
{
	  buzzer = 0;
	
	  set_time (23,59,50);
    TMOD = 0x01;                    
    TL0 = T1MS;                     
    TH0 = T1MS >> 8;                
    TR0 = 1;                        
    ET0 = 1;                        
    EA = 1;                         
   count = 0;                     
while(1)
{
  readtime();	//读取实时时间     
 	smgshow(); 
  //r_wendu();//疑惑2:读取温度时间真是太长了
	if( key_flag)  //scan keyread
	{
		key_flag = 0;
		keyread();
		//检测按键情况
		
		if(trg & 0x01)//press s7(时钟设置按钮)
		{
		  s7condition();
			addmode();
			if(mode != 0)
				set_time_f = 1;//表示时钟设置状态
			else
				set_time_f = 0;
		}
		
		if(trg & 0x02) //press s6
		{
      s6condition();//设置兼容性,避免按下s7又按下s6的情况,同时将now time赋值给闹钟设置时间的初始值	
      addmode();	
				if(mode != 0)
			   set_clock_f = 1;
				else
					set_clock_f = 0;				
		}
		
		if(trg & 0x04) //press s5
		{
			add_time();
		}
		 if(trg & 0x08) //press s4
		 {
			 subtract_time();
		 }
		 
		 if( cont & 0x08)
		 {
			 if(mode == 0)
				 show_smg2 = 1;//数码管界面2(温度显示
			 else 
				 show_smg2 = 0;
		 }
	}
   
	if(clock_blink_start) //闹钟在闪烁的标志
	{
		if( trg != 0 )
			clock_blink_start = 0; //close it
	}		
	 		 
}
}




void clock_warn()
{
	if( sshi ==  (shi/16*10)+shi%16 && ffen ==  (fen/16*10)+fen%16 && mmiao ==  (miao/16*10)+miao%16)
	{
		clock_blink_start = 1; //5s的标志
		P2 = 0x80;
		if(clock_blink)  P0 = ~0x01;
		else             P0 = 0x00;
	}
		
}

void r_wendu()
{
		if(blink_time)//read temp
	{
		EA=0;	
		temp = readtemp();
		EA=1;
	}
}


void add_time() //按s5键后不同状态时间数值+1
{

		if(set_time_f)//时间设置状态
		{
			switch(mode)
			{
				case 1: shi = (shi/16*10)+shi%16 + 1; break;//疑惑1:为什么按下s5后有时候时间会变得飞快
				case 2: fen = (fen/16*10+fen%16) + 1; break;
				case 3: miao = (miao/16*10+miao%16) + 1; break;
			}
			EA=0;
			set_time(shi,fen,miao);
			EA=1;
		}
		if(set_clock_f)
		{
			switch(mode)
			{
//				case 1: sshi = (sshi/16*10)+sshi%16 + 1; break;(改1对应
//				case 2: ffen = (ffen/16*10+ffen%16) + 1; break;
//				case 3: mmiao = (mmiao/16*10+mmiao%16) + 1; break;(有问题的原因是第二次弄这个的时候就=将十进制当做BCD码形式再转换一次
				//所以我现在准备将闹钟设置一开始就设置为十进制形式(牵扯到的就有smg
				  case 1: sshi++; if(sshi>23) sshi = 0; break;
					case 2: ffen++; if(ffen>59) ffen = 0; break;
					case 3: mmiao++; if(mmiao>59) mmiao = 0; break;
			}
		}

}
void subtract_time() //按s4键后不同状态时间数值-1
{

		if(set_time_f)//时间设置状态
		{
			switch(mode)
			{
				case 1: shi = (shi/16*10)+shi%16 - 1; break;//疑惑3:为什么0按下s4后变成92
				case 2: fen = (fen/16*10+fen%16) - 1; break;
				case 3: miao = (miao/16*10+miao%16) - 1; break;
			}
			EA=0;
			set_time(shi,fen,miao);
			EA=1;
		}
		if(set_clock_f)
		{
			switch(mode)
			{
				  case 1: sshi--; if(sshi<0) sshi = 23; break;
					case 2: ffen--; if(ffen<0) ffen = 59; break;
					case 3: mmiao--; if(mmiao<0) mmiao = 59; break;
			}
		}

}


void s7condition()
{
      if(set_time_f == 0 || set_clock_f ==1)
			{
				set_clock_f = 0; //关闭闹钟设置状态
				mode = 0;
			}	

}

void s6condition()//设置兼容性,避免按下s7又按下s6的情况,同时将now time赋值给闹钟设置时间的初始值
{
				if(set_clock_f == 0 || set_time_f == 1)//以后对if里的条件要小心又小心
			{
				set_time_f = 0; //关闭时钟设置状态
//				sshi = shi;(改1对应
//				ffen = fen;
//				mmiao = miao;
				mmiao = (miao/16*10+miao%16);
				ffen = (fen/16*10+fen%16);
				sshi = (shi/16*10)+shi%16 ;
				mode = 0;
			}
		
}

void readtime()
{
	EA = 0;
	shi = Read_Ds1302_Byte(0x85);
	fen = Read_Ds1302_Byte(0x83);
	miao = Read_Ds1302_Byte(0x81);   //read current time	
	EA = 1;	
}

void addmode()//按下S7/s6键,模式加1
{
	mode++;
	if(mode == 4)
	 mode = 0;
}

void smgshow()
{
	u8 i;
	for(i = 0; i<5; i++)
	{
		menu2[i] = 0x00;
	}
	 menu2[5] =  T_duan[ temp/10 ];
	 menu2[6] =  T_duan[ temp%10 ];
	 menu2[7] =  0x39;
	if(mode == 0)
	{
	menu1[0] = T_duan[((shi/16*10)+shi%16)/10];                   
	menu1[1] = T_duan[(shi/16*10+shi%16)%10]; 
	menu1[2] = 0x40;
	menu1[3] = T_duan[(fen/16*10+fen%16)/10]; 
	menu1[4] = T_duan[fen%16];
	menu1[5] = 0x40;
	menu1[6] = T_duan[(miao/16*10+miao%16)/10]; 
	menu1[7] = T_duan[(miao/16*10+(miao%16))%10];
	}
	if(mode != 0)  //区分设置zhuangtaihe 显示状态
	{
		for( i = (mode-1)*3; i<(mode*3) ;i++ )
		{
			if(blink_time)  //当前显示单元1秒亮灭
			{
			  menu1[i]=T_dim[i];
				
				P2=0x80;P0=0x55;P2=0;
			}
			else
			{
				if(set_time_f)//时钟设置状态
				{
						P2=0x80;P0=~0x55;P2=0;
					menu1[0] = T_duan[((shi/16*10)+shi%16)/10];                   
					menu1[1] = T_duan[(shi/16*10+shi%16)%10]; 
					menu1[2] = 0x40;
					menu1[3] = T_duan[(fen/16*10+fen%16)/10]; 
					menu1[4] = T_duan[fen%16];
					menu1[5] = 0x40;
					menu1[6] = T_duan[(miao/16*10+miao%16)/10]; 
					menu1[7] = T_duan[(miao/16*10+(miao%16))%10];

				}
				if(set_clock_f)//闹钟设置状态
					{
//					menu1[0] = T_duan[((sshi/16*10)+sshi%16)/10];                   
//					menu1[1] = T_duan[(sshi/16*10+sshi%16)%10]; 
//					menu1[2] = 0x40;
//					menu1[3] = T_duan[(ffen/16*10+ffen%16)/10]; 
//					menu1[4] = T_duan[ffen%16];
//					menu1[5] = 0x40;
//					menu1[6] = T_duan[(mmiao/16*10+miao%16)/10]; 
//					menu1[7] = T_duan[(mmiao/16*10+(mmiao%16))%10];(改1对应,同时注意sshi,ffen..表示一个数值而不是芯片认为的时间了,所以注意临界状态
					menu1[0] = T_duan[sshi/10];                   
					menu1[1] = T_duan[sshi%10]; 
					menu1[2] = 0x40;
					menu1[3] = T_duan[ffen/10]; 
					menu1[4] = T_duan[ffen%10];
					menu1[5] = 0x40;
					menu1[6] = T_duan[mmiao/10]; 
					menu1[7] = T_duan[mmiao%10];
					}
			}
		}
	}
	
}



















//bit key_flag,sz_blink_time=1, sz_flag;

//u8 code T_duan[]={ 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
//u8 code T_COM[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};   

//typedef unsigned char BYTE;
//typedef unsigned int WORD;

-----------------------------------------------

///* define constants */
//#define FOSC 11059200L

//#define T1MS (65536-FOSC/12/1000)   //1ms timer calculation method in 12T mode

///* define SFR */
//sbit TEST_LED = P1^0;               //work LED, flash once per second

///* define variables */
//WORD count;                         //1000 times counter

-----------------------------------------------

///* Timer0 interrupt routine */
//u8 trg,cont,readdat;
//void keyread()
//{
//	readdat=0xff^keypress;
//	trg=readdat&(readdat^cont);
//	cont=readdat;
//}

//void tm0_isr() interrupt 1 using 1
//{
//    TL0 = T1MS;                     //reload timer0 low byte
//    TH0 = T1MS >> 8;                //reload timer0 high byte
//    if (count-- == 0)               //1ms * 1000 -> 1s
//    {
//        count = 1000;   
//        sz_blink_time=~sz_blink_time;			
// 		
//    }
//		//smg part
//		 if (smg_count-- == 0)               //1ms * 1000 -> 1s
//    {
//        smg_count = 3;  
//        P2=0xe0; P0=~menu1[smg_i];P2=0;
//        P2=0xc0; P0=T_COM[smg_i];P2=0;
//        smg_i++;
//        if(smg_i==8)
// 				{
//					smg_i = 0;
//				}					
//    }
//		if(key_count--==0)
//		{
//			key_count = 8;
//			key_flag=1;
//			
//		}
//}

-----------------------------------------------

///* main program */
//void main()
//{
//	buzzer=0;
//	
//	set_time(23,59,50);
//    TMOD = 0x01;                    //set timer0 as mode1 (16-bit)
//    TL0 = T1MS;                     //initial timer0 low byte
//    TH0 = T1MS >> 8;                //initial timer0 high byte
//    TR0 = 1;                        //timer0 start running
//    ET0 = 1;                        //enable timer0 interrupt
//    EA = 1;                         //open global interrupt switch
//    count = 0;                      //initial counter

//    while (1)
//		{
//			     EA=0;
//			shi=Read_Ds1302_Byte (0x85);
//			fen=Read_Ds1302_Byte (0x83);
//			miao=Read_Ds1302_Byte (0x81);
//			    EA=1;	
//			szshi=(shi/16*10+shi%16);
//			szfen=(fen/16*10+fen%16);
//			szmiao=(miao/16*10+miao%16);
//			menu1[0]=T_duan[(shi/16*10+shi%16)/10];  menu1[1]=T_duan[(shi/16*10+shi%16)%10]; menu1[2]=0x40; menu1[3]=T_duan[(fen/16*10+fen%16)/10]; menu1[4]=T_duan[fen%16];
//			menu1[5]=0x40; menu1[6]=T_duan[(miao/16*10+miao%16)/10]; menu1[7]=T_duan[(miao/16*10+(miao%16))%10];
//			if(key_flag)
//			{
//				keyread();
//				key_flag=0;
//			}
//		}
//	}

//				
				switch(trg)
				{
					case 0x01:    sz_flag=1;
						           sz_smg_blink++;
												  if(sz_smg_blink == 4)  
													{
														sz_smg_blink=0;
														sz_flag=0;
													}
										 break;
					case 0x02:break;
					case 0x04: if(sz_flag)
											{
												if(sz_smg_blink ==1)
												{
													szshi++;
													if(szshi>=24) szshi=0;
												}
												if(sz_smg_blink ==2)
												{
													szfen++;
													if(szfen>=61) szfen=0;
												}
												if(sz_smg_blink ==3)
												{
													szmiao++;
													if(szmiao>=61) szmiao=0;
												}
												set_time(szshi,szfen,szmiao);
											}//s5
					case 0x08://s4
						         if(sz_flag)
											{
												if(sz_smg_blink ==1)
												{
													if(szshi>0)
													{
													szshi--;
													}
													else
														szshi=24;
													
												}
												if(sz_smg_blink ==2)
												{
														if(szfen>0)
													szfen--;
													
												}
												if(sz_smg_blink == 3)
												{
														if(szmiao>0)
													szmiao--;
													
												}
												set_time(szshi,szfen,szmiao);
											}break;
					
						         
					break;
				}
				//switch end
				              if(sz_flag)
											{
									       if(sz_smg_blink == 1) 
											 {
												 if(sz_blink_time)
												 {
													 	menu1[0]=0x00;	menu1[1]=0x00; 
				{
					P2=0x80;P0=0x55;P2=0;
				}
					
											   }
												 else
												 {
													 menu1[0]=T_duan[szshi/10];  menu1[1]=T_duan[szshi%10];
												 }
											 }
												 if(sz_smg_blink == 2) 
											 {
												 if(sz_blink_time)
												 {
													 	menu1[3]=0x00;	menu1[4]=0x00; 
											   }
												 else
												 {
                           menu1[3]=T_duan[szfen/10]; 
													 menu1[4]=T_duan[szfen%10];
												 }
											 }
												 
												 if(sz_smg_blink == 3) 
											 {
												 if(sz_blink_time)
												 {
													 	menu1[6]=0x00;	menu1[7]=0x00; 
											   }
												 else
												 {
                           menu1[6]=T_duan[szmiao/10];
													 menu1[7]=T_duan[szmiao%10];
												 }
											 }
										 }
			}
			
		}
}

驱动底层代码

ds1302.c

#include <reg52.h>
#include <intrins.h>

sbit SCK=P1^7;		
sbit SDA=P2^3;		
sbit RST = P1^3;   // DS1302复位												

void Write_Ds1302(unsigned  char temp) 
{
	unsigned char i;
	for (i=0;i<8;i++)     	
	{ 
		SCK=0;
		SDA=temp&0x01;
		temp>>=1; 
		SCK=1;
	}
}   

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; 
}

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 set_time(unsigned char shi,unsigned char fen,unsigned char miao)
{
	Write_Ds1302_Byte(0x8e,0);							//关闭写保护
	Write_Ds1302_Byte(0x80,(miao/10)*16+miao%10);		//以BCD码写入秒数据
	Write_Ds1302_Byte(0x82,(fen/10)*16+fen%10);			//以BCD码写入分数据
	Write_Ds1302_Byte(0x84,(shi/10)*16+shi%10);			//以BCD码写入时数据,这个是10进制转bcd码,然后后面写出的时间是16进制(bcd))转10进制
	Write_Ds1302_Byte(0x8e,0x80);						//打开写保护
}

onewire.c

#include "reg52.h"

sbit DQ = P1^4;  //单总线接口

//单总线延时函数
void Delay_OneWire(unsigned int t)  //STC89C52RC
{ 
	unsigned char i;
	while(t--)
	{
		for(i = 0; i<12; i++);
	}
}

//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		DQ = 0;
		DQ = dat&0x01;
		Delay_OneWire(5);
		DQ = 1;
		dat >>= 1;
	}
	Delay_OneWire(5);
}

//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
	unsigned char i;
	unsigned char dat;
  
	for(i=0;i<8;i++)
	{
		DQ = 0;
		dat >>= 1;
		DQ = 1;
		if(DQ)
		{
			dat |= 0x80;
		}	    
		Delay_OneWire(5);
	}
	return dat;
}

//DS18B20设备初始化
bit init_ds18b20(void)
{
  	bit initflag = 0;
  	
  	DQ = 1;
  	Delay_OneWire(12);
  	DQ = 0;
  	Delay_OneWire(80);
  	DQ = 1;
  	Delay_OneWire(10); 
    initflag = DQ;     
  	Delay_OneWire(5);
  
  	return initflag;
}

unsigned char readtemp()
{
//	unsigned char temp, high, low;
//	init_ds18b20();
//	 Write_DS18B20(0xcc);
//	 Delay_OneWire(5);
//	 Write_DS18B20(0x44);
//	Delay_OneWire(200);
//	
//	
//	init_ds18b20();
//	 Write_DS18B20(0xcc);
//	 Delay_OneWire(5);
//	 Write_DS18B20(0xbe);
//	 Delay_OneWire(5);
//	
//	high = Read_DS18B20();
//	low = Read_DS18B20();
//	temp = high>>4 | low <<4;
//	return temp;
	unsigned char low,high,temp;
init_ds18b20();
Delay_OneWire(1);
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
init_ds18b20();
Delay_OneWire(1);
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
low=Read_DS18B20();//温度数据16位存储,小数部分在低四位,符号在高四位。在此均不需要
high=Read_DS18B20();
high=high<<4;
low=low>>4;
temp=high|low;
return temp;
	
	
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值