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

📄 closetest.c

📁 通过时钟芯片计算按键开关闭合次数和时间
💻 C
📖 第 1 页 / 共 4 页
字号:
#include    <absacc.h>      //包含头文件
#include    <reg51.h>       //包含头文件

typedef unsigned char  byte;   //定义字节
typedef unsigned int   word;   //定义字

#define XTALL 11.0592      //定义晶振频率
#define DLY_1MS (word)(1500*XTALL/12)   //1ms延时计数次数设定

#define SECOND  (*(byte xdata*)0x4000)   //秒
#define MINUTE  (*(byte xdata*)0x4002)   //分
#define HOUR    (*(byte xdata*)0x4004)   //小时
#define DAY     (*(byte xdata*)0x4006)   //天
#define WEEK    (*(byte xdata*)0x4007)   //星期
#define MONTH   (*(byte xdata*)0x4008)   //月
#define YEAR    (*(byte xdata*)0x4009)   //年
#define MCA     (*(byte xdata*)0x400a)   //寄存器A
#define MCB     (*(byte xdata*)0x400b)   //寄存器B
#define MCC     (*(byte xdata*)0x400c)   //寄存器C
#define MCD     (*(byte xdata*)0x400d)   //寄存器D

#define TIMES      ((byte xdata*)0x00) //开关时间及次第保存地址

#define DAY_SUM    ((byte xdata*)0x0500) //继电器闭合总天数
#define PRESS_SUM  ((byte xdata*)0x0501) //继电器闭合总次数        
#define CUR_DAY    ((byte xdata*)0x0502) //上次中断日期

/*byte code ASC2[19][5]={	//各字符对应的ASC2码
		                     {	49,130,131,132,133 }, //1 R L U D_ARROW 
		                     {	50,65,66,67,35 }, //2 A B C #
		                     {	51,68,69,70,63 }, //3 D E F ?
		                     {	52,71,72,73,33 }, //4 G H I !
		                     {	53,74,75,76,60 }, //5 J K L <
		                     {	54,77,78,79,62 }, //6 M N O > 
		                     {	55,80,81,82,83 }, //7 P Q R S
		                     {	56,84,85,86,44 }, //8 T U V ,
		                     {	57,87,88,89,90 }, //9 W X Y Z 
                             {	50,97,98,99,35 }, //2 a b c #
		                     {	51,100,101,102,63 }, //3 d e f ?
		                     {	52,103,104,105,33 }, //4 g h i !
		                     {	53,106,107,108,60 }, //5 j k l <
		                     {	54,109,110,111,62 }, //6 m n o >
		                     {	55,112,113,114,115}, //7 p q r s 
		                     {	56,116,117,118,44 }, //8 t u v ,
		                     {	57,119,120,121,122 }, //9 w x y z
		                     {	41,38,36,32,37}, // $ ¥ 空格  % 
		                     {  48,43,45,47,92 }};//0 + - / \*  */

byte lcddata,datadr,last_day,last_hour,last_minute,key_num,move_num,press_num,days_sum;
byte last_num,timeout,tiancha,check_num,num1,num2,num3;
sbit RS=P3^4;
sbit RW=P3^5;
sbit E=P3^3;
//sbit sqwe_flag=P2^5;
sbit int0_flag=P2^6;
sbit uip_bit=ACC^7;
bit busy_flag,changetime_flag,checktime_flag,key_flag,close_flag,flash_flag,del_flag,daycheck_flag;//sqw_flag;
//////////////////////////////////////////////////////////////////////////
void delay(){//延时子程序
     byte d=8;
	 while(d)d--;
}
void  timer0_isr()  interrupt  1  using 1{      //定时器中断程序入口*/
      TR0=0;                                      //定时1毫秒进入中断*/
      TH0=-(DLY_1MS/256);
      TL0=-(DLY_1MS%256);
       TR0=1;                                       //1毫秒中断次数加1*/   
       num1++;                                         
       if (num1==100)                             //100毫秒定时到*/
         {          
           num1=0;num2++;num3++;
	   }
	   if(num2==5)                                   //500ms延时*/
	      {
		  flash_flag=~flash_flag;num2=0;
	   }
	   if(num3==20){       //2s检测一次日期变化                       
	      daycheck_flag=1;num3=0;
	   }
   }   
