?? 實驗九(點對點串行通信2)_接收.asm
字號:
;功能:在“串入并出”芯片擴展輸出引腳基礎上,增加串行通信
DISPBUF DATA 48H ;筆段碼顯示緩沖區:
;48H單元記錄千位,49H單元記錄百位
;4AH單元記錄十位,4BH單元記錄個位
RXDBuf DATA 30H ;接收緩沖區
RXDC DATA 50H ;發送/接收字節計數器
FRAMES BIT 07H ;信息幀開始標志
SDI BIT P1.2 ;串行數據輸入
SCLK BIT P3.4 ;串行數據移位脈沖
PCLK BIT P3.5 ;并行鎖存脈沖
ORG 0000H
LJMP MAIN
ORG 0023H
LJMP UART ;跳串行口中斷服務程序入口地址
ORG 0050H
;-----主程序開始-----
PROC MAIN
MAIN:
MOV SP, #0DFH ;對于具有256字節內部RAM芯片來說,
;將0E0H-0FFH,共計32字節作為堆棧區
MOV DPTR, #8000H ;關閉蜂鳴器
MOV A, #0FFH
MOVX @DPTR, A
;---復位后,將08H-0FF內部RAM單元清0。
MOV R7, #248
MOV R0, #08H
LOOPIC1:
MOV @R0, #0
INC R0
DJNZ R7, LOOPIC1
;初始化定時器T1(作串行通信波特率發生器輸入信號)
MOV TL1, #250 ;4800波特率對應定時器初值
MOV TH1, #250
ANL TMOD, #0F0H
ORL TMOD, #00100000B ;定時器T1工作在方式2(8位自動重裝初值)
SETB TR1 ;啟動定時器T1
CLR ET1 ;禁止T1中斷
;初始化串行口
MOV SCON, #11010000B ;串行口工作在方式3,SM2=0,以便用TB8位
;作奇偶校驗位。
;SETB REN ;允許接收
ORL PCON, #40H ;將b6位置1,啟用幀錯誤偵測功能
;-----初始化中斷控制器
SETB ES ;允許串行口中斷
SETB EA ;開中斷
;接收顯示處理
WAIT:
MOV R0, #RXDBuf+4
MOV A, @R0 ;讀接收緩沖區有效標志
JNB ACC.7, WAIT ;接收緩沖區無效,等待
CLR ACC.7
MOV @R0, A ;清接收緩沖區有效標志
;把接收緩沖區信息送顯示緩沖區顯示
MOV DPTR, #LEDTAB ;0-F字模表首地址送DPTR
MOV R0, #DISPBUF
MOV R1, #RXDBuf
MOV R7, #4
LOOP1:
MOV A, @R1 ;取顯示數碼
MOVC A, @A+DPTR ;取數碼對應字模
MOV @R0, A ;字模送顯示緩沖區
INC R0
INC R1
DJNZ R7, LOOP1
;顯示分與秒之間的小數點
MOV R0, #DISPBUF+1
MOV A, @R0
CLR ACC.7 ;使b7,即DP位亮
MOV @R0, A ;回寫
SETB REN ;允許串行口接收新的數據
LCALL S_DISP ;執行串行輸出子程序,將筆段碼送LED
SJMP WAIT ;等待
END
PROC S_DISP ;串行輸出子程序
S_DISP:
MOV R0, #DISPBUF ;顯示緩沖區首地址送R0
MOV R7, #4
LOOP2:
MOV A, @R0
MOV R6, #8
LOOP1:
CLR SCLK
RLC A
MOV SDI, C ;串行數據送SDI引腳
NOP
SETB SCLK ;鎖存串行輸入數據
DJNZ R6, LOOP1
;取下一顯示碼
INC R0
DJNZ R7, LOOP2
;4位筆段碼已全部移到串入并出芯片中
CLR PCLK
NOP ;延遲一個機器周期
SETB PCLK
RET
END
PROC UART ;串行中斷服務子程序
UART:
PUSH ACC
PUSH PSW
SETB RS0 ;切換工作寄存器區
SETB RS1
JNB RI, NEXT1
CLR RI ;清除接收中斷
;串行接收有效
JBC SCON.7, RERROR ;幀錯誤
MOV A, SBUF
;執行奇偶校驗,P標志與RB8位應該相同,否則就錯
MOV C, P
ANL C, /RB8 ;計算P. /RB8
MOV F0, C ;暫時保存F0標志中
MOV C, RB8
ANL C, /P ;計算RB8. /P
ORL C, F0 ;完成了P與RB8的異或運算!
JC RERROR ;奇偶校驗錯!
;奇偶校驗正確!判別是否為幀首信息
CJNE A, #0AAH, NEXT11
;等于0AAH,屬于一信息幀開始
MOV RXDC, #0 ;復位接收字節計數器
SETB FRAMES ;幀開始標志有效
SJMP NEXT1
NEXT11:
;非幀首信息
JNB FRAMES, RERROR ;在這之前尚未接收到幀開始標志
;當前接收內容為幀內數據信息
MOV A, RXDC
ADD A, #RXDBuf ;加接收緩沖區首地址
MOV R0, A
MOV @R0, SBUF ;接收數據送接收緩沖區
INC RXDC ;接收字節計數器加1
;判別接收的字節數
MOV A, RXDC
CJNE A, #5, NEXT1
;已經接收了5字節,做和校驗
MOV R0, #RXDBuf
MOV R7, #4 ;對30~33H單元求和,共4字節
CLR A ;清累加器
LOOP1:
ADD A, @R0 ;累加求和
INC R0
DJNZ R7, LOOP1
XRL A, @R0 ;與接收到的和校驗字節異或
JNZ RERROR
;正確
MOV A, @R0
ORL A, #80H
MOV @R0, A ;接收緩沖區數據有效標志
MOV A, #0A5H ;發送0A5H應答信號
CLR REN ;停止接收,等待處理接收數據
SJMP TXDACK
RERROR:
MOV A, #0A6H ;錯誤標志
TXDACK:
CLR FRAMES ;清除幀開始標志
MOV RXDC, #0 ;復位接收字節計數器
MOV C, P ;奇偶標志P送C
MOV TB8, C ;奇偶標志P送TB8,即b8位
MOV SBUF, A ;寫串行口緩沖寄存器,啟動發送
SJMP EXIT
NEXT1:
JNB TI, EXIT
;串行發送結束中斷
CLR TI ;清除發送結束中斷
EXIT:
POP PSW
POP ACC
RETI
END
LEDTAB: ;八段LED共陽數碼管字模
;數碼 0 1 2 3 4 5 6 7
DB 0C0H, 0F9H, 0A4H, 0B0H, 99H, 92H, 82H, 0F8H
;數碼 8 9 A B C D E F
DB 80H, 90H, 88H, 83H, 0C6H, 0A1H, 86H, 8EH
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -