A. 利用51單片機定時器實現時實時鍾功能(匯編)
51單片機有兩個16位的定時器,若果採用方式1的話,計時16位,最大計時時間
65536*1us=65.36ms,一個定時器 計時,一個定時器計數,完成一次的時間
65.36ms*65536大於一個小時的時間,去適當的值,定時一周期一個小時,
然後循環,在定時的過程中,把定時的秒數分別轉化成小時,分鍾和秒用LED顯示,就行了。編程也很簡單,書上第五,六章有定時器的用法。
B. 急求基於51單片機數字電子鍾的匯編程序
#include<reg51.h>
#include<absacc.h>
#define uchar unsigned char
#define uint unsigned int
/*七段共陰管顯示定義*/
uchar code dispcode[ ]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,
0xBF,0x86,0xCB,0xCF,0xEF,0xED,0xFD,0x87,0xFF,0xDF};
/*定義並初始化變數*/
uchar seconde=0;
uchar minite=0;
uchar hour=12;
uchar mstcnt=0;
sbit P1_0=P1^0; // second 調整定義
sbit P1_1=P1^1; //minite調整定義
sbit P1_2=P1^2; //hour調整定義
/*函數聲明*/
void delay(uchar k ); //延時子程序
void time_pro( ); //時間處理子程序
void display( ); //顯示子程序
void keyscan( ); //鍵盤掃描子程序
/*****************************/
/*延時子程序*/
/****************************/
void delay (uchar k)
{
uchar j;
while((k--)!=0)
{
for(j=0;j<125;j++)
{;}
}
}
/**************************/
/*時間處理子程序*/
/**************************/
void time_pro( void)
{
if(seconde==60) //秒鍾設為60進制
{ seconde=0;
minite++;
if( minite==60) //分鍾設為60進制
{ minite=0;
hour++;
if(hour==24) //時鍾設為24進制
{hour=0; }
}
}
}
/*****************************/
/* 顯示子程序*/
/*****************************/
void display(void)
{
P2=0xfe;
P0=dispcode[hour/10]; //顯示小時的十位
delay(4);
P2=0xfd;
P0=(dispcode[(hour%10)])|0X80; //顯示小時的個位
delay(4);
P2=0xfb;
P0=dispcode[minite/10]; //顯示分的十位
delay(4);
P2=0xf7;
P0=(dispcode[minite%10])|0X80; //顯示分的個位
delay(4);
P2=0xef;
P0=dispcode[seconde/10]; //顯示秒的十位
delay(4);
P2=0xdf;
P0=dispcode[seconde%10]; //顯示秒的個位
delay(4);
}
/*******************************/
/*鍵盤掃描子程序*/
/*******************************/
void keyscan (void)
{
if(P1_0==0) //按鍵1秒的調整
{
delay(30);
if(P1_0==0)
{
seconde++;
if(seconde==60)
{seconde=0; }
}
}
if(P1_1==0) //按鍵2分的調整
{
delay(30);
if(P1_1==0)
{
minite++;
if(minite==60)
{minite=0;}
}
}
if(P1_2==0) //按鍵3小時的調整
{
delay(30);
if(P1_2==0)
{
hour++;
if(hour==24)
{hour=0; }
}
}
}
void timer0(void) interrupt 1 using 0 //定時器0方式1,50ms中斷一次
{
TH0=0x3c;
TMOD = 0x11;
mstcnt++;
if(mstcnt==20)
{
seconde++;
mstcnt=0; //注意點。對計數單元的清零十分的重要,本次調試中就是
} //因為忽略了這一點,給我早成了很大的被動。
}
/**************************/
/*主函數*/
/**************************/
void main(void)
{ P1=0xff; //初始化p1口,全設為1
TMOD = 0x11; //time0為定時器,方式1
TH0=0x3c; //預置計數初值
TL0=0xb0;
EA=1;
ET0=1;
TR0=1;
while (1)
{
keyscan( ); //按鍵掃描
time_pro( ); //時間處理
display( ); //顯示時間
}
}
C. 基於8051單片機數字時鍾匯編語言程序
不好意思,現在我正忙著做畢業設計,抽不出時間來給你做這個啊!!!我們做課程設計都不需要調試的,你們怎麼還要求那麼高啊?不好意思!!
D. 單片機匯編語言實現實時時鍾,不知道我的哪裡出錯了,請大家幫忙看看
圖片形式的程序,不便於看,以及修改。
程序太長,也可以放在你的網路空間,大家去看。
---------
程序,重新寫了,放在:
http://hi..com/do_sermon/item/21323c9ac0555dbacc80e50e
模擬運行截圖:
E. 用單片機製作可調數字時鍾要匯編語言程序的
用這個程序吧 C和匯編都有。
數字鍾[★]
1. 實驗任務
(1. 開機時,顯示12:00:00的時間開始計時;
(2. P0.0/AD0控制「秒」的調整,每按一次加1秒;
(3. P0.1/AD1控制「分」的調整,每按一次加1分;
(4. P0.2/AD2控制「時」的調整,每按一次加1個小時;
2. 電路原理圖
圖4.20.1
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;
}
}
F. 急求單片機電子時鍾程序,用匯編寫的
A方案
--------------------------
外加一顆時鍾晶元DS1302(非常准確)。
按鍵為單片機中斷。
--------------------------
1、上電時自動顯示時、分、秒;
實現方式:上電時單片機去啟動DS1202,然後讀取裡面的時間值,自動顯示時、分、秒;
2、設置一個控制按鍵,按下按鍵,則時鍾以秒為單位開始計時;
實現方式:將DS1302此時的值暫時保存,最為計時開始的時間。
然後不停地讀取DS1302里的新的時間值,
並將新的時間值 - 計時開始的時間 = 已計時數值
3、運行狀態下可通過控制按鍵使時鍾暫停,同時顯示已計時數值;
實現方式:顯示步驟2里的已計時數值。
4、停止狀態下(已上電),按下復位按鈕,時鍾復位(清零),並進入下一次計時狀態。
實現方式:計時開始的時間換成當前時間。
B方案
--------------------------
採用單片機內部定時器計時(不準)。
按鍵為單片機中斷。
--------------------------
步驟類似,不用去讀DS1302的時間,讀自己內部的時間。
-------------------------------------------------------------------------------------------------------------------------------------------------------分割線。--------------------------------------------------------------------------
樓上的方案是當前比較常見的方案了。
沒有給出程序
先給出A 方案程序如下。。。。//C語言編寫。
*頭文件*/
#include <reg52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
#define nop() _nop_()
sbit T_CLK = P1^4; /*實時時鍾時鍾線引腳 */
sbit T_IO = P1^5; /*實時時鍾數據線引腳 */
sbit T_RST = P2^2; /*實時時鍾復位線引腳 */
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
sbit time_en_port = P3^7; /*時間控制通道寄存器LE控制腳*/
sbit sled_en_port = P3^6; /*數碼管控制通道寄存器LE控制腳*/
#define sled_dm_port P0 /*定義數碼管段碼的控制腳*/
#define sled_wm_port P2 /*定義數碼管位碼的控制腳*/
/*定義數碼管顯示字元跟數字的對應數組關系*/
uchar code mun_to_char[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
/* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
/*定義需要點亮的數碼管*/
uchar code sled_bit_table[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
uchar data sled_data[8]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}; /*0-7號SLED緩沖值*/
uchar data led_lighten_bit=0 ; /*LED燈點亮標志位0-7*/
uchar data time_data[8]={0x00,0x57,0x16,0x00,0x00,0x00,0x00,0x00};/*格式為: 秒 分 時 日 月 星期 年 */
/*-----------------------------------------------
顯示部分程序,採用定時器0產生中斷,1MS更新一次
------------------------------------------------*/
void SLED_Disp() interrupt 1 using 3
{
TH0 = (65536-1000)/256;
TL0 = (65536-1000)/256;
time_en_port = 0; /*關閉時鍾控制通道*/
sled_wm_port = sled_bit_table[led_lighten_bit]; /*輸出位碼數據到數碼管*/
sled_dm_port = sled_data[led_lighten_bit]; /*輸出段碼數據到數碼管*/
sled_en_port = 1; /*打開數碼管控制通道*/
sled_en_port = 0; /*關閉數碼管控制通道*/
sled_wm_port = 0xdf; /* 釋放P2埠,同時關閉發光二極體顯示*/
time_en_port = 1; /*打開時鍾控制通道*/
led_lighten_bit++;
if(led_lighten_bit>=8) led_lighten_bit=0; /*8位數碼管全動態輸出*/
}
void T0_valueSet() /*定義中斷方式,中斷時間*/
{
TMOD = 0x01; /*定時0,工作在方式1*/
TH0 = (65536-1000)/256;
TL0 = (65536-1000)/256;
TR0 = 1; /*啟動計數*/
EA = 1; /*開總中斷*/
ET0 = 1; /*開定時器0中斷*/
return;
}
/********************************************************************
函 數 名:RTInputByte()
功 能:實時時鍾寫入一位元組
說 明:往DS1302寫入1Byte數據 (內部函數)
入口參數:d 寫入的數據
返 回 值:無
設 計:zhaojunjie 日 期:2002-03-19
修 改: 日 期:
***********************************************************************/
void RTInputByte(uchar d)
{
uchar i;
ACC = d;
for(i=8; i>0; i--)
{
T_IO = ACC0; /*相當於匯編中的 RRC */
T_CLK = 1;
T_CLK = 0;
ACC = ACC >> 1;
}
}
/********************************************************************
函 數 名:RTOutputByte()
功 能:實時時鍾讀取一位元組
說 明:從DS1302讀取1Byte數據 (內部函數)
入口參數:無
返 回 值:ACC
設 計:zhaojunjie 日 期:2002-03-19
修 改: 日 期:
***********************************************************************/
uchar RTOutputByte(void)
{
uchar i;
for(i=8; i>0; i--)
{
ACC = ACC >>1; /*相當於匯編中的 RRC */
ACC7 = T_IO;
T_CLK = 1;
T_CLK = 0;
}
return(ACC);
}
/********************************************************************
函 數 名:W1302()
功 能:往DS1302寫入數據
說 明:先寫地址,後寫命令/數據 (內部函數)
調 用:RTInputByte() , RTOutputByte()
入口參數:ucAddr: DS1302地址, ucData: 要寫的數據
返 回 值:無
設 計:zhaojunjie 日 期:2002-03-19
修 改: 日 期:
***********************************************************************/
void W1302(uchar ucAddr, uchar ucDa)
{
T_RST = 0;
T_CLK = 0;
T_RST = 1;
RTInputByte(ucAddr); /* 地址,命令 */
RTInputByte(ucDa); /* 寫1Byte數據*/
T_CLK = 1;
T_RST = 0;
}
/********************************************************************
函 數 名:R1302()
功 能:讀取DS1302某地址的數據
說 明:先寫地址,後讀命令/數據 (內部函數)
調 用:RTInputByte() , RTOutputByte()
入口參數:ucAddr: DS1302地址
返 回 值:ucData :讀取的數據
設 計:zhaojunjie 日 期:2002-03-19
修 改: 日 期:
***********************************************************************/
uchar R1302(uchar ucAddr)
{
uchar ucData;
T_RST = 0;
T_CLK = 0;
T_RST = 1;
RTInputByte(ucAddr); /* 地址,命令 */
ucData = RTOutputByte(); /* 讀1Byte數據 */
T_CLK = 1;
T_RST = 0;
return(ucData);
}
/********************************************************************
函 數 名:BurstW1302T()
功 能:往DS1302寫入時鍾數據(多位元組方式)
說 明:先寫地址,後寫命令/數據
調 用:RTInputByte()
入口參數:pWClock: 時鍾數據地址 格式為: 秒 分 時 日 月 星期 年 控制
8Byte (BCD碼)1B 1B 1B 1B 1B 1B 1B 1B
返 回 值:無
設 計:zhaojunjie 日 期:2002-03-19
修 改: 日 期:
***********************************************************************/
void BurstW1302T(uchar *pWClock)
{
uchar i;
W1302(0x8e,0x00); /* 控制命令,WP=0,寫操作?*/
T_RST = 0;
T_CLK = 0;
T_RST = 1;
RTInputByte(0xbe); /* 0xbe:時鍾多位元組寫命令 */
for (i = 8; i>0; i--) /*8Byte = 7Byte 時鍾數據 + 1Byte 控制*/
{
RTInputByte(*pWClock); /* 寫1Byte數據*/
pWClock++;
}
T_CLK = 1;
T_RST = 0;
}
/********************************************************************
函 數 名:BurstR1302T()
功 能:讀取DS1302時鍾數據
說 明:先寫地址/命令,後讀數據(時鍾多位元組方式)
調 用:RTInputByte() , RTOutputByte()
入口參數:pRClock: 讀取時鍾數據地址 格式為: 秒 分 時 日 月 星期 年
7Byte (BCD碼)1B 1B 1B 1B 1B 1B 1B
返 回 值:無
設 計:zhaojunjie 日 期:2002-03-19
修 改: 日 期:
***********************************************************************/
void BurstR1302T(uchar *pRClock)
{
uchar i;
T_RST = 0;
T_CLK = 0;
T_RST = 1;
RTInputByte(0xbf); /* 0xbf:時鍾多位元組讀命令 */
for (i=8; i>0; i--)
{
*pRClock = RTOutputByte(); /* 讀1Byte數據 */
pRClock++;
}
T_CLK = 1;
T_RST = 0;
}
/********************************************************************
函 數 名:Set1302()
功 能:設置初始時間
說 明:先寫地址,後讀命令/數據(寄存器多位元組方式)
調 用:W1302()
入口參數:pClock: 設置時鍾數據地址 格式為: 秒 分 時 日 月 星期 年
7Byte (BCD碼)1B 1B 1B 1B 1B 1B 1B
返 回 值:無
設 計:zhaojunjie 日 期:2002-03-19
修 改: 日 期:
***********************************************************************/
void Set1302(uchar *pClock)
{
uchar i;
uchar ucAddr = 0x80;
EA = 0;
W1302(0x8e,0x00); /* 控制命令,WP=0,寫操作?*/
for(i =7; i>0; i--)
{
W1302(ucAddr,*pClock); /* 秒 分 時 日 月 星期 年 */
pClock++;
ucAddr +=2;
}
W1302(0x8e,0x80); /* 控制命令,WP=1,防寫?*/
EA = 1;
}
/********************************************************************
函 數 名:Get1302()
功 能:讀取DS1302當前時間
說 明:
調 用:R1302()
入口參數:ucCurtime: 保存當前時間地址。當前時間格式為: 秒 分 時 日 月 星期 年
7Byte (BCD碼) 1B 1B 1B 1B 1B 1B 1B
返 回 值:無
設 計:zhaojunjie 日 期:2002-03-19
修 改: 日 期:
***********************************************************************/
void Get1302(uchar ucCurtime[])
{
uchar i;
uchar ucAddr = 0x81;
EA = 0;
for (i=0; i<7; i++)
{
ucCurtime[i] = R1302(ucAddr);/*格式為: 秒 分 時 日 月 星期 年 */
ucAddr += 2;
}
EA = 1;
}
void delay_1ms(uchar x)
/* 1MS為單位的延時程序 */
{
uchar j;
while(x--){
for(j=0;j<125;j++)
{;}
}
}
void main()
{
T0_valueSet();
Set1302(time_data);
while(1){
Get1302(time_data);
sled_data[0]=mun_to_char[time_data[2]/0x10];
sled_data[1]=mun_to_char[time_data[2]%0x10];
sled_data[3]=mun_to_char[time_data[1]/0x10];
sled_data[4]=mun_to_char[time_data[1]%0x10];
sled_data[6]=mun_to_char[time_data[0]/0x10];
sled_data[7]=mun_to_char[time_data[0]%0x10];
delay_1ms(200);
}
}
方案B.
#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);
}
}
以上的程序都是用C編寫 如果是初學還是直接用C編寫吧 雖然匯編也很好用 但是C已經是時代的趨勢了。。
如果以上能幫到你 請給分哦。。 有什麼不懂得也可以問我。
G. 用匯編語言做單片機時鍾顯示
基於c8051f020單片機最小系統的實時時鍾顯示程序
c8051f020 FYD12864-0402B LCD顯示,按鍵電子時鍾//
#include <c8051f020.h>
#include<lcd.h>
#include <intrins.h>
#define uchar unsigned char
void lcd_ini();
void DISPInitial();
void ascii_change(void);
void delay();
void wri_add(uchar com);
void wri_dat(uchar com1);
void shan(void);
void disp();
void tkey(void);
void PORT_Init (void);
sbit cs=P1^7;
sbit sid=P1^6;
sbit sclk=P1^5;
bit flag=1;
uchar dat,count,f=1;//f測試哪個單元為當前閃爍狀態
uchar data clock[3]={24,00,00};
uchar code clockname[10]={"北京時間:"};
uchar data num[6];
/*******主程序*************/
void main()
{
lcd_ini();
count=10;//機器周期為1us,每次定時50ms,此變數用來控制循環次數,在下面賦值為20,共定時1秒
TMOD=0x01;
TL0=0XB0;
TH0=0X3C;
EA=1;
ET0=1;
IT0=1;
EX0=1;
TR0=1;
while(1)
{
back:ascii_change();
disp();
delay();
if(flag==1)
goto back;
tkey();
shan();
delay();
}
}
/****lcd初始化*******/
/*void lcd_ini()
{
wri_add(0x30);
delay();
wri_add(0x0c);
delay();
wri_add(0x01);
delay();
wri_add(0x06);
delay();
}*/
void PORT_Init (void)
{
XBR0 = 0x00; //不讓他連上IO口
XBR1 = 0x14; //允許外部中斷連在埠上
XBR2 = 0x40; // Enable crossbar and weak pull-ups
P0MDOUT |= 0x00; // enable TX0 as a push-pull output
// P1MDOUT |= 0x07; // enable P1.6 (LED) as push-pull output
P2MDOUT=0xfe; //為了驅動步進電機的控制線
//P3MDOUT = 0xFF;
P74OUT=0x00; //配置成漏極方式可以讓LCD顯示成功 ,我試了配置成推挽方式不能正常顯示
}
/********定時程序*************/
void timer1() interrupt 1 using 2
{
TL0=0XB0;
TH0=0X3C;
count--;
if(count==0)
{
count=10;
clock[2]++;//秒//
}
else
goto out;
if(clock[2]==60)
{
clock[2]=0;
clock[1]++;//分//
}
if(clock[1]==60)
{
clock[1]=0;
clock[0]++;
}
if(clock[0]==24)//時//
clock[0]=0;
out:_nop_();
}
/*******十位個位轉換成ASCII碼************/
void ascii_change(void)
{
num[5]=clock[2]-(clock[2]/10)*10+0x30;
num[4]=clock[2]/10+0x30;
num[3]=clock[1]-(clock[1]/10)*10+0x30;
num[2]=clock[1]/10+0x30;
num[1]=clock[0]-(clock[0]/10)*10+0x30;
num[0]=clock[0]/10+0x30;
}
/********廷時程序*************/
void delay()
{
uchar i,j;
for (i=250;i>0;i--)
for (j=250;j>0;j--);
}
/*****Write address*********/
void wri_add(uchar com)
{
uchar i,j,k;
cs=0;
cs=1;
dat=0xf8;
for(i=1;i<=8;i++)
{
sid=(bit)(dat&0x80);
sclk=0;
sclk=1;
sclk=0;
dat=dat<<1;
}
dat=com;
dat=dat&0xf0;
for(j=1;j<=8;j++)
{
sid=(bit)(dat&0x80);
sclk=0;
sclk=1;
sclk=0;
dat=dat<<1;
}
dat=com;
dat=_cror_(dat,4);// 此為高低四位交換
dat=dat&0xf0;
for(k=1;k<=8;k++)
{
sid=(bit)(dat&0x80);
sclk=0;
sclk=1;
sclk=0;
dat=dat<<1;
}
}
/*********Write data*************/
void wri_dat(uchar com1)
{
uchar i,j,k;
cs=0;
cs=1;
dat=0xfa;
for(i=1;i<=8;i++)
{
sid=(bit)(dat&0x80);
sclk=0;
sclk=1;
sclk=0;
dat=dat<<1;
}
dat=com1;
dat=dat&0xf0;
for(j=1;j<=8;j++)
{
sid=(bit)(dat&0x80);
sclk=0;
sclk=1;
sclk=0;
dat=dat<<1;
}
dat=com1;
dat=_cror_(dat,4);// 此為高低四位交換
dat=dat&0xf0;
for(k=1;k<=8;k++)
{
sid=(bit)(dat&0x80);
sclk=0;
sclk=1;
sclk=0;
dat=dat<<1;
}
}
/******display program***********/ //顯示時間
void disp()
{
uchar i,k=0;
wri_add(0x80);
for (i=1;i<=9;i++)
wri_dat(clockname[i-1]);
wri_add(0x90);
for (i=1;i<=6;i++)
{
k++;
if(k==3||k==5)
wri_dat(clockname[8]);//時間之間的冒號。
wri_dat(num[i-1]);
}
}
/*******閃爍程序*************************/
void shan(void)
{
uchar i,k=0;
wri_add(0x90);
if(f==1)
{
num[0]=' ';
num[1]=' ';
}
else
goto next;
for (i=1;i<=6;i++)
{
k++;
if(k==3||k==5)
wri_dat(clockname[8]);//時間之間的冒號。
wri_dat(num[i-1]);
}
goto return1;
next: if(f==2)
{
num[2]=' ';
num[3]=' ';
}
else
goto next1;
for (i=1;i<=6;i++)
{
k++;
if(k==3||k==5)
wri_dat(clockname[8]);//時間之間的冒號。
wri_dat(num[i-1]);
}
goto return1;
next1: if(f==3)
{
num[4]=' ';
num[5]=' ';
}
else
goto return1;
for (i=1;i<=6;i++)
{
k++;
if(k==3||k==5)
wri_dat(clockname[8]);//時間之間的冒號。
wri_dat(num[i-1]);
}
return1:_nop_();
}
/*******外部中斷***********/
void intr0() interrupt 0 using 2
{
flag=~flag;//判斷是否閃爍位//
TR0=~TR0; //閃關定時否則開定時
f=1;
}
/**********按鍵程序************/
void tkey(void)
{
uchar judcekey;
judcekey=P1&0x0f;
if(judcekey==0x0f)
goto return2;
/*******移位鍵*********/
if (judcekey==0x0e)
f++;
if (f==4)
f=1;
/**********加一鍵*********/
if(judcekey==0x0d)
{clock[f-1]++;}
if (f==1)
{ if (clock[f-1]==24){
clock[f-1]=0;}
}
else{ if (clock[f-1]==60)
clock[f-1]=0;
}
/******減一鍵***********/
if(judcekey==0x0b)
{clock[f-1]--;}
if (f==1)
{ if (clock[f-1]==0xff){
clock[f-1]=23;}
}
else
{ if (clock[f-1]==0xff)
clock[f-1]=59;
}
return2:_nop_();
}
//本程序已經調試成功並能夠正確執行
H. 51單片機簡易電子鍾設計。匯編語言編寫
KEYVALEQU 30H
KEYTMEQU 31H
KEYSCANEQU 32H
DATEQU 33H
SCANLEDEQU 39H
CLKEQU 77H
SECEQU 78H
MINEQU 79H
HOUREQU 7AH
PAUSEBIT 00H
DOTBIT 01H
ORG 0000H
LJMP MAIN
ORG 000BH
LJMP T0ISR;50ms定時
ORG 001BH
LJMP T1ISR;掃描顯示
ORG 0030H
MAIN:
MOV SP,#5FH
MOV TMOD,#11H
MOV TH0,#03CH
MOV TL0,#0B0H
MOV TH1,#0ECH
MOV TL1,#078H
MOV KEYVAL,#0
MOV SCANLED,#0
MOV 33H,#10H
MOV 34H,#10H
MOV 35H,#10H
MOV 36H,#10H
MOV 37H,#10H
MOV 38H,#10H
MOV SEC,#0
MOV MIN,#0
MOV HOUR,#0
MOV CLK,#0
CLR PAUSE
SETB EA
SETB ET1
SETB TR1
LOOP:
LCALL KEYSEL
MOV A,KEYVAL
CJNE A,#0FFH,LOOP1
SJMP LOOP
LOOP1:
CJNE A,#10,LOOP2;「ON」啟動
SETB TR0
SETB ET0
SETB PAUSE
SJMP LOOP
LOOP2:
CJNE A,#11,LOOP3;「=」清零
MOV SEC,#0
MOV MIN,#0
MOV HOUR,#0
LCALL DISCHG
SJMP LOOP
LOOP3:
CJNE A,#15,LOOP4;「+」暫停
CLR TR0
CLR ET0
CLR PAUSE
SJMP LOOP
LOOP4:
CJNE A,#14,LOOP5;「-」清顯示暫停
MOV 33H,#10H
MOV 34H,#10H
MOV 35H,#10H
MOV 36H,#10H
MOV 37H,#10H
MOV 38H,#10H
CLR TR0
CLR ET0
CLR PAUSE
SJMP LOOP
LOOP5:
CJNE A,#10,LOOP6;數字鍵
LOOP6:
JC LOOP7
LJMP LOOP
LOOP7:
JNB PAUSE,LOOP8;暫停狀態可以輸入數字鍵
LJMP LOOP
LOOP8:
MOV 33H,34H
MOV 34H,35H
MOV 35H,36H
MOV 36H,37H
MOV 37H,38H
MOV 38H,KEYVAL
MOV A,33H
SWAP A
ORL A,34H
LCALL BCDH
MOV HOUR,A
MOV A,35H
SWAP A
ORL A,36H
LCALL BCDH
MOV MIN,A
MOV A,37H
SWAP A
ORL A,38H
LCALL BCDH
MOV SEC,A
LJMP LOOP
;------------------
;BCD轉換為十六進制
BCDH:
MOV B,#10H
DIV AB
MOV R7,B
MOV B,#10
MUL AB
ADD A,R7
RET
;------------------
;十六進制轉換為BCD
HBCD:
MOV B,#10
DIV AB
SWAP A
ORL A,B
RET
;------------------
KEYSEL:
MOVKEYVAL,#0
MOVKEYSCAN,#0EFH
LCALLGETKEY
MOVA,KEYTM
JZKEYS1
MOVKEYVAL,A
SJMPKEYRTN
KEYS1:
MOVKEYSCAN,#0DFH
LCALLGETKEY
MOVA,KEYTM
JZKEYS2
CLRC
ADDA,#4
MOVKEYVAL,A
SJMPKEYRTN
KEYS2:
MOVKEYSCAN,#0BFH
LCALLGETKEY
MOVA,KEYTM
JZKEYS3
CLRC
ADDA,#8
MOVKEYVAL,A
SJMPKEYRTN
KEYS3:
MOVKEYSCAN,#7FH
LCALLGETKEY
MOVA,KEYTM
JZKEYRTN
CLRC
ADDA,#12
MOVKEYVAL,A
KEYRTN:
LCALL CHGKEY
RET
;--------------------
GETKEY:
MOV KEYTM,#0
MOVA,KEYSCAN
MOVP3,A
NOP
MOVA,P3
ANLA,#0FH
XRLA,#0FH
JZNOKEY
MOV R2,#10
LCALL DELAY
MOVA,P3
ANLA,#0FH
XRLA,#0FH
JZNOKEY
MOVA,P3
ANLA,#0FH
MOVR7,A
SF:
MOVA,P3
ANLA,#0FH
XRLA,#0FH
JNZSF
MOVA,R7
CJNEA,#0EH,NK1
MOVKEYTM,#1
SJMPNOKEY
NK1:
CJNEA,#0DH,NK2
MOVKEYTM,#2
SJMPNOKEY
NK2:
CJNEA,#0BH,NK3
MOVKEYTM,#3
SJMPNOKEY
NK3:
CJNEA,#07H,NOKEY
MOVKEYTM,#4
NOKEY:RET
;--------------------
DELAY:
MOV R3,#50
DELAY1:
MOV R4,#100
DJNZ R4,$
DJNZ R3,DELAY1
DJNZ R2,DELAY
RET
;--------------------
T0ISR:
PUSH ACC
CLR TR0
MOV TH0,#3CH
MOV TL0,#0B0H
SETB TR0
INC CLK
MOV A,CLK
CJNE A,#20,T0ISRE
MOV CLK,#0
INC SEC
MOV A,SEC
CJNE A,#60,T0ISRE
MOV SEC,#0
INC MIN
MOV A,MIN
CJNE A,#60,T0ISRE
MOV MIN,#0
INC HOUR
MOV A,HOUR
CJNE A,#24,T0ISRE
MOV SEC,#0
MOV MIN,#0
MOV HOUR,#0
T0ISRE:
LCALL DISCHG
POP ACC
RETI
;--------------------
DISCHG:
MOV A,HOUR
LCALL HBCD
PUSH ACC
ANL A,#0FH
MOV 34H,A
POP ACC
ANL A,#0F0H
SWAP A
MOV 33H,A
MOV A,MIN
LCALL HBCD
PUSH ACC
ANL A,#0FH
MOV 36H,A
POP ACC
ANL A,#0F0H
SWAP A
MOV 35H,A
MOV A,SEC
LCALL HBCD
PUSH ACC
ANL A,#0FH
MOV 38H,A
POP ACC
ANL A,#0F0H
SWAP A
MOV 37H,A
RET
;--------------------
T1ISR:
PUSH ACC
CLR TR1
MOV TH1,#0ECH
MOV TL1,#78H
SETB TR1
MOV DPTR,#LEDTAB
T100:
MOV R0,#DAT
MOV A,SCANLED
ADD A,R0
MOV R0,A
MOV A,SCANLED
JNZ T101
MOV P2,#01H
CLR DOT
SJMP T1DIS
T101:
DEC A
JNZ T102
MOV P2,#02H
SETB DOT
SJMP T1DIS
T102:
DEC A
JNZ T103
MOV P2,#04H
CLR DOT
SJMP T1DIS
T103:
DEC A
JNZ T104
MOV P2,#08H
SETB DOT
SJMP T1DIS
T104:
DEC A
JNZ T105
MOV P2,#10H
CLR DOT
SJMP T1DIS
T105:
MOV P2,#20H
CLR DOT
T1DIS:
MOV A,@R0
MOVC A,@A+DPTR
JNB DOT,T1DIS1
ORL A,#01H
T1DIS1:
CPL A
MOV P0,A
INC SCANLED
MOV A,SCANLED
CJNE A,#6,T1END
MOV SCANLED,#0
T1END:
POP ACC
RETI
;--------------------
CHGKEY:
MOV A,KEYVAL
JZ KV16
DEC A
JNZ KV01
MOV KEYVAL,#7
RET
KV01:
DEC A
JNZ KV02
MOV KEYVAL,#4
RET
KV02:
DEC A
JNZ KV03
MOV KEYVAL,#1
RET
KV03:
DEC A
JNZ KV04
MOV KEYVAL,#10
RET
KV04:
DEC A
JNZ KV05
MOV KEYVAL,#8
RET
KV05:
DEC A
JNZ KV06
MOV KEYVAL,#5
RET
KV06:
DEC A
JNZ KV07
MOV KEYVAL,#2
RET
KV07:
DEC A
JNZ KV08
MOV KEYVAL,#0
RET
KV08:
DEC A
JNZ KV09
MOV KEYVAL,#9
RET
KV09:
DEC A
JNZ KV10
MOV KEYVAL,#6
RET
KV10:
DEC A
JNZ KV11
MOV KEYVAL,#3
RET
KV11:
DEC A
JNZ KV12
MOV KEYVAL,#11
RET
KV12:
DEC A
JNZ KV13
MOV KEYVAL,#12
RET
KV13:
DEC A
JNZ KV14
MOV KEYVAL,#13
RET
KV14:
DEC A
JNZ KV15
MOV KEYVAL,#14
RET
KV15:
DEC A
JNZ KV16
MOV KEYVAL,#15
RET
KV16:
MOV KEYVAL,#0FFH
RET
;--------------------
LEDTAB:DB 0FCH;"0"00H
DB 60H;"1"01H
DB 0DAH;"2"02H
DB 0F2H;"3"03H
DB 66H;"4"04H
DB 0B6H;"5"05H
DB 0BEH;"6"06H
DB 0E0H;"7"07H
DB 0FEH;"8"08H
DB 0F6H;"9"09H
DB 0EEH;"A"0AH
DB 3EH;"B"0BH
DB 9CH;"C"0CH
DB 7AH;"D"0DH
DB 9EH;"E"0EH
DB 8EH;"F"0FH
DB 00H;" "10H
;--------------------
END