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

📄 clock.c

📁 c8051F330的一个电子钟
💻 C
字号:
	#include <c8051f330.h>
	#include <intrins.h>

	#define uchar unsigned char
	#define uint unsigned int

	sbit key_h=P1^6;	//小时加
	sbit key_m=P1^7;  //分钟加
//	sbit key_s=P1^6;
	sbit key_alarm=P2^0;   //闹钟

	sbit BEEP=P2^0;      //蜂鸣器输出

	uchar time0[3];    //time0[0]:秒  time0[1]:分 time0[2]:时
	uchar alarm0[3];   //保存闹钟时间
	uchar code  LEDData[ ] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
                          0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0xff }; //段码
	uchar code  LEDData_pot[ ] = {0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78, 
                          0x00,0x10,0x08,0x03,0x46,0x21,0x06,0x0E,0xff }; //断码带小数点

	uchar buf_s=0;    //TIMER2中断计数
	uchar dis_buf[6]; //显示缓存

	sfr16 TMR2RL = 0xCA;                   // Timer2 Reload Register
sfr16 TMR2 = 0xCC;                     // Timer2 Register
	
//*************************************************
//延时子程序
//*************************************************
	delay(int ms){                           // 延时子程序
	  int i;
	  while(ms--){
  	    for(i = 0; i<2000; i++){
   			_nop_();
   			_nop_();
   			_nop_();
   			_nop_();
  		}
	  }
	}
/*************************************************************/
/* 延时 x*0.14ms                                             */
/*************************************************************/

	void delay0(uchar x)    {
 	  unsigned char i;
  	  while(x--){
  		for (i = 0; i<13; i++) {}
 	  }
	}
 /*************************************************************/
/* 蜂鸣器响一声                                              */
/*************************************************************/
	void beep(){
  	  unsigned char i;
  	  for (i=0;i<180;i++){
   		delay0(6);
   		BEEP=!BEEP;       //BEEP取反
      } 
     BEEP=1;           //关闭蜂鸣器
     delay(50);       //延时     
	}
//**************************************************************
//定时器2初始化
//**************************************************************
	void TIMER2_init(){
	  
   CKCON &= ~0x60;                     // Timer2 uses SYSCLK/12
   TMR2CN &= ~0x01;

   TMR2RL = 10000;             // Reload value to be used in Timer2
   TMR2 = TMR2RL;                      // Init the Timer2 register

   TMR2CN = 0x04;                      // Enable Timer2 in auto-reload mode
   ET2 = 1;                            // Timer2 interrupt enabled

/*	  CKCON &= ~0x60;                     // Timer2 uses SYSCLK/12
      TMR2CN &= ~0x01;

      TMR2H=0x00;
      TMR2L=0x00;   

      TMR2RLL = 0x00;             // Reload value to be used in Timer2
      TMR2RLH = 0x00;                      // Init the Timer2 register

   

      TMR2CN = 0x04;                      // Enable Timer2 in auto-reload mode
      ET2 = 1;                            // Timer2 interrupt enabled

    }        */
	}
 /*************************************************************/
 //定时器T2中断
/*************************************************************/
	void Timer2( ) interrupt 5 {
	  buf_s++;
  	  if(buf_s==2){
	    time0[0]++;
		if(time0[0]==60){
		  time0[1]++;
		  time0[0]=0;
		}
		if(time0[1]==60){
		  time0[2]++;
		  time0[1]=0;
		}
		if(time0[2]==24)
		  time0[2]=0;
		buf_s=0;
	  }
	 TF2H=0;
	}
//*************************************************************
//led动态扫描 一次
//************************************************************
	void disp(uchar *p){
	 
	  uchar pos=0xfe;
	  uchar i=0;

	  dis_buf[0]=p[0]%10;
	  dis_buf[1]=p[0]/10;
	   
	  dis_buf[2]=p[1]%10;
	  dis_buf[3]=p[1]/10;

	  dis_buf[4]=p[2]%10;
	  dis_buf[5]=p[2]/10;   


	  for(i=0;i<6;i++){
	    P1=pos;
		if(i==2||i==4)
		  P0=LEDData_pot[dis_buf[i]];
		else
		  P0=LEDData[dis_buf[i]];
		pos=(pos<<1)|0x01;
		delay(1);   
	  }   
	}

//***********************************************************
// 设定小时h 和 分钟m
//************************************************************
	void set_hm(uchar *s){
		uchar i=0;

	    key_h=1;                //扫描小时增加键
		if(key_h==0){
		  delay(1);
 		  if(key_h==0){
 		    s[2]+=1;
		    if(s[2]==24)
 			  s[2]=0;
		  }
		}
		for(i=0;i<8;i++)		//用disp 做延时!
		disp(s);	
		
		key_m=1;			    //扫描分增加键
		if(key_m==0){
		  delay(1);
		  if(key_m==0){
			s[1]+=1;
			if(s[1]==60)
			  s[1]=0;
		  }
		}    
     	for(i=0;i<8;i++)		//用disp 做延时!
		disp(s);	

	}  
//***********************************************************
// 设定秒s  清零
//************************************************************
/*	void set_s(){
	    uchar i=8;
	  	key_s=1;			    //扫描分增加键
		if(key_s==0){
		  delay(1);
		  if(key_s==0)
		    time0[0]=0;
		}
		while(i--)		//用disp 做延时!
		disp(time0);
	}       */

//***********************************************************
//设定闹钟
//************************************************************
 	void set_alarm(){
	  key_alarm=1;
	  if(key_alarm==0){
	    delay(1);
		if(key_alarm==0){
		 while(1){
		    set_hm(alarm0);        //调用设定分钟 小时
			key_alarm=1;
			if(key_alarm==0){      
			  delay(1);
			  if(key_alarm==0)      
			  break;                 //再次按下key_alarm退出设定闹钟
			}
         }
		}
	  }
	}
//***********************************************************
//闹钟检测
//************************************************************
	void check_alarm(){
	uchar i=10;
	if(!(alarm0[1]==0&&alarm0[2]==0)){            //0时0分将被认为闹钟关闭
	  if(alarm0[2]==time0[2]){
	    if(alarm0[1]==time0[1]){
		  if(time0[0]==0){
		    while(1){
			  i=10;
     	      beep();
//		      delay(20);
		      while(i--)
              disp(alarm0);    //显示闹钟时间
			  key_alarm=1;
			  if(key_alarm==0||(alarm0[1]!=time0[1])){    
			    delay(1);
				if(key_alarm==0||(alarm0[1]!=time0[1]))
				  break;               //按下key_alarm或者时间超过1分钟退出
			  }
		    }
		  }
		}
	  }
	}
  }
//***********************************************************
//I/O口初始化
//***********************************************************
	void PORT_init (void){
   	  P0MDIN |= 0xff;                     
   	  P1MDIN |= 0xff;                    

   	  P0MDOUT = 0xff;
   	  P1MDOUT = 0xff;                   

   	  XBR1    = 0xc0;
	                                      
	}
//***********************************************************
//系统时钟频率初始化
//***********************************************************
	void SYSCLK_init(){
	  OSCICL=0x3d;  //20MHZ
      OSCICN=0xc2; // sysclk为内部振荡器得2分频  10mhz
      CLKSEL=0x00;  //chose internal sysclk
	}
//***********************************************************
//主函数
//************************************************************
	main(){
	  PCA0MD&=~0x40;	  

	  PORT_init();
	  SYSCLK_init();
//	  TIMER2_init();
      while(1){	  
        set_hm(time0);
//		set_s();
		set_alarm();
	    check_alarm();
      }
	} 

⌨️ 快捷键说明

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