• 回复
  • 收藏
  • 点赞
  • 分享
  • 发新帖

电子时钟的制作与学习

电子时钟由8位共阳数码管、stc12c5a60s2单片机、74HC373、74hc245和三个按键组成。单片机的P1口接245并串电阻来驱动数码管的位选,P2口接373来驱动数码管的段选,还有三个按键接P0口来控制时分秒的加减。后续会加上时钟芯片和备用电池做一个真正 的电子时钟。目前这个阶段想加个掉电记忆功能,来学习一下stc的EEPROM功能。

全部回复(23)
正序查看
倒序查看
2016-09-02 11:22
等着看后续更新嘞~
0
回复
2016-09-02 11:26
已经被添加到社区经典图库喽
http://www.dianyuan.com/bbs/classic/
0
回复
2016-09-03 08:28
@电源网-fqd
已经被添加到社区经典图库喽http://www.dianyuan.com/bbs/classic/
好的,希望大家提出好的建议。
0
回复
2016-09-06 17:07
@lihui710884923
好的,希望大家提出好的建议。

    做的怎样了,兄弟,你的电子时钟完成的如何了?

    个人觉得还是比较简单的,不需要自己焊接的,直接买一块开发板,基本上都可以实现的.


0
回复
2016-09-07 08:26
@hello-no1
  做的怎样了,兄弟,你的电子时钟完成的如何了?  个人觉得还是比较简单的,不需要自己焊接的,直接买一块开发板,基本上都可以实现的.
自己搭建电路虽说比较麻烦,学到的东西不少,我刚开始用373驱动数码管,结果就一个数码管显示0,还是微亮,应该是驱动能力不够的额原因,后来加了个245才正常显示了。
0
回复
2016-09-07 08:35
@lihui710884923
自己搭建电路虽说比较麻烦,学到的东西不少,我刚开始用373驱动数码管,结果就一个数码管显示0,还是微亮,应该是驱动能力不够的额原因,后来加了个245才正常显示了。
    驱动数码管经典的常规方法是通过74HC595驱动,我一般均采用这个芯片驱动,效果很好.
0
回复
2016-09-10 10:21
@hello-no1
  驱动数码管经典的常规方法是通过74HC595驱动,我一般均采用这个芯片驱动,效果很好.
#include 
#define uchar unsigned char
#define uint unsigned int
uchar code xianshi[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8, 
	0x80,0x90};//共阳数码管0到9显示BCD码
uchar second=0;//秒计数定义并初始化变量
uchar min=0;//分计数
uchar hour=0;//时计数
uchar m=0;//中断计数
sbit a1=P0^0;// 秒按键
sbit a2=P0^1;//分按键
sbit a3=P0^2;//时按键
void delay(uchar k);//延时函数
void timechuli();//时间处理函数
void anjian();//按键扫描函数
void timexianshi();//时间显示函数
void delay(uchar k)
{
	uchar i;
	while((k--)!=0)
	{
	for(i=0;i<100;i++);
	
	}
}
void timechuli()
{
	if(second==60)
	{
		second=0;
		min++;
		if(min==60)
		{
			min=0;
			hour++;
			if(hour==24)
			{hour=0;}
			
		}
	}
}
void anjian()
{
	if(a1==0)
	{
		delay(30);//按键消抖
		if(a1==0)
		{
		second++;
	}
}
	if(a2==0)
	{
		delay(30);
		if(a2==0)
		{
			min++;
	}
}
	if(a3==0)
	{
		delay(30);
		if(a3==0)
		{
			hour++;
		}
	}
}
	void timexianshi()                                
	{
		P2=0x01;
		P1=xianshi[second%10];//显示秒的个位
		delay(5);
		P2=0x02;
		P1=xianshi[second/10];//显示秒的十位
		delay(5);
		P2=0x08;
		P1=(xianshi[min%10])|0x80;//显示分的个位
		delay(5);
		P2=0x10;
		P1=xianshi[min/10];//显示分的十位
		delay(5);
		P2=0x40;
		P1=(xianshi[hour%10])|0x80;//显示时的个位
		delay(5);
		P2=0x80;
		P1=xianshi[hour/10];//显示时的个位
		delay(5);
	}
	void timer0() interrupt 1
	{
		TH0=(65536-45872)/256;         //放入初值,11.0592M,50ms
	  TL0=(65536-45872)%256;
		m++;
		if(m==20)
		{
			m=0;
			second++;
		}
	}
	void main()
	{
		P0=0xff;
	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中断
	
			while(1)
			{
			timexianshi();//时间显示函数
			anjian();//按键扫描函数
			timechuli();//时间处理函数
			
			}
		}