void check(){//忙状态检测子程序
     byte d;
     RS=0;
	 RW=1;
	 E=0;
	 E=1;
     d=P1&0x80;
     E=0; 
     if(d!=0) busy_flag=1;
     else busy_flag=0;
}
void check_busy(){//等待直到可以写入
     do{
	    check();
	 }while(busy_flag);
}
void write_data(){//数据写入子程序
     check_busy();
     E=0;
	 RS=1;
	 RW=0;
	 E=1;
     P1=lcddata;
	 E=0;
     delay();
}
void write_dr(){//数据写入地址指定,从0x00---0x13,0x40---0x53
     check_busy();
     E=0;
     RS=0;
     RW=0;
     E=1;
     P1=0x80+datadr;
     E=0;
     delay();
}
void clr_lcd(){//清屏子程序
     check_busy();
     E=0;
	 RS=0;
	 RW=0;
	 E=1;
	 P1=0x01;
	 E=0;
     delay();
}
void set_lcd(){//lcd屏设置为8位,2行,5*7点矩阵
     check_busy();
     RS=0;
	 RW=0;
	 E=1;
	 P1=0x38;
	 E=0;
     delay();
}
void lcd_on(){//lcd屏点亮,显示
     check_busy();
     RS=0;
	 RW=0;
	 E=1;
	 P1=0x0c;
	 E=0;
     delay();
}
void lcd_off(){//lcd屏熄灭,不显示
     check_busy();
     RS=0;
     RW=0;
	 E=1;
	 P1=0x08;
	 E=0;
     delay();
}
void cursor_move(){//光标移动模式设定
     check_busy();
     RS=0;
     RW=0;
	 E=1;
	 P1=0x06;
	 E=0;
} 
void start_lcd(){//lcd初始化
     set_lcd();
     lcd_off();
     cursor_move();
}
void read_initstat(){//时钟芯片忙检测
    do{
	    ACC=MCA;
		}while(uip_bit);
} 
void int0_place(){//继电器按下一次总次数和上次按下时间改变
  byte i,j,a,y,z;
  if(!close_flag){//第一次按下继电器
     last_hour=HOUR;
     last_minute=MINUTE;
	 //MCB=0x80;
     if((*DAY_SUM==0)||(*DAY_SUM==1)){//总天数尚为0,第一次
	    j=*(TIMES+1);//当天的按键次数加1
	    if(j<54){
		    j++;
            *(TIMES+1)=j;
		}	
	    *DAY_SUM=1;
        *TIMES=0;
		i=*PRESS_SUM;
		if(i<54){
		    i++;
		    *PRESS_SUM=i;
		}
		for(z=0;z<2*(*PRESS_SUM);z++){
		    *(TIMES+2*(*PRESS_SUM)+3-z)=*(TIMES+2*(*PRESS_SUM)+1-z);
		}
		*TIMES=0;
		*(TIMES+2)=last_hour;
        *(TIMES+3)=last_minute; 
        //MCB=0x20;
     }
     else if(*DAY_SUM>1){//非第一天
		if((2*(*PRESS_SUM)+2*(*DAY_SUM))<109){
			for(y=0;y<2*(*PRESS_SUM);y++){
			     *(TIMES+2*(*DAY_SUM)+2*(*PRESS_SUM)+1-y)=*(TIMES+2*(*DAY_SUM)+2*(*PRESS_SUM)-1-y);
			}
            *TIMES=0;
            a=*(TIMES+1);
			a++;
			*(TIMES+1)=a;
			y=*PRESS_SUM;
			y++;
			*PRESS_SUM=y;
	    }
        else if((2*(*PRESS_SUM)+2*(*DAY_SUM))>=110){
			for(y=0;y<2*(*PRESS_SUM)-2;y++){
			    *(TIMES+109-y)=*(TIMES+109-2-y);
			}
			z=*(TIMES+2*(*DAY_SUM)-1);
			if(z>1){
			     z--;
                 *(TIMES+2*(*DAY_SUM)-1)=z;
		    }
			else if(z==1){
			     for(y=0;y<2*(*PRESS_SUM-1);y++){
				     *(TIMES+2*(*DAY_SUM-1)+y)=*(TIMES+2*(*DAY_SUM-1)+2+y);
				 }
				 i=*DAY_SUM;
				 i--;
				 *DAY_SUM=i;
                 i=*PRESS_SUM;
				 i--;
				 *PRESS_SUM=i;
			}
			else if(z==0){
			     for(y=0;y<2*(*PRESS_SUM-1);y++){
				     *(TIMES+2*(*DAY_SUM-1)+y)=*(TIMES+2*(*DAY_SUM-1)+2+y);
				 }
				 i=*DAY_SUM;
				 i--;
				 *DAY_SUM=i;
			}
            *TIMES=0;
            a=*(TIMES+1);
            a++;
            *(TIMES+1)=a;
	    }
        *(TIMES+2*(*DAY_SUM))=last_hour;
        *(TIMES+2*(*DAY_SUM)+1)=last_minute;
	}
        
    datadr=0x46;//清除以前的次数10位
    write_dr();
    lcddata=0x20;
    write_data();
    datadr=0x46;//写入新的次数10位
    write_dr();
    lcddata=0x30+*(TIMES+1)/10;
    write_data();
     
    datadr=0x47;//清除以前的次数个位
    write_dr();
    lcddata=0x20;
    write_data();
    datadr=0x47;//写入新的次数个位
    write_dr();
    lcddata=0x30+*(TIMES+1)%10;
    write_data();

    datadr=0x4b;//清除以前的小时纪录十位
    write_dr();
    lcddata=0x20;
    write_data();
    datadr=0x4b;//写入新的小时纪录十位
    write_dr();
    lcddata=0x30+(*(TIMES+2)>>4);
    write_data();
 
    datadr=0x4c;//清除以前的小时记录个位
    write_dr();
    lcddata=0x20;
    write_data();
    datadr=0x4c;//写入新的小时记录个位
    write_dr();
    lcddata=0x30+*(TIMES+2)&0x0f;
    write_data();     

    datadr=0x4e;//清除以前的分钟记录十位
    write_dr();
    lcddata=0x20;
    write_data();
    datadr=0x4e;//写入新的分钟记录十位
    write_dr();
    lcddata=0x30+(*(TIMES+3)>>4);
    write_data();
 
    datadr=0x4f;//清除以前的分钟记录个位
    write_dr();
    lcddata=0x20;
    write_data();//写入新的分钟记录个位 
    datadr=0x4f;
    write_dr();
    lcddata=0x30+*(TIMES+3)&0x0f;
    write_data(); 
    close_flag=1; 
   }
}
void start_initstat(){//时钟芯片初始化
     byte a;
	 MCA=0x20;
	 ACC=MCC;
	 ACC=MCB;
     MCB=0x80;//时钟芯片时钟存储区处理
     if((SECOND>>4)>=6)SECOND=SECOND&0x0f;
     if((SECOND&0x0f)>9)SECOND=((SECOND>>4)<<4);
	 if((MINUTE>>4)>=6)MINUTE=MINUTE&0x0f;
     if((MINUTE&0x0f)>9)MINUTE=((MINUTE>>4)<<4);
	 if(((HOUR>>4)==2)&&((HOUR&0x0f)>3))HOUR=0x00;
	 else if((HOUR>>4)>0x02)HOUR=(HOUR&0x0f);
     else if((HOUR&0x0f)>9)HOUR=(HOUR&0xf0);
	 if((DAY>>4)>3)DAY=0x10;
     if((DAY&0x0f)>9)DAY=1;
	 if(WEEK>=8)WEEK=1; 
	 if((MONTH>>4)>1)MONTH=1;
	 if((MONTH&0x0f)>9)MONTH=1;
	 if((YEAR>>4)>9)YEAR=0;
	 if((YEAR&0x0f)>9)YEAR=0;
     for(a=0;a<=113;a++){//数据改变否?
        if(*(TIMES+a)==0xff)
           *(TIMES+a)=0;
     } 
	 //ACC=MCC;
	 //ACC=MCD;
	 MCB=0x02;   
}
void main_face(){//通常显示主界面 

⌨️ 快捷键说明

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