經過幾天的努力,第一個51單片機電子時鐘終于出爐了,通過4位數碼管來顯示時間,系統晶振11.0592MHZ,仿真圖中用二極管代替時鐘冒號閃爍,非門代替三極管,讓仿真速度與真實速度達到一致,本設計用了6個按鈕來對時間及鬧鐘時間的調節、關閉,p3.2接時間分加1按鈕,p3.3接時間時加1按鈕,p3.4接鬧鐘時間與當前時間切換按鈕,按住不放顯示鬧鐘的時間,鬧鐘初始化為00:00,放開按鈕則顯示當前時間,p3.5接鬧鐘加1按鈕,p3.6接鬧鐘時加1按鈕,p3.7接關閉鬧鐘按鈕
有沒有人會問 ,怎么沒有減的按鈕呢???
為了不用那么多按鈕,所以只設置了加1的按鈕,那減的怎么辦??
程序的設計是這樣的,當分加到59的時候,再加一次就變00,當時加到23的時候,再加一次就變00,從而實現了減的效果,O(∩_∩)O,附帶仿真圖和程序源代碼及實物圖.........
實物圖目前還差3個按鈕,準備補上\(^o^)/~,電源的指示燈太亮了╮(╯▽╰)╭,準備把它拆了
作者:胡琴
聯系qq:1257394091
本程序版本規本人所有可以任意轉載:
技術支持網站:http://www.zg4o1577.cn
本程序已經通過軟件仿真和硬件制作.
程序源代碼:
org 0000h
ajmp main ;調至主程序
org 000bh ;T0中斷入口地址
ljmp inti0
org 001bh ;T1中斷入口地址
ljmp inti1
org 0030h
main:mov tmod,#11h ;設T0、T1為模式1
mov ie,#8ah ;開T0、T1中斷允許
mov th0,#4ch ;賦T0 50ms初值
mov tl0,#00h
mov th1,#4ch ;賦T1 50ms初值
mov tl1,#00h
mov sp,#60h ;設置堆棧指針
mov r0,#20 ; T0 50ms計數20次
mov 31h,#00 ;時間秒初始化
mov 32h,#00 ;時間分初始化
mov 33h,#00 ;時間時初始化
mov 38h,#00 ;鬧鐘分初始化
mov 39h,#00 ;鬧鐘時初始化
setb tr0 ;啟動T0
setb tr1 ;啟動T1
loop:lcall display ;調用時間顯示子程序
lcall key ;調用時間調節按鍵子程序
lcall keynz ;調用鬧鐘按鍵子程序
ajmp loop
inti0:push psw ;保護現場
push acc
clr ea ;關中斷
mov th0,#4ch ;重賦50ms初值
mov tl0,#00h
djnz r0,out ;對50ms計數判斷
mov r0,#20 ;重賦50ms計數值
inc 31h ;秒加1
cpl p2.2 ;P2.2取反輸出
mov a,31h
cjne a,#60,out ;判秒是否加到60,沒有加到中斷返回
mov 31h,#00 ;秒加到60,對秒清零
inc 32h ;分加1
mov a,32h
cjne a,#60,out ;判分是否加到60,沒有加到就中斷返回
mov 32h,#00 ;分加到60,對分清零
inc 33h ;時加1
mov a,33h
cjne a,#24,out ;判時是否加到24,沒有就中斷返回
mov 33h,#00 ;時加到24,對時清零
out: setb ea ;開中斷
pop acc ;恢復現場
pop psw
reti ;中斷返回
inti1:push psw ;保護現場
push acc
clr ea ;關中斷
mov th1,#4ch ;賦50ms初值
mov tl1,#00h
inc 3ah
mov a,3ah
cjne a,#20,out1 ;判斷50ms計數是否到20,沒到就中斷返回
mov 3ah,#00 ;50ms計數到20,將計數單元清零
mov a,32h
cjne a,38h,out1 ;鬧鐘分與時間分判斷
mov a,33h
cjne a,39h,out1 ;鬧鐘時與時間時判斷
clr p1.0 ;相等就清p1.0輸出
out1: setb ea ;開中斷
pop acc ;恢復現場
pop psw
reti ;中斷返回
display:mov a,31h ;秒顯示
mov b,#10
div ab
mov 20h,a ;將秒十位存20h
mov 21h,b ;將秒個位存21h
disp1: mov a,20h ;秒十位顯示
mov dptr,#table ;查表
movc a,@a+dptr ;將A與查表的值相加,回存給A
mov p0,a ;將A的值賦給P0口
clr p2.0 ;點亮秒十位
lcall del1ms ;調用延時1MS子程序
setb p2.0 ;滅秒十位
disp2: mov a,21h ;秒個位顯示
mov dptr,#table
movc a,@a+dptr
mov p0,a
clr p2.1
lcall del1ms
setb p2.1
disp3: mov a,32h ;分顯示
mov b,#10
div ab
mov 22h,a
mov 23h,b
disp4: mov a,22h ;分十位顯示
mov dptr,#table
movc a,@a+dptr
mov p0,a
clr p2.6
lcall del1ms
setb p2.6
disp5: mov a,23h ;分個位顯示
mov dptr,#table
movc a,@a+dptr
mov p0,a
clr p2.7
lcall del1ms
setb p2.7
disp6: mov a,33h ;時顯示
mov b,#10
div ab
mov 24h,a
mov 25h,b
disp7: mov a,24h ;時十位顯示
mov dptr,#table
movc a,@a+dptr
mov p0,a
clr p2.4
lcall del1ms
setb p2.4
disp8: mov a,25h ;時個位顯示
mov dptr,#table
movc a,@a+dptr
mov p0,a
clr p2.5
lcall del1ms
setb p2.5
ret
display1:mov a,38h ;鬧鐘分顯示
mov b,#10
div ab
mov 26h,a
mov 27h,b
dispnz1:mov a,26h ;鬧鐘分十位顯示
mov dptr,#table
movc a,@a+dptr
mov p0,a
clr p2.6
lcall del1ms
setb p2.6
dispnz2:mov a,27h ;鬧鐘分個位顯示
mov dptr,#table
movc a,@a+dptr
mov p0,a
clr p2.7
lcall del1ms
setb p2.7
dispnz3:mov a,39h ;鬧鐘時顯示
mov b,#10
div ab
mov 28h,a
mov 29h,b
dispnz4:mov a,28h ;鬧鐘時十位顯示
mov dptr,#table
movc a,@a+dptr
mov p0,a
clr p2.4
lcall del1ms
setb p2.4
dispnz5:mov a,29h ;鬧鐘時個位顯示
mov dptr,#table
movc a,@a+dptr
mov p0,a
clr p2.5
lcall del1ms
setb p2.5
ret
table:db 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H ;數字0-9的十六進制數
del1ms:mov r7,#10 ;1ms延時子程序
del1: mov r6,#50
del2:djnz r6,del2
djnz r7,del1
ret
del20ms:mov r5,#40 ;20ms延時子程序
del3:mov r4,#250
del4:djnz r4,del4
djnz r5,del3
ret
key:jnb p3.2,key1 ;時間分加1按鈕
jnb p3.3,key2 ;時間時加1按鈕
sjmp keyout
key1:lcall del20ms ;20ms延時消抖
jb p3.2,keyout
jnb p3.2,$ ;等待按鍵放開
inc 32h ;分加1
mov a,32h
cjne a,#60,keyout ;判分是否加到60,沒有就返回
mov 32h,#00
sjmp keyout
key2:lcall del20ms ;20ms延時消抖
jb p3.3,keyout
jnb p3.3,$ ;等待按鍵放開
inc 33h ;時加1
mov a,33h
cjne a,#24,keyout ;判時是否加到24,沒有就返回
mov 33h,#00 ;時加到24,時清零
sjmp keyout
keyout:ret
keynz:jnb p3.4,keynz1 ;鬧鐘時間和當前時間切換按鈕
jnb p3.5,keynz2 ;鬧鐘加分1按鈕
jnb p3.6,keynz3 ;鬧鐘時加1按鈕
jnb p3.7,keynz4 ;關閉鬧鐘按鈕
sjmp nzout
nz1:lcall display1 ;調用顯示鬧鐘時間子程序
jnb p3.5,keynz2
jnb p3.6,keynz3
keynz1:jnb p3.4,nz1 ;按住按鍵不放開顯示鬧鐘時間并可以調,放開則顯示當前時間
sjmp nzout
keynz2:lcall del20ms
jb p3.5,nzout
jnb p3.5,$ ;等待按鍵放開
inc 38h ;鬧鐘分加1
mov a,38h
cjne a,#60,nzout ;判鬧鐘分是否加到60,沒有就返回
mov 38h,#00 ;鬧鐘分加到60,將鬧鐘分清零
sjmp nzout
keynz3:lcall del20ms
jb p3.6,nzout
jnb p3.6,$ ;等待按鍵放開
inc 39h ;鬧鐘時加1
mov a,39h
cjne a,#24,nzout ;判鬧鐘時是否加到24,沒有就中斷返回
mov 39h,#00 ;鬧鐘時加到24,鬧鐘時清零
sjmp nzout
keynz4:jb p3.7,nzout
jnb p3.7,$ ;等待按鍵放開
setb p1.0 ;關閉鬧鐘
sjmp nzout
nzout:ret
end