0
回复
2016-09-10 10:25
@lihui710884923
#include#defineucharunsignedchar#defineuintunsignedintucharcodexianshi[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//共阳数码管0到9显示BCD码ucharsecond=0;//秒计数定义并初始化变量ucharmin=0;//分计数ucharhour=0;//时计数ucharm=0;//中断计数sbita1=P0^0;//秒按键sbita2=P0^1;//分按键sbita3=P0^2;//时按键voiddelay(uchark);//延时函数voidtimechuli();//时间处理函数voidanjian();//按键扫描函数voidtimexianshi();//时间显示函数voiddelay(uchark){uchari;while((k--)!=0){for(i=0;i
这是电子时钟的源代码,写程序时从上到下这种写法咋样,比如开始初始化变量,声明子函数,然后把主函数放到最后写。
0
回复
2016-09-10 23:14
@lihui710884923
#include#defineucharunsignedchar#defineuintunsignedintucharcodexianshi[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//共阳数码管0到9显示BCD码ucharsecond=0;//秒计数定义并初始化变量ucharmin=0;//分计数ucharhour=0;//时计数ucharm=0;//中断计数sbita1=P0^0;//秒按键sbita2=P0^1;//分按键sbita3=P0^2;//时按键voiddelay(uchark);//延时函数voidtimechuli();//时间处理函数voidanjian();//按键扫描函数voidtimexianshi();//时间显示函数voiddelay(uchark){uchari;while((k--)!=0){for(i=0;i
很好,值得我学习。
0
回复
2016-09-12 11:19
帖子已被设置为头条,恭喜楼主可添加电源网私人官网微信(dianyuan_com)为好友,领取现金红包(备注信息:头条红包)

      注:现金红包仅限当日领取

      活动介绍:http://www.dianyuan.com/bbs/1531738.html

     

0
回复
2016-09-15 08:37
@电源网-fqd
帖子已被设置为头条,恭喜楼主可添加电源网私人官网微信(dianyuan_com)为好友,领取现金红包(备注信息:头条红包)     注:现金红包仅限当日领取     活动介绍:http://www.dianyuan.com/bbs/1531738.html     [图片]
我手里有个时钟芯片HT1381,不知程序这块咋写
0
回复
樱桃1号
LV.2
13
2016-09-16 14:37
@lihui710884923
#include#defineucharunsignedchar#defineuintunsignedintucharcodexianshi[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//共阳数码管0到9显示BCD码ucharsecond=0;//秒计数定义并初始化变量ucharmin=0;//分计数ucharhour=0;//时计数ucharm=0;//中断计数sbita1=P0^0;//秒按键sbita2=P0^1;//分按键sbita3=P0^2;//时按键voiddelay(uchark);//延时函数voidtimechuli();//时间处理函数voidanjian();//按键扫描函数voidtimexianshi();//时间显示函数voiddelay(uchark){uchari;while((k--)!=0){for(i=0;i

学习中

0
回复
2016-09-18 11:57
@lihui710884923
我手里有个时钟芯片HT1381,不知程序这块咋写
#include "reg51.h"
#include "intrins.h"

typedef unsigned char BYTE;
typedef unsigned int WORD;

/*Declare SFR associated with the IAP */
sfr IAP_DATA    =   0xC2;           //Flash data register
sfr IAP_ADDRH   =   0xC3;           //Flash address HIGH
sfr IAP_ADDRL   =   0xC4;           //Flash address LOW
sfr IAP_CMD     =   0xC5;           //Flash command register
sfr IAP_TRIG    =   0xC6;           //Flash command trigger
sfr IAP_CONTR   =   0xC7;           //Flash control register

/*Define ISP/IAP/EEPROM command*/
#define CMD_IDLE    0               //Stand-By
#define CMD_READ    1               //Byte-Read
#define CMD_PROGRAM 2               //Byte-Program
#define CMD_ERASE   3               //Sector-Erase

