⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 可设置八个闹钟的智能时钟程序
💻 C
📖 第 1 页 / 共 2 页
字号:
//************************************************************************
//    File       : main.c
//    Date       : 2008-08-22    
//    Version    : 1.3  
//    Powerd by  : shenyae86  QQ:184676957
//    modify by  :
//*************************************************************************
//    Descriptoon:                                                              
//              数码管显示程序  显示120000 采用中断扫描模式
//              适用于CC100B、CC100C                             
//              产品网站    http://www.sxcckj.com  传诚科技
//				普通的家用时钟一般只能设置一个闹钟时间,
//				但很多人均需为工作日、周末、早晨、午休等
//				不同时段设置不同的闹钟时间。如果是使用普通的闹钟,
//				只好每次休息前重新设置,很不方便,
//				有时甚至会出现忘记更改闹钟设置而睡过头的情况。
//				针对这种情况,本人利用89C51单片机设计了
//				一款有8种闹钟设置的时钟,通过一段
//				时间的使用,情况良好。
//    help:
//                 参见实验指导书                                                                    
//*************************************************************************
#include <at89x51.h>
#include <intrins.h>

unsigned char hour,min,sec,year,month,day,weekday;   //当前时间、日期、星期
unsigned int  count_down;      //1秒钟计时用
unsigned char code dis_code[]={        
						        0xC0,/*0*/
						        0xF9,/*1*/
						        0xA4,/*2*/
						        0xB0,/*3*/
						        0x99,/*4*/
						        0x92,/*5*/
						        0x82,/*6*/
						        0xF8,/*7*/
						        0x80,/*8*/
						        0x90,/*9*/};//0-9 off 

bit led_on;                     //数码管是否点亮的标志
unsigned char display[8];      	//8位数码管要显示的数据
unsigned char attr;            	//八个数码管的闪烁控制字节,当为0时,对应数码管闪
bit flash;                     	//LED 闪烁开关,与attr共同决定数码管是否闪烁
unsigned char show_status;     	//LED 显示状态标志
// 0:设置闹钟数据
// 1:显示当前日期及星期							
// 2:显示当前时间
// 3:设置当前日期
// 4:设置当前时间

bit km;                      	//按键已去抖动标志
bit kp;                      	//按键已处理标志

bit sound;                  	//蜂鸣器响标志
bit alarm_stop;             	//蜂鸣器响后用户手工按停标志
struct  { 
		unsigned char h;		//小时      
		unsigned char m;		//分钟
       } alarm[8];				//8个闹钟项
unsigned char alarm_en;        	//闹钟项启用标志
unsigned char alarm_wk;         //闹钟项周末启用标志
unsigned char cur_alarm_set;   	//当前设置的闹钟项
unsigned char cur_alarm_active;	//当前到点的闹钟项
bit new_alarm_info;             //闹钟项内容已修改标志

