电子时钟的制作与学习
全部回复(23)
正序查看
倒序查看
现在还没有回复呢,说说你的想法
@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
回复
提示
@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
回复
提示
@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
回复
提示
帖子已被设置为头条,恭喜楼主可添加电源网私人官网微信(dianyuan_com)为好友,领取现金红包(备注信息:头条红包)
注:现金红包仅限当日领取
活动介绍:http://www.dianyuan.com/bbs/1531738.html
0
回复
提示
@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
回复
提示
@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
回复
提示
@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
回复
提示
@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
回复
提示
@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
回复
提示