/*Define ISP/IAP/EEPROM operation const for IAP_CONTR*/
//#define ENABLE_IAP 0x80           //if SYSCLK<30MHz
//#define ENABLE_IAP 0x81           //if SYSCLK<24MHz
#define ENABLE_IAP  0x82            //系统工作时钟<20MHz 时,对IAP_CONTR 寄存器设置此值
//#define ENABLE_IAP 0x83           //if SYSCLK<12MHz
//#define ENABLE_IAP 0x84           //if SYSCLK<6MHz
//#define ENABLE_IAP 0x85           //if SYSCLK<3MHz
//#define ENABLE_IAP 0x86           //if SYSCLK<2MHz
//#define ENABLE_IAP 0x87           //if SYSCLK<1MHz

//Start address for STC11/10xx EEPROM
#define IAP_ADDRESS 0x0400

void Delay(BYTE n);//延时用
void IapIdle();//关闭iap
BYTE IapReadByte(WORD addr);
void IapProgramByte(WORD addr, BYTE dat);
void IapEraseSector(WORD addr);

void eep_main()
{
    WORD i;

    P1 = 0xfe;                      //1111,1110 System Reset OK
    Delay(10);                      //Delay
    IapEraseSector(IAP_ADDRESS);    //Erase current sector
    for (i=0; i<512; i++)           //Check whether all sector data is FF
    {
        if (IapReadByte(IAP_ADDRESS+i) != 0xff)
            goto Error;             //If error, break
    }
    P1 = 0xfc;                      //1111,1100 Erase successful
    Delay(10);                      //Delay
    for (i=0; i<512; i++)           //Program 512 bytes data into data flash
    {
        IapProgramByte(IAP_ADDRESS+i, (BYTE)i);
    }
    P1 = 0xf8;                      //1111,1000 Program successful
    Delay(10);                      //Delay
    for (i=0; i<512; i++)           //Verify 512 bytes data
    {
        if (IapReadByte(IAP_ADDRESS+i) != (BYTE)i)
            goto Error;             //If error, break
    }
    P1 = 0xf0;                      //1111,0000 Verify successful
    while (1);
Error:
    P1 &= 0x7f;                     //0xxx,xxxx IAP operation fail
    while (1);
}

/*----------------------------
Software delay function
----------------------------*/
void Delay(BYTE n)
{
    WORD x;

    while (n--)
    {
        x = 0;
        while (++x);
    }
}

/*----------------------------
Disable ISP/IAP/EEPROM function
Make MCU in a safe state
----------------------------*/
void IapIdle()//关闭IAP
{
    IAP_CONTR = 0;                  //Close IAP function
    IAP_CMD = 0;                    //Clear command to standby
    IAP_TRIG = 0;                   //Clear trigger register
    IAP_ADDRH = 0x80;               //Data ptr point to non-EEPROM area
    IAP_ADDRL = 0;                  //Clear IAP address to prevent misuse
}

/*----------------------------
Read one byte from ISP/IAP/EEPROM area
Input: addr (ISP/IAP/EEPROM address)
Output:Flash data
----------------------------*/
BYTE IapReadByte(WORD addr)//读EEPROM数据
{
    BYTE dat;                       //Data buffer

    IAP_CONTR = ENABLE_IAP;         //Open IAP function, and set wait time
    IAP_CMD = CMD_READ;             //Set ISP/IAP/EEPROM READ command
    IAP_ADDRL = addr;               //Set ISP/IAP/EEPROM address low
    IAP_ADDRH = addr >> 8;          //Set ISP/IAP/EEPROM address high
    IAP_TRIG = 0x5a;                //Send trigger command1 (0x5a)
    IAP_TRIG = 0xa5;                //Send trigger command2 (0xa5)
    _nop_();                        //MCU will hold here until ISP/IAP/EEPROM operation complete
    dat = IAP_DATA;                 //Read ISP/IAP/EEPROM data
    IapIdle();                      //Close ISP/IAP/EEPROM function

    return dat;                     //Return Flash data
}

/*----------------------------
Program one byte to ISP/IAP/EEPROM area
Input: addr (ISP/IAP/EEPROM address)
       dat (ISP/IAP/EEPROM data)
Output:-
----------------------------*/
void IapProgramByte(WORD addr, BYTE dat)
{
    IAP_CONTR = ENABLE_IAP;         //Open IAP function, and set wait time
    IAP_CMD = CMD_PROGRAM;          //Set ISP/IAP/EEPROM PROGRAM command
    IAP_ADDRL = addr;               //Set ISP/IAP/EEPROM address low
    IAP_ADDRH = addr >> 8;          //Set ISP/IAP/EEPROM address high
    IAP_DATA = dat;                 //Write ISP/IAP/EEPROM data
    IAP_TRIG = 0x5a;                //Send trigger command1 (0x5a)
    IAP_TRIG = 0xa5;                //Send trigger command2 (0xa5)
    _nop_();                        //MCU will hold here until ISP/IAP/EEPROM operation complete
    IapIdle();
}