sbit sound_output = P3^7;      	//蜂鸣器驱动端口,输出0时蜂鸣器响
sbit SDA_PIN   = P1^6;    		//EEPROM数据线端口
sbit SCL_PIN   = P1^5;    		//EEPROM时钟线端口
////////////////////////////////////////////////////////////////
void I2cDelay()               	//EEPROM操作时需要的延时函数
{ 
	_nop_(); 
	_nop_();  
	_nop_();
	_nop_();
	_nop_();  
	_nop_(); 
}
///////////////////////////////////////////////////////////////
void DelayX1ms(unsigned char count)		//延迟函数,参数为毫秒数
{
	unsigned char i,j;
 	 for(i=0;i<count;i++)
    	for(j=0;j<240;j++);
}
///////////////////////////////////////////////////////////////
void Start()						//I2C启动,24C08使用I2C方式
{ 
	SDA_PIN=1;   
	I2cDelay(); 
	SCL_PIN=1;   
	I2cDelay();
	SDA_PIN=0;   
	I2cDelay();  
	SCL_PIN=0;    
}
/////////////////////////////////////////////////////////////////////
void Stop()                    	//I2C停止
{ I2cDelay();  SDA_PIN=0;
  I2cDelay();  SCL_PIN=1; 
  I2cDelay();  SDA_PIN=1; 
  I2cDelay();
}
////////////////////////////////////////////////////////////////////
bit SendByte(unsigned char value)	   //发送1字节数据给EEPROM
{unsigned char i;
 bit no_ack=0;

  for(i=0;i<8;i++)                     //发送8位数据
  { I2cDelay();     
if(value&0x80)   SDA_PIN=1;
else            SDA_PIN=0;
    value=value<<1;    	
	I2cDelay();      SCL_PIN=1;         	
	I2cDelay();  	
	I2cDelay();      SCL_PIN=0; 
   }
  
  I2cDelay();        SDA_PIN=1;     //确认脉冲周期,等待EEPROM的确认
  I2cDelay();        SCL_PIN=1;       
  I2cDelay();       
  if(SDA_PIN==1)   no_ack=1;
  I2cDelay();        SCL_PIN=0;

  return no_ack;
}
/////////////////////////////////////////////////////////////////////////
void mywrite(unsigned char address,unsigned char value)		//向EEPROM写1字节
{ 
	Start();          
	SendByte(0xa0);     
	SendByte(address);    
	SendByte(value);  
	Stop();             
	DelayX1ms(10);
}
////////////////////////////////////////////////////////////////////////
unsigned char ReadByte()			//从EEPROM接收1字节
{
  unsigned char i,bval;
  bval=0;
  for(i=0;i<8;i++)					//接收8位数据
   { I2cDelay();
     SDA_PIN=1;            			//从P1输入数据时,先往P1输入"1"
     I2cDelay();    SCL_PIN=1;
     I2cDelay();    bval=bval<<1;     if(SDA_PIN)    bval=bval|0x01;
     I2cDelay();    SCL_PIN=0; 
    }    
	I2cDelay();     SDA_PIN=1; 	//确认脉冲周期,不送出确认
	I2cDelay();     SCL_PIN=1;     
	I2cDelay();      
	I2cDelay();
    return(bval);
}
////////////////////////////////////////////////////////////////////////
unsigned char myread(unsigned char address)		//从EEPROM读入1字节数据
{
  unsigned char tmp;
  Start();        
  SendByte(0xa0);     
  SendByte(address);    
  Start();        
  SendByte(0xa1);     
  tmp=ReadByte();
  Stop();         
  DelayX1ms(2);
  return(tmp);
}
////////////////////////////////////////////////////////////////////////
void SetNext(void)	//轮换调节函数
{
switch(attr)
 { case 0xff: 
			  if(show_status==1)show_status=3;  	//如果当前显示日期 切换到调准日期状态
			  if(show_status==2)show_status=4; 		//如果当前显示时间 切换到调准时间状态
		      attr=0x3f; break;						//第一、二个数码管闪烁
   case 0x3f: attr=0xcf; break;						//第三、四个数码管闪烁
   case 0xcf: attr=0xf3; break;						//第五、六个数码管闪烁
   case 0xf3: if(show_status==0) attr=0xfd;   					//第七个数码管闪烁
              if(show_status==3) {show_status=1; attr=0xff;}  	//恢复正常显示日期
              if(show_status==4) {show_status=2; attr=0xff;}  	//恢复正常显示时间
			  break;
   case 0xfd: if(show_status==0) attr=0xfe;     //第八个数码管闪烁
              break;
   case 0xfe: if(show_status==0) attr=0x3f;     //第一、二个数码管闪烁
 }
}
///////////////////////////////////////////////////////////////////////
void SetInc(void)	//轮换调节函数
{
switch(attr)
	{ 
case 0xff: if(show_status==1) show_status=2;   //在显示时间与日期间切换
		   else if(show_status==2) show_status=1;  
		   break;  
case 0x3f: if(show_status==0) cur_alarm_set=(cur_alarm_set+1)%8;
           else if(show_status==3) 
           year=(year+1)%50;       //当前日期的"年"加1
	       else if(show_status==4) 
           hour=(hour+1)%24;       //当前时间的"时"加1
		   break;    
case 0xcf: if(show_status==0) 	   //闹钟设置的"时"加1
  		   alarm[cur_alarm_set].h=(alarm[cur_alarm_set].h+1)%24;
           else if(show_status==3) 
   			{ 
				month++;                //当前日期的"月"加1
				if(month==13) month=1; 
			} 
	       else if(show_status==4) 
           min=(min+1)%60;         //当前时间的"分"加1
		   break;  
case 0xf3: if(show_status==0) 
           alarm[cur_alarm_set].m=(alarm[cur_alarm_set].m+1)%60;
           else if(show_status==3) 
                      {
						day++;                  //当前日期的"日"加1
                       if(day==32) day=1; }
                       else if(show_status==4) 
                           {
								count_down=8000; 
								sec=(sec+1)%60;
							}        //当前时间的"秒"加1
		                break;                 
case 0xfd: if(show_status==0)alarm_wk^=0x1<<cur_alarm_set;   //周末标志位切换
		   break;
case 0xfe: if(show_status==0)alarm_en^=0x1<<cur_alarm_set;   //启用标志位切换
		   break;
	}       
}
////////////////////////////////////////////////////////////////////////
void SetReduce()
{ 
	char tmp;
	switch(attr)
		     { case 0xff: if(show_status==1 || show_status==2) 
			              led_on=~led_on;        //打开或关闭数码管显示
						  break; 
			   case 0x3f: if(show_status==0)         //如果正在设置闹钟
						   { if(cur_alarm_set==0)  cur_alarm_set=7; 
                             else cur_alarm_set--;}
                        else if(show_status==3)     //当前日期的"年"减1
			               { if(year==0)  year=49;  else year--; }
			            else if(show_status==4)     //当前时间的"时"减1
						   { tmp=hour-1;  if(tmp<0) hour=23;  else  hour=tmp;  }
				          break;
			   case 0xcf: if(show_status==0)          //闹钟设置的"时"减1
						   { tmp=alarm[cur_alarm_set].h-1;
						     if(tmp<0)    alarm[cur_alarm_set].h=23;
							 else         alarm[cur_alarm_set].h=tmp;
							}
                          else if(show_status==3)          
			               { month--;             //当前日期的"月"减1
                             if(month==0)  month=12; }
						  else if(show_status==4)          
                           { tmp=min-1;           //当前时间的"分"减1

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -