電子時鐘的制作與學習
全部回復(23)
正序查看
倒序查看
已經被添加到社區經典圖庫嘍
http://m.daogou-taobao.cn/bbs/classic/
http://m.daogou-taobao.cn/bbs/classic/
0
回復
@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://m.daogou-taobao.cn/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
回復