/*----------------------------
Erase one sector area
Input: addr (ISP/IAP/EEPROM address)
Output:-
----------------------------*/
void IapEraseSector(WORD addr)//擦除扇区
{
    IAP_CONTR = ENABLE_IAP;         //Open IAP function, and set wait time
    IAP_CMD = CMD_ERASE;            //Set ISP/IAP/EEPROM ERASE command
    IAP_ADDRL = addr;               //Set ISP/IAP/EEPROM address low
    IAP_ADDRH = addr >> 8;          //Set ISP/IAP/EEPROM address high
    IAP_TRIG = 0x5a;                //Send trigger command1 (0x5a)
    IAP_TRIG = 0xa5;                //Send trigger command2 (0xa5)
    _nop_();                        //MCU will hold here until ISP/IAP/EEPROM operation complete
    IapIdle();
}
0
回复
2016-09-18 12:00
@lihui710884923
#include"reg51.h"#include"intrins.h"typedefunsignedcharBYTE;typedefunsignedintWORD;/*DeclareSFRassociatedwiththeIAP*/sfrIAP_DATA=0xC2;//FlashdataregistersfrIAP_ADDRH=0xC3;//FlashaddressHIGHsfrIAP_ADDRL=0xC4;//FlashaddressLOWsfrIAP_CMD=0xC5;//FlashcommandregistersfrIAP_TRIG=0xC6;//FlashcommandtriggersfrIAP_CONTR=0xC7;//Flashcontrolregister/*DefineISP/IAP/EEPROMcommand*/#defineCMD_IDLE0//Stand-By#defineCMD_READ1//Byte-Read#defineCMD_PROGRAM2//Byte-Program#defineCMD_ERASE3//Sector-Erase/*DefineISP/IAP/EEPROMoperationconstforIAP_CONTR*///#defineENABLE_IAP0x80//ifSYSCLK
这是掉电记忆功能的例程,我想把电子时钟断电的数据保存,不知道保存那个数据,怎么把这个数据加到这个例程里
0
回复
2016-09-26 10:22
@lihui710884923
这是掉电记忆功能的例程,我想把电子时钟断电的数据保存,不知道保存那个数据,怎么把这个数据加到这个例程里
E2prom程序这几天就出来,非常期待,正在验证
0
回复
sheng_ge520
LV.2
17
2016-09-27 16:19
@lihui710884923
这是电子时钟的源代码,写程序时从上到下这种写法咋样,比如开始初始化变量,声明子函数,然后把主函数放到最后写。
本来就是这样的顺序
0
回复
sheng_ge520
LV.2
18
2016-09-27 16:28
@lihui710884923
E2prom程序这几天就出来,非常期待,正在验证

有现成的,其它无关的程序已经删除,IC为HT46F47E,其它IC只需要做些相应的变化

//EECR
#define _cs			_02_4
#define _sk			_02_5
#define _di			_02_6
#define _do			_02_7
uchar _EECR			@0x40;

uchar Shift(uchar buf, uchar cnt)
{
	do
	{
		if(buf & 0x80)
			_di = 1;
		else
			_di = 0;
		
		_sk = 1;
	
		buf<<=1;

		if(_do)
			buf |= 0x01;
		else
			buf &= 0xfe;

		
		_sk = 0;
	
	}while(--cnt);
	
	return buf;
}

//==============================================================================
//Subroutine:	ChkBusy
//Function:		
//==============================================================================
void ChkBusy(void)
{
	_cs = 1;

	while(1)
	{
		_nop();
		_nop();
		_sk = 1;
		_nop();
		if(_do)
			break;
			
		_nop();
		_sk = 0;
	}
	
	_sk = 0;
	_cs = 0;
}	

