;串列傳輸練習; 可傳送和接收(註:此程式只適用於82G516) ;此程式因使用到82G516才有之暫存器, 所以須先載入82G516暫存器定義檔 ;執行時務必把Keil uVision2中的設定Define 8051 SFR Names勾勾取消 $INCLUDE (REG_MPC82G516.inc) ;for MPC82G516 暫存器定義檔 LCD_RS EQU P1.0 ;定義LCD接線位置 LCD_RW EQU P1.1 LCD_E EQU P1.2 LCD_DATA EQU P2 KB EQU P0 KB_BUF EQU 30H ORG 0H JMP START ORG 23H JMP UART_INT START: MOV SCON,#01010000B ;設定串列傳輸工作於模式1, 可接收資料 MOV TMOD,#00100000B ;設定TIMER1工作於模式2(自動載入模式) ORL AUXR2,#01000000B ;將AUXR2暫存器中的T1X12設為1 ;也就是TIMER1之計時時脈不除以12 MOV TH1,#217 ;設定自動載入值為216(在石英震盪器為12MHz時, 鮑率為9600bps) SETB TR1 ;啟動TIMER1 MOV IE,#10010000B ;啟動UART中斷 CLR LCD_RW ;習慣上直接將LCD的RW接腳直接接地, MOV A,#00111000B ;設定LCD介面為8位元, 2行, 5x7字型 CALL WRIR MOV A,#00001111B ;設定要LCD顯示, 要有游標, 要閃爍 CALL WRIR MOV A,#00000110B ;設定寫資料進入LCD時, 顯示器不要動, 游標向右移一格 CALL WRIR MOV A,#1 ;清除LCD CALL WRIR MOV R5,#1 ;延遲等清除LCD命令處理完畢 CALL DELAY AGAIN: MOV R4,#4 MOV KB_BUF,#11111110B ;掃描訊號 NEXT: MOV KB,KB_BUF ;送至鍵盤 MOV A,KB ;讀回鍵盤訊號 ANL A,#11110000B ;將後4位元清為0 CJNE A,#11110000B,RECHECK ;判斷是否按鍵盤(前4位元有不為0的情況) MOV A,KB_BUF ;若無則將KB_BUF內的資料左旋 RL A ; MOV KB_BUF,A ;準備掃描下一行 DJNZ R4,NEXT ;R4內的資料減一,判斷是否掃瞄4次 JMP AGAIN ;重新開始掃描 RECHECK: MOV R5,#3 ;延遲,除彈跳 CALL DELAY MOV A,KB ;重新讀回按鍵訊號 ANL A,#11110000B CJNE A,#11110000B,KEY_IN ;判斷是否按鍵盤 JMP AGAIN ;若無則為彈跳訊號, 重新開始掃描 KEY_IN: MOV A,KB ;讀回鍵盤訊號 CALL KEY ;執行判斷按鍵副程式 WAIT: MOV A,KB ;重新讀回按鍵訊號 ANL A,#11110000B CJNE A,#11110000B,WAIT ;判斷按鍵是否放開 JMP AGAIN ;------ 判斷按鍵副程式, 並將該鍵對應的值顯示在LCD ----------- ;-------------- () ---------------- KEY: CJNE A,#11101110B,S1 MOV A,#'C' MOV SBUF,A RET S1: CJNE A,#11101101B,S2 MOV A,#'D' MOV SBUF,A RET S2: CJNE A,#11101011B,S3 MOV A,#'E' MOV SBUF,A RET S3: CJNE A,#11100111B,S4 MOV A,#'F' MOV SBUF,A RET S4: CJNE A,#11011110B,S5 MOV A,#'8' MOV SBUF,A RET S5: CJNE A,#11011101B,S6 MOV A,#'9' MOV SBUF,A RET S6: CJNE A,#11011011B,S7 MOV A,#'A' MOV SBUF,A RET S7: CJNE A,#11010111B,S8 MOV A,#'B' MOV SBUF,A RET S8: CJNE A,#10111110B,S9 MOV A,#'4' MOV SBUF,A RET S9: CJNE A,#10111101B,S10 MOV A,#'5' MOV SBUF,A RET S10: CJNE A,#10111011B,S11 MOV A,#'6' MOV SBUF,A RET S11: CJNE A,#10110111B,S12 MOV A,#'7' MOV SBUF,A RET S12: CJNE A,#01111110B,S13 MOV A,#'0' MOV SBUF,A RET S13: CJNE A,#01111101B,S14 MOV A,#'1' MOV SBUF,A RET S14: CJNE A,#01111011B,S15 MOV A,#'2' MOV SBUF,A RET S15: CJNE A,#01110111B,SEND MOV A,#'3' MOV SBUF,A SEND: RET WRIR: CLR LCD_RS ;寫命令到LCD副程式 SETB LCD_E MOV LCD_DATA,A MOV R7,#50 ;延遲等訊號穩定 DJNZ R7,$ CLR LCD_E ;讓Enable接腳產生負緣訊號 MOV R7,#60 ;延遲等訊號處裡完畢 DJNZ R7,$ RET WRDR: SETB LCD_RS ;寫資料到LCD副程式 SETB LCD_E MOV LCD_DATA,A MOV R7,#50 ;延遲等訊號穩定 DJNZ R7,$ CLR LCD_E ;讓Enable接腳產生負緣訊號 MOV R7,#60 ;延遲等訊號處裡完畢 DJNZ R7,$ RET DELAY: MOV R6,#100 DEL: MOV R7,#100 DJNZ R7,$ DJNZ R6,DEL DJNZ R5,DELAY RET ;---------------------------------------------------------------------------------------------------- UART_INT: JNB TI,IS_RI ;判斷是否為傳送完畢中斷(TI=1), 如果不是就是接收完畢中斷(RI=1) CLR TI ;清除傳送完畢中斷旗號 RETI IS_RI: CLR RI ;清除接收完畢中斷旗號 MOV A,SBUF CALL WRDR ;將收到資料顯示於LCD RETI END