|
樓主 |
發表於 2012-11-18 01:34:29
|
顯示全部樓層
本帖最後由 fatzeros 於 2012-11-18 01:36 AM 編輯
剛嗑完一本8051徹底研究-入門篇後,就寫了這個小玩具,
我個人覺得,這本書還不錯的啦!學ASM51可以看這本書!
怎麼精簡啊?我還沒學到奧義啊!目前還在打怪練等!
如果版上各先進有時間的話,還請多多分享啊!
小弟先跪謝了!
發表新版程序,有加入了展式功能:
;/*----------------------------------------------------------------------------------------------
; 名稱:小朋友的數字學習機
; 編寫:沈大胖
; 日期:2012/11/16_V1.2
; 修改:程序大修,加入模式功能
; 內容:使用七段顯示器,及八個按鍵,讓小朋友學習認識數字0~9
;-----------------------------------------------------------------------------------------------*/
;定義LED接腳位置
LED_ALL EQU P1
LEDA EQU P1.1
LEDB EQU P1.0
LEDC EQU P1.7
LEDD EQU P1.5
LEDE EQU P1.4
LEDF EQU P1.2
LEDG EQU P1.3
LEDH EQU P1.6
;定義KEY接腳位置
KEY_2X4 EQU P2
;定義模式使用資料記憶體位址(DATA MEMORY)
MODE DATA 021H ;為0時為拼盤模式,為1時為展示模式
;設定P2.5~p2.0為輸入模式,STC特定SFR
P2M1 EQU 095H
P2M0 EQU 096H
MOV P2M1,#00111111B
MOV P2M0,#00000000B
;程序開始
ORG 0000H ; PC=0000H
START: ;程序開始
MOV LED_ALL,#0FFH ;初始化七段為不亮,11111111B
MOV SP,#081H ;設定PC值堆疉自DATA MEMORY 081H開始,依STC_DATASHEET
MOV MODE,#000H ;初始為拼盤模式
SJMP MAIN ;程序JUMP至MAIN段
ORG 0030H
MAIN: ;主程序(主循環)
MOV R4,#000H ;初始化鍵盤定義為暫存器R4並清零
ACALL KEY ;呼叫鍵盤掃描子程序
JB MODE.0,DEMO_START ;MODE為1時跳至DEMO子程序(展示模式)
ACALL LEDA_SWITCH ;呼叫LED子程序(拼盤模式)
SJMP MAIN ;主程序無限循環
DEMO_START: ;DEMO_START子程序(初始展示模式)
MOV LED_ALL,#0FFH ;初始化七段為不亮,11111111B
ACALL DELAY500MS ;呼叫延時程序,以待穩定
MOV R7,#10 ;定義展示數字個數為暫存器R7並定為10個
MOV DPTR,#TABLE ;TABLE載入DPTR
MOV R6,#000H ;初始定義展式模式暫存數為暫存器R6並由0開始
DEMO: ;DEMO子程序(七段驅動展示0~9)
MOV A,R6 ;載入R6值至ACC,展示數由R6控制
MOVC A,@A+DPTR ;載入TABLE至ACC
MOV LED_ALL,A ;七段顯示
ACALL DELAY500MS ;呼叫延時程序
ACALL DELAY500MS ;呼叫延時程序
INC R6 ;展示數加1
DJNZ R7,DEMO ;循環R7次數
CLR A ;ACC清零
MOV R6,#000H ;R6清零
MOV A,R6 ;載入R6至ACC
MOVC A,@A+DPTR ;載入ACC+DPTR至ACC
MOV LED_ALL,A ;七段顯示
COUNT: ;COUNT子程序(展示模式循環開始)
ACALL KEY ;呼叫鍵盤子程序
JNB MODE.0,MAIN ;如MODE為0則跳至MAIN段(拼盤模式)
CJNE R4,#5,COUNT_DEC ;如不為第5鍵,則跳至COUNT_DEC段(定義第5鍵為加鍵)
CJNE R6,#009H,R6_UP ;展示數暫存器不為第9個時,則跳至R6_UP段,(避免TABLE溢位,顯示不正常)
MOV R6,#000H ;定展示數暫存器R6為第0個,避免顯示不正常
MOV A,R6 ;載入R6至ACC
MOVC A,@A+DPTR ;載入A+DPTR至ACC
MOV LED_ALL,A ;七段顯示
MOV R4,#000H ;初始鍵盤暫存器R4
SJMP COUNT ;COUNT無限循環至跳出展示模式
COUNT_DEC: ;COUNT_DEC子程序
JNB MODE.0,MAIN ;判斷是否為展示模式
CJNE R4,#3,COUNT ;定義第3鍵為減鍵
CJNE R6,#000H,R6_DOWN ;展示數暫存器不為第0個時,則跳至R6_DOWN段,避免顯示不正常
MOV R6,#009H ;定展示數暫存器為第9個,避免顯示不正常
MOV A,R6 ;七段顯示驅動
MOVC A,@A+DPTR ;七段顯示驅動
MOV LED_ALL,A ;七段顯示驅動
MOV R4,#000H ;初始鍵盤展存器R4
SJMP COUNT ;程序跳回COUNT段並無限循環至跳出
R6_UP: ;R6_UP子程序
INC R6 ;展示數暫存器R6加1
MOV A,R6 ;七段顯示驅動
MOVC A,@A+DPTR ;七段顯示驅動
MOV LED_ALL,A ;七段顯示驅動
MOV R4,#000H ;初始鍵盤暫存器R4
SJMP COUNT ;程序跳回COUNT段並無限循環至跳出
R6_DOWN: ;R6_DOWN子程序(展示模式循環結束)
DEC R6 ;展示數暫存器R6減1
MOV A,R6 ;七段顯示驅動
MOVC A,@A+DPTR ;七段顯示驅動
MOV LED_ALL,A ;七段顯示驅動
MOV R4,#000H ;初始鍵盤暫存器R4
SJMP COUNT ;程序跳回COUNT段並無限循環至跳出
LEDA_SWITCH: ;LEDA_SWITCH子程序(拼盤模式循環開始)
CJNE R4,#1,LEDB_SWITCH ;若R4不為1則跳至LEDB_SWITCH
CPL LEDA ;LEDA取反
RET ;程序跳至MAIN段(主循環)
LEDB_SWITCH: ;LEDB_SWITCH子程序
CJNE R4,#2,LEDC_SWITCH ;若R4不為2則跳至LEDB_SWITCH
CPL LEDB ;LEDB取反
RET ;程序跳至MAIN段(主循環)
LEDC_SWITCH: ;LEDC_SWITCH子程序
CJNE R4,#3,LEDD_SWITCH ;若R4不為3則跳至LEDC_SWITCH
CPL LEDC ;LEDC取反
RET ;程序跳至MAIN段(主循環)
LEDD_SWITCH: ;LEDD_SWITCH子程序
CJNE R4,#4,LEDE_SWITCH ;若R4不為4則跳至LEDD_SWITCH
CPL LEDD ;LEDD取反
RET ;程序跳至MAIN段(主循環)
LEDE_SWITCH: ;LEDE_SWITCH子程序
CJNE R4,#5,LEDF_SWITCH ;若R4不為5則跳至LEDE_SWITCH
CPL LEDE ;LEDE取反
RET ;程序跳至MAIN段(主循環)
LEDF_SWITCH: ;LEDF_SWITCH子程序
CJNE R4,#6,LEDG_SWITCH ;若R4不為6則跳至LEDF_SWITCH
CPL LEDF ;LEDF取反
RET ;程序跳至MAIN段(主循環)
LEDG_SWITCH: ;LEDG_SWITCH子程序
CJNE R4,#7,LEDH_SWITCH ;若R4不為7則跳至LEDG_SWITCH
CPL LEDG ;LEDG取反
RET ;程序跳至MAIN段(主循環)
LEDH_SWITCH: ;LEDH_SWITCH_OR_CLEAR子程序
CJNE R4,#8,LED_END ;若R4不為8則跳至LED_END段
CPL LEDH ;LEDH取反
RET ;程序跳至MAIN段(主循環)
LED_END: ;LED_END子程序(拼盤模式循環結束)
AJMP MAIN ;跳回MAIN段
KEY: ;2行4列矩陣鍵盤掃描子程序,
; P1.4為第1行,P1.5為第2行,
; P1.0~P1.3為第1~4列
MOV KEY_2X4,#00110000B ;初始化鍵盤
AJMP K10 ;跳至K10段
K10: ;K10子程序(矩陣鍵盤第1行掃描開始)
JB KEY_2X4.4,K20 ;若P1.4為1時(表示第1行無按鍵按下)跳至K20段
K11: ;K11子程序
MOV KEY_2X4,#00111110B ;初始化第1行第1列鍵
JB KEY_2X4.4,K12 ;掃描第1行鍵盤,如無按下程序跳至K12段
MOV R4,#4 ;定此鍵為4,R4值為4,為模式切換鍵
ACALL DELAY500MS ;呼叫延時去抖動
JB KEY_2X4.4,K12 ;判斷此鍵是否持續按下
ACALL T0_2S ;呼叫定時器
AJMP KEND ;中斷掃描程序跳至KEND段,返回MAIN主程序
K12: ;K12子程序
MOV KEY_2X4,#00111101B ;初始化第1行第2列鍵
JB KEY_2X4.4,K13 ;掃描第1行鍵盤,如無按下程序跳至K13段
MOV R4,#5 ;定此鍵為5,R4值為5
ACALL DELAY500MS ;呼叫延時去抖動
AJMP KEND ;中斷掃描程序跳至KEND段,返回MAIN主程序
K13: ;K13子程序
MOV KEY_2X4,#00111011B ;初始化第1行第3列鍵
JB KEY_2X4.4,K14 ;掃描第1行鍵盤,如無按下程序跳至K14段
MOV R4,#6 ;定此鍵為6,R4值為6
ACALL DELAY500MS ;呼叫延時去抖動
AJMP KEND ;中斷掃描程序跳至KEND段,返回MAIN主程序
K14: ;K14子程序
MOV KEY_2X4,#00110111B ;初始化第1行第4列鍵
JB KEY_2X4.4,KEND ;掃描第1行鍵,如無按下程序跳至KEND段,返回MAIN主程序,第一行掃描結束
MOV R4,#1 ;定此鍵為1,R4值為1
ACALL DELAY500MS ;呼叫延時去抖動
AJMP KEND ;中斷掃描程序跳至KEND段,返回MAIN主程序
K20: ;K20子程序(矩陣鍵盤第2行掃描開始)
JB KEY_2X4.5,KEND ;若P1.5為1時(表示第2行無按鍵按下)跳至KEND段,返回MAIN主程序
K21: ;K21子程序
MOV KEY_2X4,#00111110B ;初始化第2行第1列鍵
JB KEY_2X4.5,K22 ;掃描第2行鍵盤,如無按下程序跳至K22段
MOV R4,#8 ;定此鍵為8,R4值為8,為DP及清除鍵
ACALL DELAY500MS ;呼叫延時去抖動
JB KEY_2X4.5,K22 ;判斷此鍵是否持續按下
ACALL T0_2S ;呼叫定時器
AJMP KEND ;中斷掃描程序跳至KEND段,返回MAIN主程序
K22: ;K22子程序
MOV KEY_2X4,#00111101B ;初始化第2行第2列鍵
JB KEY_2X4.5,K23 ;掃描第2行鍵盤,如無按下程序跳至K23段
MOV R4,#3 ;定此鍵為3,R4值為3
ACALL DELAY500MS ;呼叫延時去抖動
AJMP KEND ;中斷掃描程序跳至KEND段,返回MAIN主程序
K23: ;K23子程序
MOV KEY_2X4,#00111011B ;初始化第2行第3列鍵
JB KEY_2X4.5,K24 ;掃描第2行鍵盤,如無按下程序跳至K24段
MOV R4,#7 ;定此鍵為7,R4值為7
ACALL DELAY500MS ;呼叫延時去抖動
AJMP KEND ;中斷掃描程序跳至KEND段,返回MAIN主程序
K24: ;K24子程序
MOV KEY_2X4,#00110111B ;初始化第2行第4列鍵
JB KEY_2X4.5,KEND ;掃描第2行鍵,如無按下程序跳至KEND,返回MAIN主程序,第2行掃描結束
MOV R4,#2 ;定此鍵為2,R4值為2
ACALL DELAY500MS ;呼叫延時去抖動
AJMP KEND ;中斷掃描程序跳至KEND段,返回MAIN主程序
KEND: ;KEND子程序(矩陣鍵盤掃描結束)
RET ;結束鍵盤掃描,返回MAIN主程序
T0_2S: ;TIMER0_2秒計時子程序
MOV R5,#200 ;定R5為200次計時
MOV TMOD,#011H ;定TIMER0模式為1
MOV TH0,#0D8H ;初始化TH0值為D8,為10MS@12MHZ
MOV TL0,#0F0H ;知始化TL0值為F0,為10MS@12MHZ
SETB TR0 ;啟動TIMER0
CJNE R4,#8,LOOP_DEMO ;判斷是否為清除功能,若否則跳至LOOP_DEMO段
LOOP_CLEAR: ;TIMER0_10MS循環計時(清除拼盤顯示功能)
JB KEY_2X4.5,KEND ;掃描第2行,如無按下程序跳至KEND,返回MAIN主程序
JNB TF0,LOOP_CLEAR ;判斷TF0是否溢位,如否重新判斷
ACALL T0_RELOAD ;如TF0溢位時,呼叫T0_RELOAD子程序,重新計時10MS
DJNZ R5,LOOP_CLEAR ;遞減R5值循環
MOV LED_ALL,#0FFH ;清除七段顯示
MOV R4,#000H ;初始化鍵盤暫存器R4
ACALL DELAY500MS ;呼叫延時去抖動
ACALL DELAY500MS ;呼叫延時防誤顯示
RET ;返回K21段
LOOP_DEMO: ;TIMER0_10MS循環計時(切換模式功能)
JB KEY_2X4.4,KEND ;掃描第1行,如無按下程序跳至KEND,返回MAIN主程序
JNB TF0,LOOP_DEMO ;判斷TF0是否溢位,如否重新判斷
ACALL T0_RELOAD ;如TF0溢位時,呼叫T0_RELOAD子程序,重新計時10MS
DJNZ R5,LOOP_DEMO ;遞減R5值循環
MOV LED_ALL,#0FFH ;清除七段顯示
CPL MODE.0 ;MODE取反
RET ;返回K11段
T0_RELOAD: ;TIMER0_10MS計時子程序(10MS循環)
CLR TR0 ;停止TIMER0
MOV TH0,#0D8H ;初始化TH0值為D8,為10MS@12MHZ
MOV TL0,#0F0H ;初始化TL0值為F0,為10MS@12MHZ
CLR TF0 ;清除TF0溢位符號
SETB TR0 ;啟動TIMER0
RET ;返回LOOP段
;延時500MS@12.000MHz程序,感謝使用STC計算器得出
DELAY500MS: ;@12.000MHz
PUSH 30H
PUSH 31H
PUSH 32H
MOV 30H,#19
MOV 31H,#62
MOV 32H,#39
NEXT:
DJNZ 32H,NEXT
DJNZ 31H,NEXT
DJNZ 30H,NEXT
POP 32H
POP 31H
POP 30H
RET
TABLE:
;定義數字表: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
DB 048H,07EH,0C4H,054H,072H,051H,041H,07CH,040H,050H
END
數字學習機_20121106_V1.21_15F204EA.ASM.zip
(2.89 KB, 下載次數: 41)
|
|