void EWEN()
{	
	_cs = 1;
	
	Shift(0x80,3);			//OP Code
	Shift(0xc0,7);
	
	_cs = 0;

}
void EWDS()
{
	_cs = 1;
	
	Shift(0x80,3);			//OP Code
	Shift(0x00,7);
	
	_cs = 0;
}
void WRITE(uchar EEADDR,uchar EEDATA)
{	
	_cs = 1;
	
	Shift(0xa0,3);			//OP Code
	EEADDR<<=1;	
	Shift(EEADDR,7);			//Address
	Shift(EEDATA,8);			//Address
//	Shift(minute,8);			//Address	
//	Shift(hour,8);			//Address
//	Shift(day,8);			//Address	
	_cs = 0;
	
	ChkBusy();
}
uchar READ(uchar EEADDR)
{	uchar EEDATA;
	uchar cnt;
	cnt=8;
	_cs = 1;
	
	Shift(0xc0,3);				//OP Code
	EEADDR<<=1;
	Shift(EEADDR,7);			//Address
	EEDATA = Shift(0x00,8);

//	minute = Shift(0x00,8);

//	hour = Shift(0x00,8);	

//	day = Shift(0x00,8);	
	_cs = 0;
	return(EEDATA);	
}

void motor_control()
{if(timeout==0) 
			{	_bp = 1;
				_mp1 = 0x40;
				EWEN();
				_clrwdt();

				WRITE(2,minute);
				WRITE(3,hour);
				WRITE(4,day);

				_clrwdt();		
				EWDS();
			}
}
//******************************************************
//**********************祘**************************
void main()
{

	safeguard_init();
	for(_mp0=0x40;_mp0<0xff;_mp0++)
	{_iar0=0;}
	user_init();
	_clrwdt();
	_bp = 1;
	_mp1 = 0x40;
	EWEN();
	_clrwdt();
	minute=READ(2);
	hour=READ(3);
	day=READ(4);
	_clrwdt();		
	EWDS();

}

0
回复
2016-09-29 08:21
@sheng_ge520
有现成的,其它无关的程序已经删除,IC为HT46F47E,其它IC只需要做些相应的变化//EECR#define_cs_02_4#define_sk_02_5#define_di_02_6#define_do_02_7uchar_EECR@0x40;ucharShift(ucharbuf,ucharcnt){do{if(buf&0x80)_di=1;else_di=0;_sk=1;buf
好的非常感谢
0
回复
2016-09-29 21:45
@lihui710884923
好的非常感谢
你要是用e2prom的话,每隔一段时间写一次e2prom的话,这样写的频率太高了,就一万次,这样寿命大大缩减,断电瞬间去保存最好了
0
回复
2016-10-09 21:50
@liuxiaofei126
你要是用e2prom的话,每隔一段时间写一次e2prom的话,这样写的频率太高了,就一万次,这样寿命大大缩减,断电瞬间去保存最好了
断电瞬间要加大电容才可以保存数据
0
回复
2016-10-12 08:40
@lihui710884923
断电瞬间要加大电容才可以保存数据
#include 
#include 

//宏定义,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间隔时间
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(uchar 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(uchar 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 anjian()
{
	if(a1==0)
	{
		delay(30);//按键消抖
		if(a1==0)
		{
		Sec++;
	}
}
	if(a2==0)
	{
		delay(30);
		if(a2==0)
		{
			Min++;
	}
}
	if(a3==0)
	{
		delay(30);
		if(a3==0)
		{
			Hour++;
		}
	}
}
	void timexianshi()         //P2口位选 P1口段选                       
	{
		P2=0x01;
		P1=xianshi[Sec%10];//显示秒的个位
		delay(5);
		P2=0x02;
		P1=xianshi[Sec/10];//显示秒的十位
		delay(5);
		P2=0x08;
		P1=(xianshi[Min%10])|0x80;//显示分的个位
		delay(5);
		P2=0x10;
		P1=xianshi[Min/10];//显示分的十位
		delay(5);
		P2=0x40;
		P1=(xianshi[Hour%10])|0x80;//显示时的个位
		delay(5);
		P2=0x80;
		P1=xianshi[Hour/10];//显示时的个位
		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;
	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的程序,大家可以借鉴一下,希望亲们指出缺点,非常感谢

0
回复
于豆豆
LV.4
23
2016-10-13 17:58

1.在main函数第一句加上P2=0;

2. timexianshi() 改为:   

         P1=xianshi[second%10];//显示秒的个位     

              P2=0x01;

delay(5);

P2=0x0;

P1=xianshi[second/10];//显示秒的十位

P2=0x02;delay(5);

P2=0x0;..................

0
回复
2016-10-14 13:28
@于豆豆
1.在main函数第一句加上P2=0;2.timexianshi()改为:       P1=xianshi[second%10];//显示秒的个位           P2=0x01;delay(5);P2=0x0;P1=xianshi[second/10];//显示秒的十位P2=0x02;delay(5);P2=0x0;..................

不行,按键按的时候数码管都会闪一下


0
回复