1. 有時會出現程序一點錯誤也沒有,但就是不能正常運行的現象,最后我們發行是因為程序中有的指令書寫得不規范導致的,例如有的 RET 返回指令一定要按正確格式書寫或在兩 行指令間最好不要留空行。
2. 程序中的跳轉指令的運用很重要,為保險起見,都用 LJMP,我們就遇到過跳轉指令用錯 程序無法正常運行的現象。當用 JNZ 指令時,跳轉范圍比較少,這時要用一個標號中轉。
3. 編程時要注意,在程序開始時,要寫入各定時器中斷的入口地址。
4. 編程過程中要注意加注釋或分割線,否則,在程序過長時容易變得很亂,不便于查找或更改。
5. 程序的結構要設計的合理,避免上下亂調用的現象,這樣會使程序更加清晰化。
6. 編程前要加流程圖, 這樣會使思路清晰, 例如數字音樂盒的設計思路完全可以按著 MP3 的工作方式列寫流程圖。
7. LCD 計時正常顯示的解決辦法:
a. 兩個定時器同時工作,存在中斷時序問題,剛開始時我們把定時器 1 設定在方式 3,計 250us,由于定時中斷過于頻繁,使 CPU 負載過大,導致音樂不能正常播放,時間不能正常 顯示。解決辦法:將定時器 1 設定在工作方式 1,16 位計數,計 50ms,效果有很大改觀。但還有問題。
b. 當音樂為全 4 拍起始時,此時音樂節奏與定時器 T1 中斷頻率錯開,LCD 顯示和音樂播 放都會好一些。
c. 另外,在歌曲中,當遇到一個音符發音為 4 拍,在編曲中為*CH,托因時間較長,當定 時器 T1 此時來中斷時,就會對歌曲播放產生影響,若改為發音一拍,中斷對歌曲播放影響 減弱,但音樂效果變差。
d. 改進方案:若采用可以定時時間更長的單片機,可以避免所有問題。
0.png (30.18 KB, 下載次數: 102)
下載附件
2017-4-22 15:28 上傳
單片機源程序(匯編語言):
- RS BIT P2.0 ;引腳定義,定義液晶顯示端口標號
- RW BIT P2.1
- E BIT P2.2
- L50MS EQU 60H ;工作內存定義
- L1MS EQU 61H
- L250MS EQU 62H
- SEC EQU 65H
- MIN EQU 64H
- HOU EQU 63H
- ORG 0000H
- LJMP MAIN
- ORG 000BH ;定時器T0溢出中斷入口地址
- LJMP TT0
- ORG 001BH ; 定時器T1溢出中斷入口地址
- LJMP T1INT
- ORG 1000H
- MAIN: ;液晶初始化
- MOV SP,#70H
- MOV P0,#01H ;清屏
- CALL DISPLAY
- MOV P0,#38H ;8位,2行顯示
- LCALL DISPLAY
- MOV P0,#0FH ;屏顯on,光標on,閃爍on
- LCALL DISPLAY
- MOV P0,#06H ;計數地址加1,顯示幕on
- LCALL DISPLAY
- LCALL INITIL ;內存初始化
- WAIT: LCALL KEY ;鍵盤掃描,是否有鍵按下,否則等待
- LCALL MODD
- LJMP WAIT
- KEY: NOP
- NOP
- LCALL KS
- JNZ K1 ;有按鍵轉到K1
- LCALL KAIJI
- LCALL SOP
- XN: LJMP KEY
- K1: LCALL MODD
- LCALL MODD
- LCALL KS
- JNZ K2
- LJMP KEY
- K2: MOV R2,#0FEH ;讀鍵盤
- MOV R4,#00H
- K3: MOV A,R2
- MOV P1,A
- MOV A,P1
- JB ACC.4,L1 ;為1跳轉,第一行無按鍵
- MOV A,#00H
- LJMP LK
- L1: JB ACC.5,L2
- MOV A,#04H
- LJMP LK
- L2: JB ACC.6,L3
- MOV A,#08H
- LJMP LK
- L3: JB ACC.7,NEXT1
- MOV A,#0CH
- LK: ADD A,R4
- PUSH ACC
- K4: LCALL DELAY1 ;若同時有其他按鍵,則等待
- LCALL KS
- JNZ K4
- MOV R3,#07H
- CLR A
- MOV R0,#30H
- MOV R1,#31H
- MM1: MOV A,@R1
- MOV @R0,A
- INC R0
- INC R1
- DJNZ R3,MM1
- POP ACC
- MOV @R0,A
- RET
- NEXT1: INC R4 ;列掃描
- MOV A,R2
- JNB ACC.3,N2
- LJMP N1
- N2: LJMP KEY
- N1: RL A
- MOV R2,A
- LJMP K3
- KS: MOV A,#0F0H ;判斷P1口
- MOV P1,A
- NOP
- NOP
- MOV A,P1
- CPL A
- ANL A,#0F0H
- RET
- DELAY1:SETB RS0
- DL: MOV R5,#0AH
- DL2: MOV R6,#63
- DL3: NOP
- NOP
- DJNZ R6,DL3
- DJNZ R5,DL2
- CLR RS0
- RET
- INITIL: ;30H-37H初值為零
- MOV R3,#08H
- MOV R0,#30H
- M1: MOV @R0,#00H
- INC R0
- DJNZ R3,M1
- RET
- MODD: ;顯示
- MOV P0,#8EH
- CALL DISPLAY
- MOV A,37H
- MOV DPTR,#TABLE3
- MOVC A,@A+DPTR
- CALL WRITE2
- RET
- KAIJI: MOV A,37H ;開機提示字
- CJNE A,#0FH,DFF
- MOV P0,#80H ;設光標地址
- CALL DISPLAY
- MOV DPTR,#TABLE1;寫數據
- CALL WRITE1
- DFF: RET
- ;按鍵值播放歌曲
- SOP: MOV A,37H
- CJNE A,#01H,A11
- LCALL MODD
- MOV 52H,#HIGH TABLE10
- MOV 53H,#LOW TABLE10
- LCALL INITILE2
- LCALL MAIN0
- A11: CJNE A,#02H,A22
- LCALL MODD
- MOV 52H,#HIGH TABLE20
- MOV 53H,#LOW TABLE20
- LCALL INITILE2
- lcall MAIN0
- A22: CJNE A,#03H,A33
- LCALL MODD
- MOV 52H,#HIGH TABLE30
- MOV 53H,#LOW TABLE30
- LCALL INITILE2
- lcall MAIN0
- A33: CJNE A,#04H,A44
- LCALL MODD
- MOV 52H,#HIGH TABLE40
- MOV 53H,#LOW TABLE40
- LCALL INITILE2
- lcall MAIN0
- A44: CJNE A,#05H,A55
- LCALL MODD
- MOV 52H,#HIGH TABLE50
- MOV 53H,#LOW TABLE50
- LCALL INITILE2
- lcall MAIN0
- A55: CJNE A,#06H,A66
- LCALL MODD
- MOV 52H,#HIGH TABLE60
- MOV 53H,#LOW TABLE60
- LCALL INITILE2
- lcall MAIN0
- A66: CJNE A,#07H,A77
- LCALL MODD
- MOV 52H,#HIGH TABLE70
- MOV 53H,#LOW TABLE70
- LCALL INITILE2
- lcall MAIN0
- A77: CJNE A,#08H,A88
- LCALL MODD
- MOV 52H,#HIGH TABLE80
- MOV 53H,#LOW TABLE80
- LCALL INITILE2
- lcall MAIN0
- A88: CJNE A,#09H,A99
- LCALL MODD
- MOV 52H,#HIGH TABLE90
- MOV 53H,#LOW TABLE90
- LCALL INITILE2
- lcall MAIN0
- A99: CJNE A,#0AH,AAA
- LCALL MODD
- MOV 52H,#HIGH TABLE100
- MOV 53H,#LOW TABLE100
- LCALL INITILE2
- lcall MAIN0
- AAA: RET
- INITILE2:
- MOV L50MS,#20
- MOV L1MS,#00H
- MOV L250MS,#00H
- MOV SEC,#00H
- MOV MIN,#00H
- MOV HOU,#00H
- MOV A,HOU
- MOV B,#10
- DIV AB
- ADD A,#30H ;將BCD嗎轉化為ASIIC碼
- MOV P0,#0C8H ;顯示小時十位
- CALL DISPLAY
- CALL WRITE2
- MOV A,B
- ADD A,#30H
- MOV P0,#0C9H ;顯示小時個位
- CALL DISPLAY
- CALL WRITE2
- MOV A,#3AH
- MOV P0,#0DH ;顯示冒號
- CALL DISPLAY
- CALL WRITE2
- MOV A,MIN
- MOV B,#10
- DIV AB
- ADD A,#30H
- MOV P0,#0CBH ;顯示分十位
- CALL DISPLAY
- CALL WRITE2
- MOV A,B
- ADD A,#30H
- MOV P0,#0CCH ;顯示分個位
- CALL DISPLAY
- CALL WRITE2
- MOV A,#3AH
- MOV P0,#0CDH ;顯示冒號
- CALL DISPLAY
- CALL WRITE2
- MOV A,SEC
- MOV B,#10
- DIV AB
- ADD A,#30H
- MOV P0,#0CEH ;顯示秒十位
- CALL DISPLAY
- CALL WRITE2
- MOV A,B
- ADD A,#30H
- MOV P0,#0CFH ;顯示秒個位
- CALL DISPLAY
- CALL WRITE2
- MOV P0,#0C0H ;設光標地址
- CALL DISPLAY
- MOV DPTR,#TABLE2;寫數據
- CALL WRITE1
- RET
- DISPLAY: CLR RS ;寫指令
- CLR RW
- CLR E
- LCALL DELAY
- SETB E
- RET
- WRITE1: MOV R1,#00H ;寫數據
- A1: MOV A,R1
- MOVC A,@A+DPTR
- CALL WRITE2
- INC R1
- CJNE A,#0FEH,A1 ;未到字符串末尾繼續
- RET
- WRITE2: MOV P0,A
- SETB RS
- CLR RW
- CLR E
- CALL DELAY
- SETB E
- RET
- DELAY: MOV R4,#05
- D1: MOV R5,#0FFH
- DJNZ R5,$
- DJNZ R4,D1
- RET
- TAB: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H
- DB 80H,90H,88H,83H,0C6H,0A1H,86H,8EH
- TAB1: DB 89H,86H,0C7H,0C7H,0C0H
- TAB2: DB 0C6H,88H,0C0H
- TABLE1: DB 'WELCOM HERE',0FEH
- TABLE2: DB 'DFF WB ',0FEH
- TABLE4: DB 'CAU',0FEH
- TABLE3: DB 30H,31H,32H,33h
- DB 34H,35H,36H,37H
- DB 38h,39H,41H,42H
- DB 43H,44H,45H,46H
- MAIN0: MOV TMOD,#11H ;播放歌曲程序
- MOV IE,#8aH
- MOV TH1, #3cH
- MOV TL1, #0b0H
- LCALL KS
- JNZ TTM12
- MOV 40H,#00H
- NEXT20: MOV A,40H
- MOV DPH,52H
- MOV DPL,53H
- MOVC A,@A+DPTR
- MOV R2,A
- JZ STOP
- ANL A,#0FH
- MOV R1,A
- MOV A,R2
- SWAP A
- ANL A,#0FH
- JNZ SING
- CLR TR0
- JMP W1
- SING: DEC A
- MOV 22H,A
- RL A
- MOV DPTR,#TABLE00
- MOVC A,@A+DPTR
- MOV TH0,A
- MOV 21H,A
- MOV A,22H
- RL A
- INC A
- MOVC A,@A+DPTR
- MOV TL0,A
- MOV 20H,A
- SETB TR0
- SETB TR1
- W1: LCALL DELAY30
- INC 40H
- LCALL KS ;有鍵跳出
- JNZ STOP
- LJMP NEXT20
- STOP: CLR TR0
- CLR TR1
- LJMP MAIN0
- TTM12: LCALL K2
- MOV A,37H
- CJNE A,#0EH,TTM13
- CLR TR1
- LCALL DELAY1
- TTM120: LCALL KS
- LCALL DELAY1
- JZ TTM120
- LCALL K2
- MOV A,37H
- CJNE A,#0EH,TTM120
- SETB TR1
- LJMP NEXT20
- TTM13: CJNE A,#0CH,TTM14
- MOV A,52H
- INC A
- MOV 52H,A
- MOV A,53H
- INC A
- MOV 53H,A
- MOV A,36H
- INC A
- MOV 37H,A
- LJMP TTM2
- TTM14: CJNE A,#0DH,TTM2
- MOV A,52H
- DEC A
- MOV 52H,A
- MOV A,53H
- DEC A
- MOV 53H,A
- MOV A,36H
- DEC A
- MOV 37H,A
- TTM2: RET
- TT0: PUSH ACC ;定時器中斷子程序0
- PUSH PSW
- MOV TL0,20H
- MOV TH0,21H
- CPL P3.7
- POP PSW
- POP ACC
- RETI
- ;定時器中斷子程序1
- T1INT: MOV TH1, #3CH ;定時器中斷子程序1
- MOV TL1, #0B0H
- DJNZ L50MS,X4
- MOV L50MS,#20
- SECSET: ;每秒種時鐘刷新秒顯示一次
- MOV A,SEC
- MOV B,#10
- DIV AB
- ADD A,#30H
- MOV P0,#0CEH ;顯示秒十位
- CALL DISPLAY
- CALL WRITE2
- MOV A,B
- ADD A,#30H
- MOV P0,#0CFH ;顯示秒個位
- CALL DISPLAY
- CALL WRITE2
- MOV A,SEC
- INC A
- MOV SEC,A
- XRL A,#60
- X4: JNZ OUT
- MINSET: MOV SEC,#00H ; *每分鐘刷新分顯示一次
- MOV A,MIN
- INC A
- MOV MIN,A
- MOV B,#10
- DIV AB
- ADD A,#30H
- MOV P0,#0CBH ;顯示分十位
- CALL DISPLAY
- CALL WRITE2
- MOV A,B
- ADD A,#30H
- MOV P0,#0CCH ;顯示分個位
- CALL DISPLAY
- CALL WRITE2
- MOV A,MIN
- MOV B,#3
- MUL AB
- MOV B,#100
- DIV AB
- MOV R2,A
- MOV A,#10
- XCH A,B
- DIV AB
- MOV A,MIN
- XRL A,#60
- JNZ OUT
- HOUSET:
- MOV MIN,#00H ;每小時刷新小時顯示一次
- MOV A,HOU
- MOV B,#10
- DIV AB
- ADD A,#30H ;將BCD嗎轉化為ASIIC碼
- MOV P0,#0C8H ;顯示小時十位
- CALL DISPLAY
- CALL WRITE2
- MOV A,B
- ADD A,#30H
- MOV P0,#0C9H ;顯示小時個位
- CALL DISPLAY
- CALL WRITE2
- MOV A,HOU
- INC A
- MOV HOU,A
- XRL A,#10
- JNZ OUT
- SJMP OVERFLOW
- OUT: RETI;溢出處理
- OVERFLOW:
- MOV L50MS,#20
- MOV L1MS,#00H
- MOV L250MS,#00H
- MOV SEC,#00H
- MOV MIN,#00H
- MOV HOU,#00H
- RETI
- DELAY30:
- MOV R7,#2
- W2: MOV R4,#125
- W3: MOV R3,#248
- DJNZ R3,$
- DJNZ R4,W3
- DJNZ R7,W2
- DJNZ R1,DELAY30
- RET
- TABLE00:
- DW 64580,64684,64777,64820
- DW 64898,64968,65030,64260
- DW 64400,64524,65058,63835,64021
- TABLE10: ;第一首《精忠報國》
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
0.png (63.66 KB, 下載次數: 116)
下載附件
2017-4-22 15:28 上傳
資料下載:
音樂盒.zip
(62.11 KB, 下載次數: 99)
2017-4-22 10:24 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|