痞酷網_PIGOO

 找回密碼
 立即註冊
!!! [系統偵測到廣告阻擋軟體] !!!

如果您覺得痞酷網對您有些許幫助,或者您認同痞酷網的理想,

那麼希望您將痞酷網設定為白名單.

並請在上論壇的時候,動動您的手指,用行動支持我們.

謝謝!
查看: 3587|回復: 8

給小朋友玩的數字學習機玩具基本版!

[複製鏈接]
發表於 2012-11-10 13:45:58 | 顯示全部樓層 |閱讀模式
本帖最後由 fatzeros 於 2012-11-12 08:01 PM 編輯

一切的發想都是從這個東東來的:A01這個

話說前一陣子回了草屯老家一趟,順便到了傳說中的一元積木去看看,
除了一堆好玩的積木外,還有成品 ,就是這個A01,我一看到,就想到要使用單片機來作了。

寫了一個月的組語,作了一個星期的電路,總算是作出了第一個基本版,
程式裡包含了七段顯示器的輸出,二行四列的矩陣鍵盤輸入,單片機定時器的使用,三大初學者必學的程序。

作了一個星期的電路,主要是因為矩陣鍵盤的電路,我作錯了!哈哈哈!
電路裡包含,七段顯示器,限流電阻,二行四列矩陣鍵盤,9V電池輸入,7805降壓輸出。

看圖片啦:
DSC_0054_1.jpg
DSC_0055_1.jpg
請無視裡面的1N4148,接了這個就不能用了!想問一下為什麼,要改用ZENER嗎?還是我那裡搞錯了!?

電路原理圖:
電路原理圖_20121110.PNG

程式為組合語言,電路圖使用PAD2PAD畫製,
程式及原理圖下載:
數字學習機_20121110.zip (36.35 KB, 下載次數: 55)

下一板要加入蜂嗚器,來個按對組合就唱歌的功能,再來加入數字展示和PWM調亮度的功能,
我覺得這個東東可以拿來當成單片機的實驗板來玩的啦!真的是小朋友開心,大人也開心!

謝謝大家收看!

程序:

;/*----------------------------------------------------------------------------------------------
;  名稱:小朋友的數字學習機
;  編寫:沈大胖
;  日期:2012/11/10_V1.1
;  修改:修正相關按鍵位置
;  內容:使用七段顯示器,及八個按鍵,讓小朋友學習認識數字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

;設定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 65H開始
                MOV                R4,#000H                ;R4清零
                AJMP        MAIN                                ;程序JUMP至MAIN段

                ORG                0010H
MAIN:                                                        ;主程序
                ACALL                KEY                        ;呼叫鍵盤掃描程序
                AJMP                LEDA_ON                ;取得鍵盤值後,程序跳至LEDA_ON段

LEDA_ON:                                                ;LEDA_ON子程序
                CJNE        R4,#1,LEDB_ON        ;若R4不為1則跳至LEDB_ON
                JNB                LEDA,LEDA_OFF        ;若LEDA為0則跳至LEDA_OFF
                CLR                LEDA                        ;接通LEDA
                MOV                R4,#000H                ;R4清零
                AJMP        LED_END                        ;程序跳回MAIN

LEDA_OFF:                                                ;LEDA_OFF子程序
                SETB        LEDA                        ;斷開LEDA
                MOV                R4,#000H                ;R4清零
                AJMP        LED_END                        ;程序跳回MAIN

LEDB_ON:                                                ;LEDB_ON子程序
                CJNE        R4,#2,LEDC_ON        ;若R4不為1則跳至LEDB_ON
                JNB                LEDB,LEDB_OFF        ;若LEDB為0則跳至LEDB_OFF
                CLR                LEDB                        ;接通LEDB
                MOV                R4,#000H                ;R4清零
                AJMP        LED_END                        ;程序跳回MAIN

LEDB_OFF:                                                ;LEDB_OFF子程序
                SETB        LEDB                        ;斷開LEDB
                MOV                R4,#000H                ;R4清零
                AJMP        LED_END                        ;程序跳回MAIN

LEDC_ON:                                                ;LEDC_ON子程序
                CJNE        R4,#3,LEDD_ON        ;若R4不為1則跳至LEDC_ON
                JNB                LEDC,LEDC_OFF        ;若LEDC為0則跳至LEDC_OFF
                CLR                LEDC                        ;接通LEDC
                MOV                R4,#000H                ;R4清零
                AJMP        LED_END                        ;程序跳回MAIN

LEDC_OFF:                                                ;LEDC_OFF子程序
                SETB        LEDC                        ;斷開LEDC
                MOV                R4,#000H                ;R4清零
                AJMP        LED_END                        ;程序跳回MAIN

LEDD_ON:                                                ;LEDD_ON子程序
                CJNE        R4,#4,LEDE_ON        ;若R4不為1則跳至LEDD_ON
                JNB                LEDD,LEDD_OFF        ;若LEDD為0則跳至LEDD_OFF
                CLR                LEDD                        ;接通LEDD
                MOV                R4,#000H                ;R4清零
                AJMP        LED_END                        ;程序跳回MAIN

LEDD_OFF:                                                ;LEDD_OFF子程序
                SETB        LEDD                        ;斷開LEDD
                MOV                R4,#000H                ;R4清零
                AJMP        LED_END                        ;程序跳回MAIN

LEDE_ON:                                                ;LEDE_ON子程序
                CJNE        R4,#5,LEDF_ON        ;若R4不為1則跳至LEDE_ON
                JNB                LEDE,LEDE_OFF        ;若LEDE為0則跳至LEDE_OFF
                CLR                LEDE                        ;接通LEDE
                MOV                R4,#000H                ;R4清零
                AJMP        LED_END                        ;程序跳回MAIN

LEDE_OFF:                                                ;LEDE_OFF子程序
                SETB        LEDE                        ;斷開LEDE
                MOV                R4,#000H                ;R4清零
                AJMP        LED_END                        ;程序跳回MAIN

LEDF_ON:                                                ;LEDF_ON子程序
                CJNE        R4,#6,LEDG_ON        ;若R4不為1則跳至LEDF_ON
                JNB                LEDF,LEDF_OFF        ;若LEDF為0則跳至LEDF_OFF
                CLR                LEDF                        ;接通LEDF
                MOV                R4,#000H                ;R4清零
                AJMP        LED_END                        ;程序跳回MAIN

LEDF_OFF:                                                ;LEDF_OFF子程序
                SETB        LEDF                        ;斷開LEDF
                MOV                R4,#000H                ;R4清零
                AJMP        LED_END                        ;程序跳回MAIN

LEDG_ON:                                                ;LEDG_ON子程序
                CJNE        R4,#7,LEDH_ON        ;若R4不為1則跳至LEDG_ON
                JNB                LEDG,LEDG_OFF        ;若LEDG為0則跳至LEDG_OFF
                CLR                LEDG                        ;接通LEDG
                MOV                R4,#000H                ;R4清零
                AJMP        LED_END                        ;程序跳回MAIN

LEDG_OFF:                                                ;LEDG_OFF子程序
                SETB        LEDG                        ;斷開LEDG
                MOV                R4,#000H                ;R4清零
                AJMP        LED_END                        ;程序跳回MAIN

LEDH_ON:                                                ;LEDH_ON子程序
                CJNE        R4,#8,LED_END        ;若R4不為1則跳至MAIN
                JNB                LEDH,LEDH_OFF        ;若LEDH為0則跳至LEDH_OFF
                CLR                LEDH                        ;接通LEDH
                MOV                R4,#000H                ;R4清零
                AJMP        LED_END                        ;程序跳回MAIN

LEDH_OFF:                                                ;LEDH_OFF子程序
                SETB        LEDH                        ;斷開LEDH
                MOV                R4,#000H                ;R4清零
                AJMP        LED_END                        ;程序跳回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子程序
                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                        ;定此鍵為1,R4值為1
                ACALL                DELAY500MS                ;呼叫延時去抖動
                AJMP                KEND                        ;中斷掃描程序跳至KEND段,返回MAIN主程序

K12:                                                        ;K12子程序
                MOV                KEY_2X4,#00111101B        ;初始化第1行第2列鍵
                JB                KEY_2X4.4,K13                ;掃描第1行鍵盤,如無按下程序跳至K13段
                MOV                R4,#5                        ;定此鍵為2,R4值為2
                ACALL                DELAY500MS                ;呼叫延時程序去抖動
                AJMP                KEND                        ;中斷掃描程序跳至KEND段,返回MAIN主程序

K13:                                                        ;K13子程序
                MOV                KEY_2X4,#00111011B        ;初始化第1行第3列鍵
                JB                KEY_2X4.4,K14                ;掃描第1行鍵盤,如無按下程序跳至K14段
                MOV                R4,#6                        ;定此鍵為3,R4值為3
                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                        ;定此鍵為4,R4值為4
                ACALL                DELAY500MS                ;呼叫延時程序去抖動
                AJMP                KEND                        ;中斷掃描程序跳至KEND段,返回MAIN主程序

K20:                                                        ;K20子程序
                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                        ;定此鍵為5,R4值為5
                ACALL                DELAY500MS                ;呼叫延時程序去抖動
                ACALL                T0_2S                        ;呼叫TIMER0計時程序,計時約3秒後,使LED全不亮
                AJMP                KEND                        ;中斷掃描程序跳至KEND段,返回MAIN主程序

K22:                                                        ;K22子程序
                MOV                KEY_2X4,#00111101B        ;初始化第2行第2列鍵
                JB                KEY_2X4.5,K23                ;掃描第2行鍵盤,如無按下程序跳至K23段
                MOV                R4,#3                        ;定此鍵為6,R4值為6
                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主程序
                MOV                R4,#2                        ;定此鍵為8,R4值為8
                ACALL                DELAY500MS                ;呼叫延時程序去抖動
                AJMP                KEND                        ;中斷掃描程序跳至KEND段,返回MAIN主程序

KEND:                                                        ;KEND子程序
                RET                                        ;結束鍵盤掃描,返回MAIN主程序

T0_2S:                                                        ;TIMER0_2秒計時子程序,清除LED子程序
                JB                KEY_2X4.5,KEND                ;掃描第8鍵,如無按下程序跳至KEND,返回MAIN主程序
                MOV                R5,#250                        ;定R5為250次計時
                MOV                TMOD,#011H                ;定TIMER0模式為1
                MOV                TH0,#0D8H                ;初始化TH0值為D8,為10MS@12MHZ
                MOV                TL0,#0F0H                ;知始化TL0值為F0,為10MS@12MHZ
                SETB                TR0                        ;啟動TIMER0

LOOP_T0:                                                        ;TIMER0_10MS循環計時
                JB                KEY_2X4.5,KEND                ;掃描第8鍵,如無按下程序跳至KEND,返回MAIN主程序
                JNB                TF0,LOOP_T0                ;判斷TF0是否溢位,如否重新判斷
                ACALL                T0_RELOAD                ;如TF0溢位時,呼叫T0_RELOAD子程序,重新計時10MS
                DJNZ                R5,LOOP_T0                ;遞減R5值循環
                MOV                LED_ALL,#0FFH                ;設定七段為不亮,11111111B
                ACALL                DELAY500MS                ;呼叫延時程序
                ACALL                DELAY500MS                ;防止誤亮LEDH
                MOV                R4,#000H                        ;R4清零
                RET                                        ;返回K24段

T0_RELOAD:                                                ;TIMER0_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_T0段

;延時250MS@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

END

評分

4

查看全部評分

發表於 2012-11-10 23:28:48 | 顯示全部樓層
加了1n4148為什麼不能動作,不過看了圖片1n4148位罝來看是不是接反了
加這棵應該是打算要作反接電壓的保護用的吧,不然應該不會這樣的
動手作作玩具是有趣的
 樓主| 發表於 2012-11-11 20:29:13 | 顯示全部樓層
本來我也覺得是我接錯了,
但是,正接反接後,換了一顆後,我量了量,還是不行,電路繞過1n4148就ok,
是想請問,在電路上,加上1n4148在7805前應該是不影響整體運作才是吧?
加上1n4148的想法是一方面降壓,一方面怕電源反接!
發表於 2012-11-11 22:32:45 | 顯示全部樓層
本帖最後由 legion 於 2012-11-11 10:33 PM 編輯

基本上加棵二極體大都是為了怕不小心接反電壓
不過大約降個0.6v就會不動作的話
應是輸入電壓不足,經過二極體後剩下給7805的電壓不足
7805的輸入電壓記得壓差大約要多個2.5v以上,
測試的方式就是用電源供應器直接輸入就會知道
或加上二極體後量一量進入7805的電壓就知道問題在那了
5v+0.6v+2.5v=8.1v,至少進7805的輸入端要在這個以上吧
 樓主| 發表於 2012-11-12 15:49:18 | 顯示全部樓層
legion 發表於 2012-11-11 10:32 PM static/image/common/back.gif
基本上加棵二極體大都是為了怕不小心接反電壓
不過大約降個0.6v就會不動作的話
應是輸入電壓不足,經過二極 ...

看來應該就是這個問題了,
因為我有量過電壓,
9v電池過1n4148後,就只剩下8.4v了,
所以7805有可能不作動!
謝謝legion兄!
發表於 2012-11-12 17:44:14 | 顯示全部樓層
請問單晶片那個藍色IC座一個多少錢?好用嗎?

 樓主| 發表於 2012-11-12 18:18:23 | 顯示全部樓層
這個是某工作室結束後,在露拍上拍來的,
當時零零總總買了一千元,把他手上的所有IC座都清了,
一個要算多少,我也不知道要怎麼算!
好像是某日本連接器廠作的,名字我也忘了,
IC插上去相當的緊啊!
要拔還不太簡單,要花一點力氣呢!
不知道這樣是好還是不好!
針腳放了一點時間還是亮晶晶的,
我個人覺得是還不錯的啦!
發表於 2012-11-17 12:50:27 | 顯示全部樓層
程式有點多。感覺有規則性,有規則性的東西就應該很好簡化才對。
不過當練功真的很不錯。有練有保庇!!
 樓主| 發表於 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)
您需要登錄後才可以回帖 登錄 | 立即註冊

本版積分規則

關閉

站長小叮嚀上一條 /1 下一條

禁閉室|手機版|連繫我們|痞酷網電子技術論壇

GMT+8, 2024-5-4 04:08 PM , Processed in 0.072793 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.4 Licensed

© 2001-2023 Discuz! Team.