㈠ 基於單片機的數字時鍾怎麼做
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit la=P2^6;
sbit wela=P2^7;
sbit rs=P3^5;
sbit lcden=P3^4;
sbit s1=P3^0;
sbit s2=P3^1;
sbit s3=P3^2;
sbit rd=P3^7;
uchar count,s1num;
char miao,shi,fen;
uchar code table[]=" 2007-7-30 MON";
uchar code table1[]=" 00:00:00";
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void write_com(uchar com)
{
rs=0;
lcden=0;
P0=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void write_date(uchar date)
{
rs=1;
lcden=0;
P0=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
void init()
{
uchar num;
la=0;
wela=0;
lcden=0;
// fen=59;
// miao=53;
// shi=23;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);
for(num=0;num<15;num++)
{
write_date(table[num]);
delay(5);
}
write_com(0x80+0x40);
for(num=0;num<12;num++)
{
write_date(table1[num]);
delay(5);
}
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
}
void write_sfm(uchar add,uchar date)
{
uchar shi,ge;
shi=date/10;
ge=date%10;
write_com(0x80+0x40+add);
write_date(0x30+shi);
write_date(0x30+ge);
}
void keyscan()
{
rd=0;
if(s1==0)
{
delay(5);
if(s1==0)
{ s1num++;
while(!s1);
if(s1num==1)
{
TR0=0;
write_com(0x80+0x40+10);
write_com(0x0f);
}
}
if(s1num==2)
{
write_com(0x80+0x40+7);
}
if(s1num==3)
{
write_com(0x80+0x40+4);
}
if(s1num==4)
{
s1num=0;
write_com(0x0c);
TR0=1;
}
}
if(s1num!=0)
{
if(s2==0)
{
delay(5);
if(s2==0)
{
while(!s2);
if(s1num==1)
{
miao++;
if(miao==60)
miao=0;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}
if(s1num==2)
{
fen++;
if(fen==60)
fen=0;
write_sfm(7,fen);
write_com(0x80+0x40+7);
}
if(s1num==3)
{
shi++;
if(shi==24)
shi=0;
write_sfm(4,shi);
write_com(0x80+0x40+4);
}
}
}
if(s3==0)
{
delay(5);
if(s3==0)
{
while(!s3);
if(s1num==1)
{
/* if(miao==0)
{
miao=59;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}*/
miao--;
if(miao==-1)
miao=59;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}
if(s1num==2)
{
fen--;
if(fen==-1)
fen=59;
write_sfm(7,fen);
write_com(0x80+0x40+7);
}
if(s1num==3)
{
shi--;
if(shi==-1)
shi=23;
write_sfm(4,shi);
write_com(0x80+0x40+4);
}
}
}
}
}
void main()
{
init();
while(1)
{
keyscan();
}
// while(1);
}
void timer0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
count++;
if(count==18)
{
count=0;
miao++;
if(miao==60)
{
miao=0;
fen++;
if(fen==60)
{
fen=0;
shi++;
if(shi==24)
{
shi=0;
}
write_sfm(4,shi);
}
write_sfm(7,fen);
}
write_sfm(10,miao);
}
}
這個是數字時鍾的源程序,用12864夜晶顯示。
㈡ 51單片機做數字電子鍾
這么復雜的東西給這么少分 暈死了 你也太小氣了吧,分多的話還可能幫你動動腦
㈢ 數字時鍾 以AT89C52單片機為核心的時鍾
我可以幫你做,需要報酬,願意找我。
㈣ 單片機數字時鍾原理
給你個程序看看,主要是看時分顯示哪裡!這個程序已經調試通過了,在走時的同時流水燈進行流動,時分之間有一個小數點作為分隔。還有整點報時功能,在早上八點到中午十二點以及下午三點到晚上八點兩個時間段內逢整點報時,其他時間不報時(是因為考慮到人們要午休及晚間休息),除此之外還有調時、調分功能。整個程序基於單片機AT89S52(可用C51、C52、S51等代替)。
#include <reg52.h>
#define uint unsigned int
sbit P3_0=P3^0;
sbit K1=P3^2;
sbit K2=P3^3;
sbit K3=P3^4;
sbit K4=P3^5;
uint count,min,hour,i,j=0;
uint code tab1[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uint code tab2[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
uint code tab3[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0xff,
0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,0xff,0x00,0xff,0x00,0xff,
0xfe,0xfb,0xef,0xbf,0xfd,0xf7,0xdf,0x7f,0x7e,0x3c,0x18,0x00,0x81,
0xc3,0xe7,0xff,0xe7,0xdb,0xbd,0x7e,0xff,0x7e,0xbd,0xdb,0xe7,0xff,
0x00,0xff,0x00,0xff,0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80,0x00,0x80,
0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff,0x00,0xff,0x00,0xff,0xfe,0xfc,
0xf8,0xf0,0xe0,0xc0,0x80,0x00,0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,
0xff,0xfc,0xf9,0xf3,0xe7,0xcf,0x9f,0x3f,0xff,0x00,0xff,0x00,0xff};//流水燈
void adjust(void)
{
if(!K3) //分調整
{
for(i=0;i<20000;i++);min++;
if(min==60)min=0;
}
if(!K4) //時調整
{
for(i=0;i<20000;i++);hour++;
if(hour==24)hour=0;
}
}
void display(void)
{
P0=tab1[min%10];P2=0xf7;for(i=0;i<5;i++);P2=0xff;//分個位顯示
P0=tab1[min/10];P2=0xfb;for(i=0;i<5;i++);P2=0xff;//分十位顯示
P0=tab2[hour%10];P2=0xfd;for(i=0;i<5;i++);P2=0xff;//時個位顯示
P0=tab1[hour/10];P2=0xfe;for(i=0;i<5;i++);P2=0xff;//時十位顯示
}
void ring(void)
{
if(hour/10==0&&(hour%10>=8&&hour%10<=9))P3_0=0;//早上7:00到晚上7:00自動整點報時,其中13、14點不報時
if(hour/10==1&&(hour%10>=0&&hour%10<=2))P3_0=0;
if(hour/10==1&&(hour%10>=5&&hour%10<=9))P3_0=0;
}
void update(void)
{
if(count==1200)
{
count=0;min++;
if(min==60)
{
min=0;hour++;
if(hour==24)hour=0;
ring();
}
}
}
void main(void)
{
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
TR0=1;
EA=1;
ET0=1;
while(1)
{
if(count==120)P3_0=1;//報時六秒後自動關閉蜂鳴器
adjust();
display();
}
}
void timer0_rupt(void) interrupt 1 // 定時器0中斷
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
count++;
if(count%10==0)
{
P1=tab3[j];
j++;
if(j>99)j=0;
}
update();
}
㈤ 單片機數字時鍾課程設計
這個 我正在學單片機,也剛剛做過了這個實驗沒多久,不過我的是8098單片機,確實是匯編語言。不過我做的僅僅是個電子鍾,你可以隨時改變你輸入的時間然後它就會按時分秒跳動,我做的是24小時制的。不過我沒有弄鬧鍾額……不過也簡單,可以弄一個中斷申請就ok。話說你的鬧鍾要求是什麼?我記得8098是不能響的,只有一個發光二極體可以亮一亮……
話說能請你把問題補充一下么?我的程序寫在紙上,然後我們還要求是要把程序翻譯出機器碼然後在單片機上實驗出結果的。所以我連機器碼都翻譯了的……實在不知道你們的要求。
原理可以先和你說一下:主程序先是一系列的初始化(中斷懸掛的清零和寄存器的設置,堆棧的設置等),然後開啟中斷,寫顯示程序(顯示程序前要弄好你顯示的寄存器以及掃描子程序的地址,還要對十六進制數進行轉換變成十進制數,只要做一個除法就行,用十六進制數除以A就能夠得出相應的十進制數。)
然後就是你的中斷程序了,比如你的中斷申請是每10ms申請一次,那你就計數,如果到了100次中斷了,那就秒加一,再查看秒是否到60,是則清零讓分加一,否則跳到中斷程序末端;然後再依次查分和時。最後中斷程序的末端還要用一次計時器軟體中斷申請。再跳回主程序反復運行。可能比較麻煩,我記得我打的草稿就好多張紙呢,後來在16進制向10進制轉換的時候還出了個寄存器的問題。
不知道和你程序的要求是否相同= =。
期待你能夠補充一下你的問題。
㈥ 用單片機設計一個數字時鍾
#include <REG51.H>#include <intrins.h> #define uint unsigned int#define uchar unsigned charsbit DS1302_CLK = P1^7; //實時時鍾時鍾線引腳 sbit DS1302_IO = P1^6; //實時時鍾數據線引腳 sbit DS1302_RST = P1^5; //實時時鍾復位線引腳sbit wireless_1 = P3^0;sbit wireless_2 = P3^1;sbit wireless_3 = P3^2;sbit wireless_4 = P3^3; //無線控制sbit ACC0 = ACC^0;sbit ACC7 = ACC^7;char hide_sec,hide_min,hide_hour,hide_day,hide_week,hide_month,hide_year; //秒,分,時到日,月,年位閃的計數sbit Set = P2^0; //模式切換鍵sbit Up = P2^1; //加法按鈕sbit Down = P2^2; //減法按鈕sbit out = P2^3; //立刻跳出調整模式按鈕sbit DQ = P1^0; //溫度傳送數據IO口char done,count,temp,flag,up_flag,down_flag;uchar temp_value; //溫度值uchar TempBuffer[5],week_value[2]; void show_time(); //液晶顯示程序/***********1602液晶顯示部分子程序****************///Port Definitions**********************************************************sbit LcdRs = P2^5;sbit LcdRw = P2^6;sbit LcdEn = P2^7;sfr DBPort = 0x80; //P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.數據埠 //內部等待函數**************************************************************************unsigned char LCD_Wait(void){ LcdRs=0; LcdRw=1; _nop_(); LcdEn=1; _nop_(); LcdEn=0; return DBPort; }//向LCD寫入命令或數據************************************************************#define LCD_COMMAND 0 // Command#define LCD_DATA 1 // Data#define LCD_CLEAR_SCREEN 0x01 // 清屏#define LCD_HOMING 0x02 // 游標返回原點void LCD_Write(bit style, unsigned char input){ LcdEn=0; LcdRs=style; LcdRw=0; _nop_(); DBPort=input; _nop_();//注意順序 LcdEn=1; _nop_();//注意順序 LcdEn=0; _nop_(); LCD_Wait(); } //設置顯示模式************************************************************#define LCD_SHOW 0x04 //顯示開#define LCD_HIDE 0x00 //顯示關 #define LCD_CURSOR 0x02 //顯示游標#define LCD_NO_CURSOR 0x00 //無游標 #define LCD_FLASH 0x01 //游標閃動#define LCD_NO_FLASH 0x00 //游標不閃動 void LCD_SetDisplay(unsigned char DisplayMode){ LCD_Write(LCD_COMMAND, 0x08|DisplayMode); } //設置輸入模式************************************************************#define LCD_AC_UP 0x02#define LCD_AC_DOWN 0x00 // default #define LCD_MOVE 0x01 // 畫面可平移#define LCD_NO_MOVE 0x00 //default void LCD_SetInput(unsigned char InputMode){ LCD_Write(LCD_COMMAND, 0x04|InputMode);} //初始化LCD************************************void LCD_Initial(){ LcdEn=0; LCD_Write(LCD_COMMAND,0x38); //8位數據埠,2行顯示,5*7點陣 LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR); //開啟顯示, 無游標 LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN); //清屏 LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE); //AC遞增, 畫面不動} //液晶字元輸入的位置************************void GotoXY(unsigned char x, unsigned char y){ if(y==0) LCD_Write(LCD_COMMAND,0x80|x); if(y==1) LCD_Write(LCD_COMMAND,0x80|(x-0x40));} //將字元輸出到液晶顯示void Print(unsigned char *str){ while(*str!='\0') { LCD_Write(LCD_DATA,*str); str++; }} /***********DS1302時鍾部分子程序******************/typedef struct __SYSTEMTIME__{ unsigned char Second; unsigned char Minute; unsigned char Hour; unsigned char Week; unsigned char Day; unsigned char Month; unsigned char Year; unsigned char DateString[11]; unsigned char TimeString[9];}SYSTEMTIME; //定義的時間類型SYSTEMTIME CurrentTime; #define AM(X) X#define PM(X) (X+12) // 轉成24小時制#define DS1302_SECOND 0x80 //時鍾晶元的寄存器位置,存放時間#define DS1302_MINUTE 0x82#define DS1302_HOUR 0x84 #define DS1302_WEEK 0x8A#define DS1302_DAY 0x86#define DS1302_MONTH 0x88#define DS1302_YEAR 0x8C void DS1302InputByte(unsigned char d) //實時時鍾寫入一位元組(內部函數){ unsigned char i; ACC = d; for(i=8; i>0; i--) { DS1302_IO = ACC0; //相當於匯編中的 RRC DS1302_CLK = 1; DS1302_CLK = 0; ACC = ACC >> 1; } } unsigned char DS1302OutputByte(void) //實時時鍾讀取一位元組(內部函數){ unsigned char i; for(i=8; i>0; i--) { ACC = ACC >>1; //相當於匯編中的 RRC ACC7 = DS1302_IO; DS1302_CLK = 1; DS1302_CLK = 0; } return(ACC); } void Write1302(unsigned char ucAddr, unsigned char ucDa) //ucAddr: DS1302地址, ucData: 要寫的數據{ DS1302_RST = 0; DS1302_CLK = 0; DS1302_RST = 1; DS1302InputByte(ucAddr); // 地址,命令 DS1302InputByte(ucDa); // 寫1Byte數據 DS1302_CLK = 1; DS1302_RST = 0;} unsigned char Read1302(unsigned char ucAddr) //讀取DS1302某地址的數據{ unsigned char ucData; DS1302_RST = 0; DS1302_CLK = 0; DS1302_RST = 1; DS1302InputByte(ucAddr|0x01); // 地址,命令 ucData = DS1302OutputByte(); // 讀1Byte數據 DS1302_CLK = 1; DS1302_RST = 0; return(ucData);} void DS1302_GetTime(SYSTEMTIME *Time) //獲取時鍾晶元的時鍾數據到自定義的結構型數組{ unsigned char ReadValue; ReadValue = Read1302(DS1302_SECOND); Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_MINUTE); Time->Minute = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_HOUR); Time->Hour = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_DAY); Time->Day = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_WEEK); Time->Week = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_MONTH); Time->Month = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); ReadValue = Read1302(DS1302_YEAR); Time->Year = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); } void DateToStr(SYSTEMTIME *Time) //將時間年,月,日,星期數據轉換成液晶顯示字元串,放到數組里DateString[]{ if(hide_year<2) //這里的if,else語句都是判斷位閃爍,<2顯示數據,>2就不顯示,輸出字元串為 2007/07/22 { Time->DateString[0] = '2'; Time->DateString[1] = '0'; Time->DateString[2] = Time->Year/10 + '0'; Time->DateString[3] = Time->Year%10 + '0'; } else { Time->DateString[0] = ' '; Time->DateString[1] = ' '; Time->DateString[2] = ' '; Time->DateString[3] = ' '; } Time->DateString[4] = '/'; if(hide_month<2) { Time->DateString[5] = Time->Month/10 + '0'; Time->DateString[6] = Time->Month%10 + '0'; } else { Time->DateString[5] = ' '; Time->DateString[6] = ' '; } Time->DateString[7] = '/'; if(hide_day<2) { Time->DateString[8] = Time->Day/10 + '0'; Time->DateString[9] = Time->Day%10 + '0'; } else { Time->DateString[8] = ' '; Time->DateString[9] = ' '; } if(hide_week<2) { week_value[0] = Time->Week%10 + '0'; //星期的數據另外放到 week_value[]數組里,跟年,月,日的分開存放,因為等一下要在最後顯示 } else { week_value[0] = ' '; } week_value[1] = '\0'; Time->DateString[10] = '\0'; //字元串末尾加 '\0' ,判斷結束字元} void TimeToStr(SYSTEMTIME *Time) //將時,分,秒數據轉換成液晶顯示字元放到數組 TimeString[];{ if(hide_hour<2) { Time->TimeString[0] = Time->Hour/10 + '0'; Time->TimeString[1] = Time->Hour%10 + '0'; } else { Time->TimeString[0] = ' '; Time->TimeString[1] = ' '; } Time->TimeString[2] = ':'; if(hide_min<2) { Time->TimeString[3] = Time->Minute/10 + '0'; Time->TimeString[4] = Time->Minute%10 + '0'; } else { Time->TimeString[3] = ' '; Time->TimeString[4] = ' '; } Time->TimeString[5] = ':'; if(hide_sec<2) { Time->TimeString[6] = Time->Second/10 + '0'; Time->TimeString[7] = Time->Second%10 + '0'; } else { Time->TimeString[6] = ' '; Time->TimeString[7] = ' '; } Time->DateString[8] = '\0';} void Initial_DS1302(void) //時鍾晶元初始化{ unsigned char Second=Read1302(DS1302_SECOND); if(Second&0x80) //判斷時鍾晶元是否關閉 { Write1302(0x8e,0x00); //寫入允許 Write1302(0x8c,0x07); //以下寫入初始化時間 日期:07/07/25.星期: 3. 時間: 23:59:55 Write1302(0x88,0x07); Write1302(0x86,0x25); Write1302(0x8a,0x07); Write1302(0x84,0x23); Write1302(0x82,0x59); Write1302(0x80,0x55); Write1302(0x8e,0x80); //禁止寫入 } } /***********ds18b20子程序*************************/ /***********ds18b20延遲子函數(晶振12MHz )*******/ void delay_18B20(unsigned int i){ while(i--);} /**********ds18b20初始化函數**********************/ void Init_DS18B20(void) { unsigned char x=0; DQ = 1; //DQ復位 delay_18B20(8); //稍做延時 DQ = 0; //單片機將DQ拉低 delay_18B20(80); //精確延時 大於 480us DQ = 1; //拉高匯流排 delay_18B20(14); x=DQ; //稍做延時後 如果x=0則初始化成功 x=1則初始化失敗 delay_18B20(20);} /***********ds18b20讀一個位元組**************/ unsigned char ReadOneChar(void){ uchar i=0; uchar dat = 0; for (i=8;i>0;i--) { DQ = 0; // 給脈沖信號 dat>>=1; DQ = 1; // 給脈沖信號 if(DQ) dat|=0x80; delay_18B20(4); } return(dat);} /*************ds18b20寫一個位元組****************/ void WriteOneChar(uchar dat){ unsigned char i=0; for (i=8; i>0; i--) { DQ = 0; DQ = dat&0x01; delay_18B20(5); DQ = 1; dat>>=1; }} /**************讀取ds18b20當前溫度************/ void ReadTemp(void){ unsigned char a=0; unsigned char b=0; unsigned char t=0; Init_DS18B20(); WriteOneChar(0xCC); // 跳過讀序號列號的操作 WriteOneChar(0x44); // 啟動溫度轉換 delay_18B20(100); // this message is wery important Init_DS18B20(); WriteOneChar(0xCC); //跳過讀序號列號的操作 WriteOneChar(0xBE); //讀取溫度寄存器等(共可讀9個寄存器) 前兩個就是溫度 delay_18B20(100); a=ReadOneChar(); //讀取溫度值低位 b=ReadOneChar(); //讀取溫度值高位 temp_value=b<<4; temp_value+=(a&0xf0)>>4; }void temp_to_str() //溫度數據轉換成液晶字元顯示{ TempBuffer[0]=temp_value/10+'0'; //十位 TempBuffer[1]=temp_value%10+'0'; //個位 TempBuffer[2]=0xdf; //溫度符號 TempBuffer[3]='C'; TempBuffer[4]='\0';}void Delay1ms(unsigned int count){ unsigned int i,j; for(i=0;i<count;i++) for(j=0;j<120;j++);} /*延時子程序*/void mdelay(uint delay){ uint i; for(;delay>0;delay--) {for(i=0;i<62;i++) //1ms延時. {;} }}
㈦ 單片機做數字時鍾,求程序
1、解決驅動碼。得到顯示所有字元的七段碼。
2、解決動態掃描問題。在定時中斷中順序掃描其中一個數碼管。
3、解決內容——定時的計時表述。Hour,Minute,Second,mS;
4、解決時間的修改設置。
1、通用碼表
#define SEGA 1
#define SEGB 2
#define SEGC 4
#define SEGD 8
#define SEGE 0x10
#define SEGF 0x20
#define SEGG 0x40
#define SEGH 0x80
unsigned char code SegCode[11]=
{ ~(SEGA+SEGB+SEGC+SEGD+SEGE+SEGF),//0
~(SEGB+SEGC),//1
~(SEGA+SEGB+SEGD+SEGE+SEGG),//2
~(SEGA+SEGB+SEGC+SEGD+SEGG),//3
~(SEGB+SEGC+SEGF+SEGG),//4
~(SEGA+SEGC+SEGD+SEGF+SEGG),//5
~(SEGA+SEGC+SEGD+SEGE+SEGF+SEGG),//6
~(SEGA+SEGB+SEGC),//7
~(SEGA+SEGB+SEGC+SEGD+SEGE+SEGF+SEGG),//8
~(SEGA+SEGB+SEGC+SEGD+SEGF+SEGG),//9
~(SEGG),//—
};
2、動態掃描,內容放在
unsigned char i, Time[8]={0,0,0xa,0,0,0xa,0,0};
void Disp(unsigned char x)//顯示第x個數碼管的內容。
{
P0=0xff;
P1=SegCode[Time[x]];
P0=~(1<<x);
}
在定時中斷中調用。
3、定時管理並得到50mS時基。按12MHz,定時1方式,定時器0配置中斷。
定義unsigned char mS50,Sec,Min,Hour;
void InitialT0(void)//主程序調用一次
{
TMOD=0x1;
ET0=1;EA=1;TR0=1;
}
void ISRForT0(void) interrupt 1
{
TH0=(-50000)>>8;
TL0=(-50000)&0xff;
mS50++;
Disp(i++%8);
if(mS50>19)
{
mS50=0;
Sec++;
if(Sec>59){Sec=0;Min++;if(Min>59){Min=0;Hour++;Hour%=24;}}
Time[0]=Hour/10;
Time[1]=Hour%10;
Time[3]=Min/10;
Time[4]=Min%10;
Time[6]=Sec/10;
Time[7]=Sec%10;
}
}
4、修改時間的問題,還是等你自己忙吧。放到while(1)裡面讀鍵,修改Hour,Min,Sec即可。
main函數如下:把上面的代碼全部搞到一起,編譯通過後調試吧。
main()
{
InitialT0();
while(1);
}
【補充一下,明天數碼管會閃的厲害。把中斷時間改成2mS,再試一遍。】
㈧ 跪求!基於單片機的數字時鍾設計
#include<reg52.h>
#include<absacc.h>
#include<intrins.h>
#define unit unsigned int
#define uchar unsigned char
//#define HZ 12
sbit key0=P0^0; // 分鍾調整
sbit key1=P0^1; // 小時調整
sbit P2_0=P2^7; //秒 指示燈
sbit MN_RXD=P3^6;
sbit MN_TXD=P3^7;
uchar data CLOCK[4]={0,0,0,12};//存放時鍾時間(百分秒,秒,分,和時位)
//數碼管顯示表0-f 滅
uchar code TABLE[]={0xBE,0x06,0xEA,0x6E,0x56,0x7C,0xFC,0x0E,0xFE,0x7E,0x00};
//**********************************
//模擬串口發送一個位元組數據 函數
//**********************************
void SendData(unsigned char senddata)
{
unsigned char i;
for(i=0;i<8;i++)
{
if((senddata&0x01)==0)
MN_RXD=0;
else
MN_RXD=1;
_nop_();
MN_TXD=0;
_nop_();
MN_TXD=1;
senddata=senddata>>1;
}
}
//**********************************
//顯示程序函數
//**********************************
void display(void)
{
// unsigned int n;
uchar temp;
temp=CLOCK[1]; temp=temp%10; SendData(TABLE[temp]);
temp=CLOCK[1]; temp=temp/10; SendData(TABLE[temp]);
temp=CLOCK[2]; temp=temp%10; SendData(TABLE[temp]);
temp=CLOCK[2]; temp=temp/10; SendData(TABLE[temp]);
temp=CLOCK[3]; temp=temp%10; SendData(TABLE[temp]);
temp=CLOCK[3]; temp=temp/10; SendData(TABLE[temp]);
/*
for(n=0;n<5000;n++);
for(n=0;n<6;n++)
{
SendData(TABLE[10]);
}
*/
}
//**********************************
//按鍵控制函數
//**********************************
void keycan()
{
unsigned int n;
EA=0;
if(key0==0) // 分鍾調整
{
for(n=0;n<10000;n++); //延時去抖動
while(key0==0);
CLOCK[2]=CLOCK[2]+1;
if(CLOCK[2]==60) //到一時
{
CLOCK[2]=0;
}
display();
}
if(key1==0) // 小時調整
{
for(n=0;n<10000;n++); //延時去抖動
while(key1==0);
CLOCK[3]=CLOCK[3]+1;
if(CLOCK[3]==24)
{
CLOCK[3]=0;
}
display();
}
EA=1;
}
//**********************************
//T0中斷服務函數
//**********************************
void time0() interrupt 1 //using 1
{
TH0=0xD8; TL0=0xF0; //重置初值
// TH0=0xB1; TL0=0xE0;
//時鍾處理
CLOCK[0]=CLOCK[0]+1;
}
//**********************************
//主函數
//**********************************
void main()
{
EA=1;
ET0=1;
TMOD=0x01; //T0方式1定時
TH0=0xD8; TL0=0xF0; //D8F0 定時10ms
// TH0=0xB1; TL0=0xE0; //定時 20ms
TR0=1;
for(;;)
{
if(CLOCK[0]==100) //到一秒 10ms*100
{
CLOCK[0]=0;
P2_0=~P2_0;
CLOCK[1]=CLOCK[1]+1;
if(CLOCK[1]==60) //到一分
{
CLOCK[1]=0;
CLOCK[2]=CLOCK[2]+1;
if(CLOCK[2]==60) //到一時
{
CLOCK[2]=0;
CLOCK[3]=CLOCK[3]+1;
if(CLOCK[3]==24)
{
CLOCK[3]=0;
}
}
}
display();
}
keycan();
}
}
㈨ 基於單片機的數字時鍾,基於單片機的數字時鍾有什麼區別啊
時鍾晶元比較准,如果是要用單單片機的話,必須使用帶有rtc功能的單片機