Ⅰ 求用單片機c語言做一個電子時鍾,實現調時、顯示、整點報時等功能。
(1)用數字邏輯集成塊實現;
(2)時間以24小時為一個周期,顯示時、分、秒;
(3)計時過程具有報時功能,當時間到達整點前5秒進行蜂鳴報時;
(4)為了保證計時的穩定及准確須由晶體振盪器提供表針時間基準信號。
c51單片機 晶振為11.0592MHz
#include<reg52.h>
#define HOUR1 1
#define HOUR0 0
#define MIN1 2
#define MIN0 8
#define SEC1 2
#define SEC0 0
#define uint unsigned int
#define ulint unsigned long int
#define uchar unsigned char
sbit la=P2^6;
sbit wela=P2^7;
sbit beep=P2^3;
int i;
ulint
sharp,second,count=0,sec0=SEC0,sec1=SEC1,min0=MIN0,min1=MIN1,hour0=HOUR0,hour1=HOUR1;//秒計數全局變數
uchar code segment[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
uchar code time[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f};
void delay(uint);//程序毫秒延時
void beeper(uchar);//開蜂鳴器毫秒
void init();//初始化函數
void display();//從數碼管上顯示
void counter();//計算進行過程中的時、分、秒值
void scan();//掃描鍵盤
void main()
{
init();
while(1)
{
scan();//掃描鍵盤看是否有鍵按下
for(i=6;i>0;i--)//動態掃描6位數碼管
{
display();//顯示時、分、秒
}
}
}
void init()
{
second=hour1*36000+hour0*3600+min1*600+min0*60+sec1*10+sec0;
TMOD=0x01;
TH0=(65536-46080)/256;
TL0=(65536-46080)%256;
EA=1;
ET0=1;
TR0=1;
}
void delay(uint z)//程序毫秒延時
{
uint x=0,y=0;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void timer0() interrupt 1
{
TH0=(65536-46080)/256;
TL0=(65536-46080)%256;
count++;
if(count==20)//判斷是否到1秒
{
counter();//計算進行過程中的時、分、秒值
if(sharp!=hour0) beeper(1000);//判斷小時的值是否改變,變則啟動蜂鳴器
}
}
void beeper(uchar tt)
{
uchar t=tt;
count=0;
beep=0;//開蜂鳴器
delay(t);
beep=1;//關蜂鳴器
}
void display()
{
P0=0xff;//位消影(低電平選擇位)
//送位選信號
wela=1;
P0=segment[i-1];
wela=0;
P0=0x00;//段消影(高電平選擇段)
//送段選信號
la=1;
switch(i)
{
case 6 : P0=time[sec0]; break;
case 5 : P0=time[sec1]; break;
case 4 : P0=time[min0]; break;
case 3 : P0=time[min1]; break;
case 2 : P0=time[hour0]; break;
case 1 : P0=time[hour1]; break;
}
delay(1);
P0=0x00; //配合上面用於消隱
la=0;
}
void counter()
{
second++;
if(second==86400) second=0;
count=0;
sharp=hour0;//設置報時檢測KEY
sec0=second%10;
sec1=(second%60-sec0)/10;
min0=((second%3600-sec1*10-sec0)/60)%10;
min1=((second%3600-sec1*10-sec0)/60-min0)/10;
hour0=(second%36000-min1*600-min0*60-sec1*10-sec0)/3600;
hour1=second/36000;
}
void scan()
{
}
Ⅱ 51單片機做數字電子鍾
這么復雜的東西給這么少分 暈死了 你也太小氣了吧,分多的話還可能幫你動動腦
Ⅲ 基於51單片機的數碼管設計電子時鍾,可以調時間的,怎麼弄唉,大家幫幫忙...
說一下步驟吧:
1、數碼管驅動電路設計。一般用三極體如9013或者鎖存器如74HC573來驅動,使其能夠正常亮滅。
2、使用動態掃描的方式讓數碼管能夠顯示你想要的數字,這個可以用中斷來掃描也可以不用。
3、使用實時時鍾晶元如DS1302來獲得你想要的時間數據。這種網上有很多源程序,你可以搜索看。你要學會幾點:(1)對晶元初始化;(2)獲得時間數據;(3)知道怎麼修改數據。
4、使用按鍵來修改時間數據。這個方法很多,盡提供參考的。使用三個按鍵,分別是:設置按鍵(這個是復用按鍵,按一次進入設置模式,並讓某一位閃爍,再按則依次讓下一位閃爍,表示被選擇,直到要設置的數字完成再按則確認設置),+鍵和-鍵。這個不僅僅是修改數據那麼簡單,還需要涉及到對DS1302數據的修改,需要關閉DS1302的防寫功能,設置結束後再打開這個功能。
以上字字手打,希望對你有幫助
Ⅳ 用單片機設計一個時鍾,可顯示時和分,可以調時間,也要有鬧鍾功能,要有設計的電路圖
其實不用定時中斷也能實現功能:
#include<reg51.h> 主函數
unsigned char tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};定義0-9數組
unsigned int tmp;定義變數
void delay(unsigned int xms)定義延時函數
{unsigned int j,i;
for(i=0;i<xms;i++)
for(j=0;j<100;j++);
}
void disp()定義子函數
{
P1=tmp;
delay(1);
P2=0xff;
tmp=tmp<<1;
}
void main( )
{
unsigned char z,s=00,m=00,h=00;給時鍾初始值
while(1)
{
for(z=0;z<100;z++)
{
tmp=0x01;
P2=tab[h/10];小時顯示
disp();
P2=tab[h%10];
disp();
P2=tab[m/10];分鍾顯示
disp();
P2=tab[m%10];
disp();
P2=tab[s/10];秒顯示
disp();
P2=tab[s%10];
disp();
}
s++;
while(s==60)秒進一位,到60清0
{
m++;
s=00;
}
while(m==60)分鍾進一位,到60清0
{
h++;
m=00;
}
while(h==24)小時進一位,到24清0
{
h=00;
}
}
}
Ⅳ 跪求單片機c51一個多功能時鍾設計。要鬧鍾。調整時間、秒錶、就行了。急求。。。C語言編寫
//給你發一個數碼管輸出的可調節時鍾的程序,<DS1302.H>在最後
#include <at89x52.h>
#include <DS1302.h>
//定義共陽極字型碼0123456789-
unsigned char code dispcode[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf};
unsigned char time[]={0,0,0,0,0,0,0,0};//用來儲存時間
unsigned char date[]={0,0,0,0,0,0,0,0};//用來儲存日期
SYSTEMTIME time1; //在ds1302.h文件中已經定義了一個名字為SYSTEMTIME的結構體,在這里我們定義一個變數名
//為time的SYSTEMTIME結構體
void delay(unsigned char i) //延時子程序
{
unsigned char j;
while((i--)!=0)
{
for(j=123;j>0;j--);
}
}
unsigned char button_time(n,x,y) //時鍾調整子程序
unsigned char n,x,y;
{
if(P1_7==0)
{
delay(50);
if(P1_7==0)
{
n++;
if(n==x)
n=0;
while(P1_7==0);
}
}
if(P1_5==0)
{
delay(50);
if(P1_5==0)
{
if(n==0)
n=y;
else
n--;
while(P1_5==0);
}
}
return n;
}
unsigned char button_date(n,x,y) //日期調整子程序
unsigned char n,x,y;
{
if(P1_7==0)
{
delay(50);
if(P1_7==0)
{
n++;
if(n==x)
n=1;
while(P1_7==0);
}
}
if(P1_5==0)
{
delay(50);
if(P1_5==0)
{
if(n==1)
n=y;
else
n--;
while(P1_5==0);
}
}
return n;
}
void display(second10,second1,minute10,minute1,hour10,hour1) //顯示子程序
unsigned char second10,second1,minute10,minute1,hour10,hour1;
{
P2=0xfe;
P0=dispcode[second10];//顯示秒的十位
delay(1);
P2=0xfd;
P0=dispcode[second1]; //顯示秒的個位
delay(1);
P2=0xfb;
P0=dispcode[10]; //顯示"-"
delay(1);
P2=0xf7;
P0=dispcode[minute10];//顯示分的十位
delay(1);
P2=0xef;
P0=dispcode[minute1]; //顯示分的個位
delay(1);
P2=0xdf;
P0=dispcode[10]; //顯示"-"
delay(1);
P2=0xbf;
P0=dispcode[hour10]; //顯示時的十位
delay(1);
P2=0x7f;
P0=dispcode[hour1]; //顯示時的個位
delay(1);
}
void main()
{
unsigned char flag;
Initial_DS1302(); //初始化DS1302這個時鍾晶元,
while(1)
{
DS1302_GetTime(&time1); //讀取時間參數
time[5]=(time1.Second)%10; //把秒的個位數據存入time[5]
time[4]=(time1.Second)/10; //把秒的十位數據存入time[4]
time[3]=(time1.Minute)%10; //把分的個位數據存入time[3]
time[2]=(time1.Minute)/10; //把分的十位數據存入time[2]
time[1]=(time1.Hour)%10; //把時的個位數據存入time[1]
time[0]=(time1.Hour)/10; //把時的十位數據存入time[0]
date[5]=(time1.Day)%10;
date[4]=(time1.Day)/10;
date[3]=(time1.Month)%10;
date[2]=(time1.Month)/10;
date[1]=(time1.Year)%10;
date[0]=(time1.Year)/10;
if(P1_4==0) //如果按下Time Start鍵一下,時鍾開始正常顯示時間,再按一下,顯示日期
{
delay(50);
if(P1_4==0)
{
flag++;
if(flag>1)
{
flag=0;
}
}
while(P1_4==0);
}
if(P1_6==0) //如果按下Time Set鍵一下,開始顯示日期,再按一下進入日期跟時鍾的調節模式
{
delay(50);
if(P1_6==0)
{
flag++;
if(flag>7)
{
flag=0;
}
}
while(P1_6==0);
}
switch(flag)
{
case 0:display(time[0],time[1],time[2],time[3],time[4],time[5]); //調用子函數display,把存入數組time的數據給顯示出來
break;
case 1:display(date[0],date[1],date[2],date[3],date[4],date[5]); //調用子函數display,把存入數組date的數據給顯示出來
break;
case 2:time1.Year=button_date(time1.Year,100,99); //調整年
DS1302_SetTime(0x8c,time1.Year);
display(date[0],date[1],10,10,10,10);
break;
case 3:time1.Month=button_date(time1.Month,13,12); //調整月
DS1302_SetTime(0x88,time1.Month);
display(10,10,date[2],date[3],10,10);
break;
case 4:time1.Day=button_date(time1.Day,32,31); //調整日
DS1302_SetTime(0x86,time1.Day);
display(10,10,10,10,date[4],date[5]);
break;
case 5:time1.Hour=button_time(time1.Hour,24,23); //調整時
DS1302_SetTime(0x84,time1.Hour);
display(time[0],time[1],10,10,10,10);
break;
case 6:time1.Minute=button_time(time1.Minute,60,59); //調整分
DS1302_SetTime(0x82,time1.Minute);
display(10,10,time[2],time[3],10,10);
break;
case 7:time1.Second=button_time(time1.Second,60,59); //調整秒
DS1302_SetTime(0x80,time1.Second);
display(10,10,10,10,time[4],time[5]);
break;
}
}
}
//DS1302.H
#ifndef _REAL_TIMER_DS1302_2003_7_21_
#define _REAL_TIMER_DS1302_2003_7_21_
#include <at89x52.h>
sbit DS1302_CLK = P1^0; //實時時鍾時鍾線引腳
sbit DS1302_IO = P1^1; //實時時鍾數據線引腳
sbit DS1302_RST = P1^2; //實時時鍾復位線引腳
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
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[9];
unsigned char TimeString[9];
}SYSTEMTIME; //定義的時間類型
#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
#define DS1302_RAM(X) (0xC0+(X)*2) //用於計算 DS1302_RAM 地址的宏
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; //RST 0->1->0,CLK 0->1
}
unsigned char Read1302(unsigned char ucAddr) //讀取DS1302某地址的數據
{
unsigned char ucData;
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1; //enable
DS1302InputByte(ucAddr|0x01); // 地址,命令
ucData = DS1302OutputByte(); // 讀1Byte數據
DS1302_CLK = 1; //RST 0->1->0,CLK 0->1
DS1302_RST = 0;
return(ucData);
}
void DS1302_SetProtect(bit flag) //是否防寫
{
if(flag)
Write1302(0x8E,0x10); //WP=1,不能寫入
else
Write1302(0x8E,0x00);//WP=0,可以寫入
}
void DS1302_SetTime(unsigned char Address, unsigned char Value) // 設置時間函數
{
DS1302_SetProtect(0);
Write1302(Address, ((Value/10)<<4 | (Value%10))); //高4位為十位,低4位為個位
}
void DS1302_GetTime(SYSTEMTIME *Time)
{
unsigned char ReadValue;
ReadValue = Read1302(DS1302_SECOND);
Time->Second = ((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);//轉換成10進制的秒
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&0xf0)>>4)*10 + (ReadValue&0x0F);
}
/*
void DateToStr(SYSTEMTIME *Time)
{
Time->DateString[0] = Time->Year/10 + '0'; //數字類型轉化為字元類型
Time->DateString[1] = Time->Year%10 + '0';
Time->DateString[2] = '-';
Time->DateString[3] = Time->Month/10 + '0';
Time->DateString[4] = Time->Month%10 + '0';
Time->DateString[5] = '-';
Time->DateString[6] = Time->Day/10 + '0';
Time->DateString[7] = Time->Day%10 + '0';
Time->DateString[8] = '\0';
}
void TimeToStr(SYSTEMTIME *Time)
{
Time->TimeString[0] = Time->Hour/10 + '0'; //數字類型轉化為字元類型
Time->TimeString[1] = Time->Hour%10 + '0';
Time->TimeString[2] = ':';
Time->TimeString[3] = Time->Minute/10 + '0';
Time->TimeString[4] = Time->Minute%10 + '0';
Time->TimeString[5] = ':';
Time->TimeString[6] = Time->Second/10 + '0';
Time->TimeString[7] = Time->Second%10 + '0';
Time->DateString[8] = '\0';
}
*/
void Initial_DS1302(void)
{
unsigned char Second=Read1302(DS1302_SECOND);
if(Second&0x80) //如果第七為1(表明沒有啟動), 則啟動時鍾
DS1302_SetTime(DS1302_SECOND,0);
}
/********************************************************************************
void BurstWrite1302(unsigned char *pWClock) //往DS1302寫入時鍾數據(多位元組方式)
{
unsigned char i;
Write1302(0x8e,0x00); // 控制命令,WP=0,寫操作?
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
DS1302InputByte(0xbe); // 0xbe:時鍾多位元組寫命令
for (i = 8; i>0; i--) //8Byte = 7Byte 時鍾數據 + 1Byte 控制
{
DS1302InputByte(*pWClock); // 寫1Byte數據
pWClock++;
}
DS1302_CLK = 1;
DS1302_RST = 0;
}
void BurstRead1302(unsigned char *pRClock) //讀取DS1302時鍾數據(時鍾多位元組方式)
{
unsigned char i;
DS1302_RST = 0;
DS1302_CLK = 0;
DS1302_RST = 1;
DS1302InputByte(0xbf); // 0xbf:時鍾多位元組讀命令
for (i=8; i>0; i--)
{
*pRClock = DS1302OutputByte(); // 讀1Byte數據
pRClock++;
}
DS1302_CLK = 1;
DS1302_RST = 0;
}
void DS1302_TimeStop(bit flag) // 是否將時鍾停止
{
unsigned char Data;
Data=Read1302(DS1302_SECOND);
DS1302_SetProtect(0);
if(flag)
Write1302(DS1302_SECOND, Data|0x80);//停止
else
Write1302(DS1302_SECOND, Data&0x7F);不停止
}
********************************************************************************/
#endif
Ⅵ 我想用單片機的顯示器寫一電子鍾可是不知道怎麼編才能調整時間望高人指教我的程序如下:
能:
1。 全日歷計時。
2。 12/24小時轉換。
3。 8路定時輸出(可關/開控制)
4。 誤差:15S+1uS
5。 大、小月,潤年,周,自動追蹤
二、 調校:
上電後,電子鍾顯示「1:00」。
1。 8路定時時間查詢
按下K1鍵依此顯示8路定時時間。星期位顯示:「H」表示:打開當前定時輸出;「L」 表示:關閉當前定時輸出。此時按K2鍵可進行「H」、「L」的切換。所有輸出,均由蜂鳴器輸出!
2。 顯示狀態的控制
按下K2鍵可進入以下工作狀態:
1)12小時/ 日月交替顯示。
2)12小時固定顯示。
3)24小時/ 日月交替顯示。
4)24小時固定顯示。
3。 校時
按下K2鍵3S後,進入校時菜單。按下K1鍵依次進入校時狀態:分、時、天、月、年、微調系數。此時按K2鍵,完成+1。當顯示「d」時,表示要調整微調系數(0-99),其值越小,時鍾走時越慢。當使用的6MHz的晶振偏差大時,應仔細調整微調系數!當顯示「out」時,按K2鍵,即可退出!退出後,按任意鍵即可啟動時鍾。
4。 設置定時時間
按下K1鍵3S後,進入設置菜單。按下K1鍵依次進入8路定時調整狀態:時、分。此時按K2鍵,完成+1。當顯示「out」時,按K2鍵,即可退出!
Ⅶ 基於單片機的數字時鍾設計方案
數字鍾〔★〕這里用了兩種編租肆寫方法(即匯編語言與C語言)
(1. 開機時,顯示12:00:00的時間開始計時;
(2. P0.0/AD0控制「秒」的調整,每按一次加1秒;
(3. P0.1/AD1控制「分」的調整,每按一次加1分;
(4. P0.2/AD2控制「時」的調整,每按一次加1個小時;
2. 電路原理圖
3. 系統板上硬體連線
(1. 把「單片機系統」區域中的P1.0-P1.7埠用8芯排線連接到「動態數碼顯示」區域中的A-H埠上;
(2. 把「單片機系統:區域中的P3.0-P3.7埠用8芯排線連接到「動態數碼顯示」區域中的S1-S8埠上;
(3. 把「單片陵型碧機系統」區域中的P0.0/AD0、P0.1/AD1、P0.2/AD2埠分別用導線連接到「獨立式鍵盤」區域中尺舉的SP3、SP2、SP1埠上;
4. 相關基本知識
(1. 動態數碼顯示的方法
(2. 獨立式按鍵識別過程
(3. 「時」,「分」,「秒」數據送出顯示處理方法
5. 程序框圖
6. 匯編源程序
SECOND EQU 30H
MINITE EQU 31H
HOUR EQU 32H
HOURK BIT P0.0
MINITEK BIT P0.1
SECONDK BIT P0.2
DISPBUF EQU 40H
DISPBIT EQU 48H
T2SCNTA EQU 49H
T2SCNTB EQU 4AH
TEMP EQU 4BH
ORG 00H
LJMP START
ORG 0BH
LJMP INT_T0
START: MOV SECOND,#00H
MOV MINITE,#00H
MOV HOUR,#12
MOV DISPBIT,#00H
MOV T2SCNTA,#00H
MOV T2SCNTB,#00H
MOV TEMP,#0FEH
LCALL DISP
MOV TMOD,#01H
MOV TH0,#(65536-2000) / 256
MOV TL0,#(65536-2000) MOD 256
SETB TR0
SETB ET0
SETB EA
WT: JB SECONDK,NK1
LCALL DELY10MS
JB SECONDK,NK1
INC SECOND
MOV A,SECOND
CJNE A,#60,NS60
MOV SECOND,#00H
NS60: LCALL DISP
JNB SECONDK,$
NK1: JB MINITEK,NK2
LCALL DELY10MS
JB MINITEK,NK2
INC MINITE
MOV A,MINITE
CJNE A,#60,NM60
MOV MINITE,#00H
NM60: LCALL DISP
JNB MINITEK,$
NK2: JB HOURK,NK3
LCALL DELY10MS
JB HOURK,NK3
INC HOUR
MOV A,HOUR
CJNE A,#24,NH24
MOV HOUR,#00H
NH24: LCALL DISP
JNB HOURK,$
NK3: LJMP WT
DELY10MS:
MOV R6,#10
D1: MOV R7,#248
DJNZ R7,$
DJNZ R6,D1
RET
DISP:
MOV A,#DISPBUF
ADD A,#8
DEC A
MOV R1,A
MOV A,HOUR
MOV B,#10
DIV AB
MOV @R1,A
DEC R1
MOV A,B
MOV @R1,A
DEC R1
MOV A,#10
MOV @R1,A
DEC R1
MOV A,MINITE
MOV B,#10
DIV AB
MOV @R1,A
DEC R1
MOV A,B
MOV @R1,A
DEC R1
MOV A,#10
MOV @R1,A
DEC R1
MOV A,SECOND
MOV B,#10
DIV AB
MOV @R1,A
DEC R1
MOV A,B
MOV @R1,A
DEC R1
RET
INT_T0:
MOV TH0,#(65536-2000) / 256
MOV TL0,#(65536-2000) MOD 256
MOV A,#DISPBUF
ADD A,DISPBIT
MOV R0,A
MOV A,@R0
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV P1,A
MOV A,DISPBIT
MOV DPTR,#TAB
MOVC A,@A+DPTR
MOV P3,A
INC DISPBIT
MOV A,DISPBIT
CJNE A,#08H,KNA
MOV DISPBIT,#00H
KNA: INC T2SCNTA
MOV A,T2SCNTA
CJNE A,#100,DONE
MOV T2SCNTA,#00H
INC T2SCNTB
MOV A,T2SCNTB
CJNE A,#05H,DONE
MOV T2SCNTB,#00H
INC SECOND
MOV A,SECOND
CJNE A,#60,NEXT
MOV SECOND,#00H
INC MINITE
MOV A,MINITE
CJNE A,#60,NEXT
MOV MINITE,#00H
INC HOUR
MOV A,HOUR
CJNE A,#24,NEXT
MOV HOUR,#00H
NEXT: LCALL DISP
DONE: RETI
TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,40H
TAB: DB 0FEH,0FDH,0FBH,0F7H,0EFH,0DFH,0BFH,07FH
END
7. C語言源程序
#include <AT89X51.H>
unsigned char code dispcode[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,0x00};
unsigned char dispbitcode[]={0xfe,0xfd,0xfb,0xf7,
0xef,0xdf,0xbf,0x7f};
unsigned char dispbuf[8]={0,0,16,0,0,16,0,0};
unsigned char dispbitcnt;
unsigned char second;
unsigned char minite;
unsigned char hour;
unsigned int tcnt;
unsigned char mstcnt;
unsigned char i,j;
void main(void)
{
TMOD=0x02;
TH0=0x06;
TL0=0x06;
TR0=1;
ET0=1;
EA=1;
while(1)
{
if(P0_0==0)
{
for(i=5;i>0;i--)
for(j=248;j>0;j--);
if(P0_0==0)
{
second++;
if(second==60)
{
second=0;
}
dispbuf[0]=second%10;
dispbuf[1]=second/10;
while(P0_0==0);
}
}
if(P0_1==0)
{
for(i=5;i>0;i--)
for(j=248;j>0;j--);
if(P0_1==0)
{
minite++;
if(minite==60)
{
minite=0;
}
dispbuf[3]=minite%10;
dispbuf[4]=minite/10;
while(P0_1==0);
}
}
if(P0_2==0)
{
for(i=5;i>0;i--)
for(j=248;j>0;j--);
if(P0_2==0)
{
hour++;
if(hour==24)
{
hour=0;
}
dispbuf[6]=hour%10;
dispbuf[7]=hour/10;
while(P0_2==0);
}
}
}
}
void t0(void) interrupt 1 using 0
{
mstcnt++;
if(mstcnt==8)
{
mstcnt=0;
P1=dispcode[dispbuf[dispbitcnt]];
P3=dispbitcode[dispbitcnt];
dispbitcnt++;
if(dispbitcnt==8)
{
dispbitcnt=0;
}
}
tcnt++;
if(tcnt==4000)
{
tcnt=0;
second++;
if(second==60)
{
second=0;
minite++;
if(minite==60)
{
minite=0;
hour++;
if(hour==24)
{
hour=0;
}
}
}
dispbuf[0]=second%10;
dispbuf[1]=second/10;
dispbuf[3]=minite%10;
dispbuf[4]=minite/10;
dispbuf[6]=hour%10;
dispbuf[7]=hour/10;
}
Ⅷ 利用單片機的定時器和數碼管,設計一個電子時鍾
給你個電路和程序,//前幾天幫一個網友寫,單片機定時時鍾在調節功能,可以參考一下我程序
/***************************************************
* 6位數碼管顯示電子鍾
*
* 功能: 按鍵加,按鍵減, 按鍵,啟動和停止。
*
*
***************************************************/
#include "REG52.H"
sbit SHUG_01 = P2^0; //數碼管1
sbit SHUG_02 = P2^1; //數碼管2
sbit SHUG_03 = P2^2; //數碼管3
sbit SHUG_04 = P2^3; //數碼管4
sbit SHUG_05 = P2^4; //數碼管5
sbit SHUG_06 = P2^5; //數碼管6
sbit KEY0_01 = P0^0; //按鍵 啟動或停止sbit KEY0_02 = P0^1; //按鍵 加
sbit KEY0_03 = P0^2; //按鍵減
sbit KEY0_04 = P0^3; //按鍵菜單
#define LED_DATA P1 //P1數據埠
unsigned char value_temp = 0;unsigned char value_Outk = 0;
unsigned char value_shio = 8;
unsigned char value_feno = 40;
unsigned char value_miao = 0;
unsigned char code value_tab0[]={0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90}; //共陽極unsigned char code value_tab1[]={0x40, 0x79, 0x24, 0x30, 0x19, 0x12, 0x02, 0x78, 0x00, 0x10}; //共陽極帶點
/*
* 延時1ms延時子函數
**/
void Delay_1ms(unsigned int Time)
{
unsigned int x, y;
for(x = Time; x > 0; x--)
for(y = 120; y > 0; y--);
}
/* * 程序運行【啟動和停止】子函數
**/
void Disp_layledketCmd(void)
{
/***小時***/
SHUG_01 = 1;
LED_DATA = value_tab0[value_shio / 10]; /*******小時的十位數顯示***************/
Delay_1ms(5);
SHUG_01 = 0;
SHUG_02 = 1;
LED_DATA = value_tab1[value_shio % 10]; /*******小時的個位數顯示***************/
Delay_1ms(5);
SHUG_02 = 0;
/***分鍾***/ SHUG_03 = 1;
LED_DATA = value_tab0[value_feno / 10]; /*******分鍾的十位數顯示***************/
Delay_1ms(5);
SHUG_03 = 0;
SHUG_04 = 1;
LED_DATA = value_tab1[value_feno % 10]; /*******分鍾的個位數顯示***************/
Delay_1ms(5);
SHUG_04 = 0;
/***秒鍾***/ SHUG_05 = 1;
LED_DATA = value_tab0[value_miao / 10]; /*******秒鍾的十位數顯示***************/
Delay_1ms(5);
SHUG_05 = 0;
SHUG_06 = 1;
LED_DATA = value_tab0[value_miao % 10]; /*******秒鍾的個位數顯示***************/
Delay_1ms(5);
SHUG_06 = 0;
}
/* * 定時器初始化定時50ms
**/
void Tero_Init(void)
{
TMOD = 0x01;
TH0 = 0x4C;
TL0 = 0x00;
ET0 = 1;
TR0 = 1;
EA = 1;
}
/* * 按鍵開關【啟動和停止】子函數
**/
void Scan_keyoutCmd(void)
{
if(KEY0_01 == 0)
{
Delay_1ms(10);
if(KEY0_01 == 0)
{
TR0 = ~ TR0;
}
while(KEY0_01 == 0);
}
if(KEY0_02 == 0) {
Delay_1ms(10);
if(KEY0_02 == 0)
{
value_miao--;
if(value_miao == -1)
{
value_feno--;
value_miao = 59;
if(value_feno == -1)
{
value_shio--;
value_feno = 59;
if(value_shio == -1)
{
value_shio = 23;
}
}
}
while(KEY0_02 == 0);
}
}
if(KEY0_03 == 0) {
Delay_1ms(10);
if(KEY0_03 == 0)
{
value_miao++;
if(value_miao == 60)
{
value_miao = 0;
value_feno++;
if(value_feno == 60)
{
value_feno = 0;
value_shio++;
if(value_shio == 24)
{
value_shio = 0;
}
}
}
while(KEY0_03 == 0); //檢測鬆手
}
}
}
/* * 函數主體
**/
int main(void)
{
P1 = P2 = P3 = 0x00;
Tero_Init();
while(1)
{
Scan_keyoutCmd();
Disp_layledketCmd(); //執行應運程序
}
}
/* * 定時器中斷服務程序
**/
void Tmero()interrupt 1
{
TH0 = 0x4C;
TL0 = 0x00;
value_temp++;
if(value_temp == 20)
{
value_temp = 0;
value_miao++;
if(value_miao == 60)
{
value_feno++;
value_miao = 0;
if(value_feno == 60)
{
value_shio++;
value_feno = 0;
if(value_shio == 24)
{
value_shio = 0;
}
}
} }
}