![]() |
發布時間: 2018-12-14 23:38
正文摘要:剛學單片機,首先接觸的是匯編,感覺比較直接,C有些拐彎抹角,呵呵,所以就學匯編了。實習編什么好呢?忽然想起之前買有一個電控錄音機芯,就拿它來練習好了。畫好線路圖并做好了PCB(花費了100大洋,唔唔),用匯編 ... |
好厲害,都沒寫過這么長的匯編。 |
雙卡錄放機,組合音響等都落寞了。拿來練練手還是不錯的 |
你好,還有沒有搞單片機控制錄音機芯,想跟你學習學習。 |
終于弄明白了,是因為這里使用的是LCALL指令但指令出去后的子程序都沒有RET返回所以就跑飛了 LCALL DISP ;調用顯示及功能操作 LJMP L1 ;返回做下一次掃描 ....... DISP: MOV DPTR, #TABKEY ;讀功能操作數據 MOV A,R1 MOV B,#3 MUL AB JMP @A+DPTR ;轉執行具體功能操作 |
比如你在死等硬件某個信號,程序的這種寫法是有風險的,一但硬件有問題(你等不到),就死在那里了。 你也可以走全速仿真,在你認為“已死機”的時候,斷下來,看看這時的PC指針指向何處,再對照你的程序地址,以找到死在何處?或是飛出程序之外了。 |
yzwzfyz 發表于 2018-12-15 12:29 謝謝。復雜程序或許C比較好應付,我剛學匯編個把月。感覺指向明確,當然在有注釋的情況下還是好理解的。今后是要養成畫流程圖的習慣。不過,《超時跳出》,我都是設定跳回矩陣鍵盤檢測那去的呀,因為感覺所有控制都是根據矩陣鍵盤的鍵值進行操作的。比如說按下播放鍵執行完畢程序就回到矩陣鍵盤檢測去了。還是會死機。特別是反復的按前進,后退,播放最容易死機,1602屏是一片亂碼。怎么回事呢?真的搞不懂 |
不錯!汝子可教也! 畫出程序架構的邏輯框圖?纯纯驁D中有沒有死循環結構。設法拆開它(超時跳出)。 這個程序還不復雜,如果再復雜幾十倍,當如何處理呢? 所以必須學會畫程序流程圖,并以流程圖審核程序。 |
抱歉,第一次發帖,有重復了,煩請版主幫忙把我發的后面幾個貼刪除了吧。謝謝 |
我現在用的是廣電網絡,龜速。沒辦法 |
匯編程序: ORG 0040H CLR EA ;關閉所有中斷 ;----------------定義1602顯示屏端口----------- RS EQU P3.0 ;數據/命令選擇 RW EQU P3.1 ;讀/寫選擇 E EQU P3.2 ;使能控制 COUNT EQU 30H ;字數計數 DISPAD EQU 31H ;顯示起始地址 ;---------------定義機芯控制端口-------------- AHD EQU P1.0 ; A帶倉檢測口 LYJ EQU P1.1 ; 錄音使能檢測 BHD EQU P1.2 ; B帶倉檢測口 BMC EQU P1.3 ; B倉脈沖檢測 AMC EQU P1.4 ; A倉脈沖檢測 BCT EQU P1.5 ; B倉機芯動作控制 MDZ EQU P1.6 ; 馬達控制 ACT EQU P1.7 ; A倉機芯動作控制 AKEY DATA 32H ;保存A倉鍵值 BKEY DATA 33H ;保存B倉鍵值 ;---------------1602顯示初始化------------ MOV P0,#01H ;清屏并光標復位 ACALL ENABLE ;調用寫入命令子程序 MOV P0,#38H ;設置顯示模式:8位2行5x7點陣 ACALL ENABLE ;調用寫入命令子程序 MOV P0,#0CH ;顯示器開、光標關、光標不閃爍 ACALL ENABLE ;調用寫入命令子程序 MOV P0,#06H ;文字不動,光標自動右移 ACALL ENABLE ;調用寫入命令子程序 LJMP START ;--------------- 數據寫入---------------- QUSHU: CLR A MOVC A,@A+DPTR ;查表 MOV P0,A SETB RS ;RS=1 CLR RW ;RW=0 ;準備寫入數據 CLR E ;E=0 ;執行顯示命令 LCALL DELAY ;判斷液晶模塊是否忙? INC DPTR DJNZ COUNT,QUSHU RET ;--------------- 命令寫入---------------- ENABLE: CLR RS CLR RW CLR E LCALL DELAY SETB E RET ;--------------- 判斷忙---------------- DELAY: MOV P0,#0FFH CLR RS SETB RW CLR E NOP SETB E JB P0.7,DELAY ;P1.7為高電平表示忙循環等待 RET ;------------- 開始程序 ---------------- START: MOV P0,#080H ;第1行第1位 LCALL ENABLE ;調用寫入命令子程序 MOV DPTR,#TAB0 ;顯示 A: B: MOV COUNT,#0AH ;顯示10個字符。 LCALL QUSHU MOV AKEY,#00H MOV BKEY,#00H MOV R4, #00H ;------------ 鍵檢測 -------------------- L1: LCALL CDJC ;盒帶狀況顯示 LCALL MCXHJC ;脈沖信號檢測 LCALL YXZKXS ;運行狀況顯示 MOV R3, #0F7H MOV R1, #00H ;初始化 L2: MOV A, R3 MOV P2, A ;R3值賦P2口 MOV A, P2 ;讀取鍵值 MOV R4, A SETB C ;設CY=1 MOV R5, #04H ;掃描4次 L3: RLC A ;A帶進位左移一位 JNC KEY ;CY=0,有鍵按下,轉鍵處理 INC R1 ;無鍵按下,掃描下一列 DJNZ R5, L3 ;掃描不夠4次,再掃描, MOV A, R3 SETB C ;設CY=1 RRC A ;右移一位, MOV R3, A JC L2 LJMP L1 ;重新掃描 KEY: LCALL DL30MS ;延時30Ms D1: MOV A, P2 XRL A,R4 JZ D1 ;等待鍵放開 LCALL BB ;按鍵提示聲 MOV A, R1 LCALL DISP ;調用顯示及功能操作 LJMP L1 ;返回做下一次掃描 ;********** BB提示聲音 *********** BB: MOV R6,250 BB1: CLR P3.3 ACALL BB2 SETB P3.3 LCALL BB2 DJNZ R6,BB1 RET BB2: MOV R7,#50 DJNZ R7,$ RET ;************輸出控制*************** DISP: MOV DPTR, #TABKEY ;讀功能操作數據 MOV A,R1 MOV B,#3 MUL AB JMP @A+DPTR ;轉執行具體功能操作 ;-------------盒帶狀況顯示----------------- CDJC: JB AHD,AWHD MOV DISPAD,#083H ;A有盒帶 MOV DPTR,#TAB2 ;顯示 RADY LCALL DISP0 LJMP BHDJC AWHD: MOV DISPAD,#083H ;A無盒帶 MOV DPTR,#TAB1 ;顯示 -- LCALL DISP0 BHDJC: JB BHD,BWHD MOV DISPAD,#08BH ;B有盒帶 MOV DPTR,#TAB2 ;顯示 RADY LCALL DISP0 RET BWHD: MOV DISPAD,#08BH ;B無盒帶 MOV DPTR,#TAB1 ;顯示 -- DISP0: MOV P0,DISPAD LCALL ENABLE MOV COUNT,#04H LCALL QUSHU RET ;*************脈沖信號檢測********** MCXHJC: MOV A,AKEY ;檢測A鍵值 JZ BMCJC ;A倉無鍵按下檢測B倉 JNB AMC,BMCJC ;有脈沖,檢測B倉 LCALL S4 ;去A停止鍵 BMCJC: MOV A,BKEY ;檢測B鍵值 JZ FHJPJC ;B倉無鍵按下返回 JNB BMC,FHJPJC ;有脈沖,返回 LCALL S12 ;去B停止鍵 FHJPJC: RET ;*************運行狀況顯示********** YXZKXS: MOV A,AKEY CJNE A,#00H, AXS1 MOV DISPAD,#0C2H MOV DPTR,#TAB3 ;A顯示 STOP LCALL DISP0 LJMP BXS1 AXS1: CJNE A,#01H, AXS2 MOV DISPAD,#0C2H MOV DPTR,#TAB4 ;A顯示 >> LCALL DISP0 LJMP BXS1 AXS2: CJNE A,#02H, AXS3 MOV DISPAD,#0C2H MOV DPTR,#TAB5 ;A顯示 >>>> LCALL DISP0 LJMP BXS1 AXS3: CJNE A,#03H, BXS1 MOV DISPAD,#0C2H MOV DPTR,#TAB6 ;A顯示 <<<< LCALL DISP0 BXS1: MOV A,BKEY CJNE A,#00H, BXS2 MOV DISPAD,#0CAH MOV DPTR,#TAB3 ;B顯示 STOP LCALL DISP0 RET BXS2: CJNE A,#01H, BXS3 MOV DISPAD,#0CAH MOV DPTR,#TAB4 ;B顯示 >> LCALL DISP0 RET BXS3: CJNE A,#02H, BXS4 MOV DISPAD,#0CAH MOV DPTR,#TAB5 ;B顯示 >>>> LCALL DISP0 RET BXS4: CJNE A,#03H, XSFH MOV DISPAD,#0CAH MOV DPTR,#TAB6 ;B顯示 <<<< LCALL DISP0 XSFH: RET ;************ A帶 播放 ************** S1: JB AHD,AJX100 MOV A,AKEY ;讀保存的鍵值 CJNE A,#01H,AJX101 ;此鍵未按過,檢查其他鍵 AJX100: LJMP L1 ;正在執行此鍵操作,返回 AJX101: CJNE A,#00H,AJX102 ;有鍵按下(停止鍵除外) AJMP AJX103 AJX102: LCALL ATZ ;去停止鍵 AJX103: LCALL MDJC ;啟動馬達 CLR ACT LCALL DL350MS ;電磁鐵吸合時間350MS SETB ACT MOV AKEY,#01H ;保存鍵值 LJMP L1 ;************** A帶 快進 ************** S2: JB AHD,AJX200 MOV A,AKEY CJNE A,#02H,AJX201 AJX200: LJMP L1 AJX201: CJNE A,#00H,AJX202 AJMP AJX203 AJX202: LCALL ATZ AJX203: LCALL MDJC MOV R0,#2 ;電磁鐵吸合兩次 DE1: CLR ACT LCALL DL100MS SETB ACT LCALL DL200MS DJNZ R0,DE1 MOV AKEY,#02H LJMP L1 ;************* A帶 快倒 *********** S3: JB AHD,AJX300 MOV A,AKEY CJNE A,#03H,AJX301 AJX300: LJMP L1 AJX301: CJNE A,#00H,AJX302 AJMP AJX303 AJX302: LCALL ATZ AJX303: LCALL MDJC CLR ACT LCALL DL100MS SETB ACT MOV AKEY,#03H LJMP L1 ;************* A帶 停止 ************ S4: JNB AHD,AJX000 LJMP L1 ;A倉無帶,返回 AJX000: MOV A,AKEY CJNE A,#00H,AJX001 ;有鍵按下 LJMP L1 AJX001: ACALL ATZ ;停止 MOV AKEY,#00H MOV A,BKEY CJNE A,#00H,AFH0 ;B倉運行中,返回 SETB MDZ ;馬達停止 AFH0: LJMP L1 ATZ: CLR ACT LCALL DL50MS SETB ACT LCALL DL350MS SETB P3.4 ;錄音停止 RET ;********** B帶 播放 ************* S9: JNB BHD,BJX100 LJMP L1 BJX100: MOV A,BKEY CJNE A,#01H,BJX101 LJMP L1 BJX101: CJNE A,#00H,BJX102 AJMP BJX103 BJX102: LCALL BTZ BJX103:LCALL MDJC CLR BCT LCALL DL350MS SETB BCT MOV BKEY,#01H LJMP L1 ;********** B帶 快進 ************ S10: JNB BHD,BJX200 LJMP L1 BJX200: MOV A,BKEY CJNE A,#02H,BJX201 LJMP L1 BJX201: CJNE A,#00H,BJX202 AJMP BJX203 BJX202: LCALL BTZ BJX203:LCALL MDJC MOV R0,#2 DE2: CLR BCT LCALL DL100MS SETB BCT LCALL DL200MS DJNZ R0,DE2 MOV BKEY,#02H LJMP L1 ;************ B帶 快倒 ************ S11: JNB BHD,BJX300 LJMP L1 BJX300: MOV A,BKEY CJNE A,#03H,BJX301 LJMP L1 BJX301: CJNE A,#00H,BJX302 AJMP BJX303 BJX302: LCALL BTZ BJX303:LCALL MDJC CLR BCT LCALL DL100MS SETB BCT MOV BKEY,#03H LJMP L1 ;*********** B帶 停止 ********** S12: JNB BHD,BJX000 LJMP L1 BJX000: MOV A,BKEY CJNE A,#00H,BJX002 LJMP L1 BJX002: ACALL BTZ MOV BKEY,#00H MOV A,#00H CJNE A,AKEY,BFH0 ;A倉運行中,返回 SETB MDZ ;馬達停止 BFH0: LJMP L1 BTZ: CLR BCT LCALL DL50MS SETB BCT LCALL DL350MS RET ;--------------馬達啟動------------ MDJC: JNB MDZ,FHA ;馬達已經運行 CLR MDZ ;啟動馬達 LCALL DL350MS ;延時待馬達運行平穩 FHA: RET ;-------------- 錄音 -------------- S16: JNB P3.4,LYJZ JB LYJ,LYJZ ;禁止錄音 CLR P3.4 ;錄音允許 LCALL S1 LYJZ: LJMP L1 ;------------ 暫無定功能 ---------- S5: LJMP L1 S6: LJMP L1 S7: LJMP L1 S8: LJMP L1 S13: LJMP L1 S14: LJMP L1 S15: LJMP L1 ;*********** 延時程序 ********** DL350MS: MOV R5,#35 ;延時350毫秒 ACALL DT1 RET DL200MS: MOV R5,#20 ;延時200毫秒 ACALL DT1 RET DL100MS: MOV R5,#10 ;延時100毫秒 ACALL DT1 RET DL50MS: MOV R5,#5 ;延時50毫秒 ACALL DT1 RET DL30MS: MOV R5,#3 ;延時30毫秒 DT1: MOV R6,#20 DT2: MOV R7,#250 DJNZ R7,$ DJNZ R6,DT2 DJNZ R5,DT1 RET ;***********控制跳轉數據 *********** TABKEY: LJMP S1 ;A播放 LJMP S2 ;A快進 LJMP S3 ;A快倒 LJMP S4 ;A停止 LJMP S5 ; LJMP S6 ; LJMP S7 ; LJMP S8 ; LJMP S9 ;B播放 LJMP S10 ;B快進 LJMP S11 ;B快倒 LJMP S12 ;B停止 LJMP S13 LJMP S14 LJMP S15 LJMP S16 ;錄音 TAB0: DB 'A: B:' TAB1: DB ' -- ' TAB2: DB 'RADY' TAB3: DB 'STOP' TAB4: DB ' >> ' TAB5: DB '>>>>' TAB6: DB '<<<<' END |