- #include <STC12C5A60S2.h>
- #include <intrins.h>
- //宏定义,11.0592M晶振
- #define uchar unsigned char
- #define uint unsigned int
- #define ulong unsigned long
- //位定义
- sbit a1=P0^0;// 秒按键
- sbit a2=P0^1;//分按键
- sbit a3=P0^2;//时按键
- //数码管显示数组
- uchar code xianshi[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
- 0x80,0x90};//共阳数码管0到9显示BCD码
- //变量声明
- bit Time_FLAG=0;//定义一个时间间隔标志,用来控制写EEPROM间隔时间
- bit Yanshi_FLAG=0;
- uchar Sec;//秒计数定义并初始化变量
- uchar Min;//分计数
- uchar Hour;//时计数
- uchar m=0;//中断计数
- uchar cnt=0;
- //定义IAP/ISP/EEPROM命令
- #define CMD_IDLE 0 //空闲模式
- #define CMD_READ 1 //IAP字节读命令
- #define CMD_PROGRAM 2 //IAP字节编程命令
- #define CMD_ERASE 3 //IAP扇区擦除命令
- #define ENABLE_IAP 0x82 //if SYSCLK<20MHz
- #define IAP_ADDRESS 0x0000 //定义EEPROM地址
- void delay(uint k);//延时函数
- void timechuli();//时间处理函数
- void anjian();//按键扫描函数
- void timexianshi();//时间显示函数
- void IapIdle();
- uchar IapReadunsigned_char(uint addr);
- void IapProgramunsigned_char(uint addr, uchar dat);
- void IapEraseSector(uint addr);
- void Write_EEPROM();
- //----------------------------
- //关闭IAP,初始化函数
- //---------------------------*/
- void IapIdle()
- {
- IAP_CONTR = 0; //关闭IAP功能
- IAP_CMD = 0; //清除命令寄存器
- IAP_TRIG = 0; //清除触发寄存器
- IAP_ADDRH = 0x80; //将地址设置到非IAP区域
- IAP_ADDRL = 0;
- }
- //---------------------------
- //从ISP/IAP/EEPROM区域读取一字节
- //---------------------------
- uchar IapReadunsigned_char(uint addr)
- {
- uchar dat; //数据缓冲区
- IAP_CONTR = ENABLE_IAP; //使能IAP
- IAP_CMD = CMD_READ; //设置IAP命令
- IAP_ADDRL = addr; //设置IAP低地址
- IAP_ADDRH = addr >> 8; //设置IAP高地址
- IAP_TRIG = 0x5a; //写触发命令(0x5a)
- IAP_TRIG = 0xa5; //写触发命令(0xa5)
- _nop_(); //等待ISP/IAP/EEPROM操作完成
- dat = IAP_DATA; //读ISP/IAP/EEPROM数据
- IapIdle(); //关闭IAP功能
- return dat; //返回
- }
- //----------------------------
- //写一字节数据到ISP/IAP/EEPROM区域
- //----------------------------
- void IapProgramunsigned_char(uint addr, uchar dat)
- {
- IAP_CONTR = ENABLE_IAP; //使能IAP
- IAP_CMD = CMD_PROGRAM; //设置IAP命令
- IAP_ADDRL = addr; //设置IAP低地址
- IAP_ADDRH = addr >> 8; //设置IAP高地址
- IAP_DATA = dat; //写ISP/IAP/EEPROM数据
- IAP_TRIG = 0x5a; //写触发命令(0x5a)
- IAP_TRIG = 0xa5; //写触发命令(0xa5)
- _nop_(); //等待ISP/IAP/EEPROM操作完成
- IapIdle();
- }
- //----------------------------
- //扇区擦除
- //---------------------------
- void IapEraseSector(uint addr)
- {
- IAP_CONTR = ENABLE_IAP; //使能IAP
- IAP_CMD = CMD_ERASE; //设置IAP命令
- IAP_ADDRL = addr; //设置IAP低地址
- IAP_ADDRH = addr >> 8; //设置IAP高地址
- IAP_TRIG = 0x5a; //写触发命令(0x5a)
- IAP_TRIG = 0xa5; //写触发命令(0xa5)
- _nop_(); //等待ISP/IAP/EEPROM操作完成
- IapIdle();
- }
- void Write_EEPROM()//将数据写入EEPROM
- {
- IapEraseSector(IAP_ADDRESS); //扇区擦除
- delay(2); //延时
- IapProgramunsigned_char(IAP_ADDRESS,Hour);//写入时
- delay(2); //延时
- IapProgramunsigned_char(IAP_ADDRESS+1,Min);//写入分
- delay(2); //延时
- IapProgramunsigned_char(IAP_ADDRESS+2,Sec); //写入秒
-
-
- }
- void delay(uint k)
- {
- uchar i;
- while((k--)!=0)
- {
- for(i=0;i<100;i++);
-
- }
- }
- void timechuli()
- {
- if(Sec==60)
- {
- Sec=0;
- Min++;
- if(Min==60)
- {
- Min=0;
- Hour++;
- if(Hour==24)
- {Hour=0;}
-
- }
- }
- }
- void delay123(uchar w)
- {
- uchar n;
- for(n=0;n<w;n++)
- {
- timexianshi();
- }
- }
-
- void anjian()
- {
- if(a1==0)
- {
- delay(500);//按键消抖 怎么改成显示的程序
- if(a1==0)
- {
- Sec++;
- if(Sec==60)
- {
- Sec=0;
- Min++;
- }
- }
- }
- if(a2==0)
- {
- delay(500);
- if(a2==0)
- {
- P1=(xianshi[Min%10])|0x80;//显示分的个位
- P2=0x08;
- delay(5);
-
-
- P1=xianshi[Min/10];//显示分的十位
- P2=0x10;
- delay(5);
- Min++;
- if(Min==60)
- {
- Min=0;
- Hour++;
- }
- }
- }
- if(a3==0)
- {
- delay(500);
- if(a3==0)
- {
- Hour++;
- if(Hour==24)
- {
- Hour=0;
- }
- }
- }
- }
- void timexianshi() //P2口位选 P1口段选
- {
- P1=xianshi[Sec%10];//显示秒的个位
- P2=0x01;
- delay(5);
-
-
- P1=xianshi[Sec/10];//显示秒的十位
- P2=0x02;
- delay(5);
-
-
- P1=(xianshi[Min%10])|0x80;//显示分的个位
- P2=0x08;
- delay(5);
-
-
- P1=xianshi[Min/10];//显示分的十位
- P2=0x10;
- delay(5);
-
-
-
- P1=(xianshi[Hour%10])|0x80;//显示时的个位
- P2=0x40;
- delay(5);
-
-
-
- P1=xianshi[Hour/10];//显示时的个位
- P2=0x80;
- delay(5);
-
- }
- void timer0() interrupt 1
- {
- TH0=(65536-45872)/256; //放入初值,11.0592M,50ms
- TL0=(65536-45872)%256;
- m++;
-
- if(m==20)
- {
- m=0;
- Sec++;
- cnt++;
-
- if(cnt==5)
- {
- Time_FLAG = 1;
- cnt=0;
- }
- }
- }
- void main()
- {
- P0=0xff;
- P2=0;
-
- AUXR &= 0x7F; //定时器时钟12T模式
- TMOD &= 0xF0; //设置定时器模式
- TMOD |= 0x01; //设置定时器模式
- TH0=(65536-45872)/256; //放入初值,11.0592M,50ms
- TL0=(65536-45872)%256;
- TF0 = 0; //清除TF0标志
- TR0 = 1; //定时器0开始计时
- EA=1; //开总中断
- EX0=1;
- ET0=1; //开定时器0中断
- //从EEPROM读取时间信息
- Hour = IapReadunsigned_char(IAP_ADDRESS); //小时
- delay(2);
- Min = IapReadunsigned_char(IAP_ADDRESS+1); //分钟
- delay(2);
- Sec = IapReadunsigned_char(IAP_ADDRESS+2); //秒钟
- delay(2);
-
- while(1)
- {
- timexianshi();//时间显示函数
- anjian();//按键扫描函数
- timechuli();//时间处理函数
-
- //每隔一段时间,将Time_FLAG置1,写一次EEPROM,这个时间看你自己需求了
-
- if(Time_FLAG==1)
- {
- Write_EEPROM();//写EEPROM
- Time_FLAG = 0; //写完EEPROM将Time_FLAG标志清0
- }
-
- }
- }
- 这是完整的一个电子时钟,带eeprom一个程序
|