SENTONEBYTE2: ;SENT OUT DATA IN R4
PUSH ACC
MOV IE2, #00H ;Disable the secondary UART interrupt, ES2=0
MOV A, S2CON ;1111,1101, Clear secondary UART transimit interrupt flag
ANL A, #0FDH
MOV S2CON, A
MOV S2BUF, R4
UART2_Send_Wait:
MOV A, S2CON
ANL A, #02H ;0000,0010
CJNE A,#02H, UART2_Send_Wait
MOV A, S2CON
ANL A, #0FDH ;1111,1101, Clear secondary UART transimit interrupt flag
MOV S2CON, A
MOV IE2, #01H ;Enable the secondary UART interrupt, ES2=1
POP ACC
NOP
NOP
NOP
NOP
RET 作者: dalaoshi 時間: 2019-1-25 13:32
另一個問題是,如果這個串口只是單純用來傳送字符就沒有問題,如果還要同時接收字符,那么在傳送等待期間如果有接收到字符,由于串口中斷(IE2)被關(guān)掉了,無法產(chǎn)生接收中斷RI, 那不是要丟失接收到的字符了嗎?作者: welcome123 時間: 2019-1-25 14:57
可以啊,配置中斷發(fā)送和接收,在中斷中去處理不就好了,在有發(fā)送完成中斷時,再放入下一個字節(jié),不過這樣就需要你先開一個緩沖區(qū)或者隊列,對于51來說,RAM都比較小,這么開緩沖區(qū),對你的RAM的使用來說是個問題。作者: dalaoshi 時間: 2019-1-26 02:59
這么說來說明書上的范例不是最好的串口傳送方法了,我的程序是已經(jīng)有緩沖區(qū)了,而STC12的內(nèi)存是很夠的,我還沒學(xué)過一個串口同時發(fā)送和接收,有點擔(dān)心寫不出。我是想用“放了就走,要再放之前先看看是否已經(jīng)傳完(TI已經(jīng)置位)的方式試一下,而且整個過程不關(guān)中斷,不知是否可行。作者: yzwzfyz 時間: 2019-1-27 10:34
范例的目標(biāo)是:說明一個問題。
把程序?qū)懙目茖W(xué)合理是:綜合性的問題。
目的不同,手法不同而矣。不要認(rèn)為范例是最好的,就可以了。學(xué)習(xí)不能太機(jī)械。
關(guān)于串行通訊,串行一個字節(jié),對于CPU來說,需要很久時間,CPU在此時間內(nèi)可以執(zhí)行上千條指令,所以樓主的想法是對的。也是通用的。作者: GUELL 時間: 2019-1-28 15:32
答案是肯定的,你只要開出一個字符串發(fā)送緩沖區(qū)就可以了,在串口發(fā)送字符串時先把字符串送入緩沖區(qū)加結(jié)束符,啟動串口發(fā)送,產(chǎn)生發(fā)送中斷后發(fā)送下一字節(jié)直到發(fā)送結(jié)束,有接收中斷照樣可以接收。作者: dalaoshi 時間: 2019-1-30 01:51
謝謝各位指導(dǎo),看來得用這個新年寫一個收發(fā)的程序看看,串口通訊已經(jīng)發(fā)明了很多年,不能充分掌握實在不能算是掌握單片機(jī),初學(xué)單片機(jī)自然把說明書上的范例當(dāng)成權(quán)威標(biāo)準(zhǔn),不敢稍微改動,熟悉后就想打主意了。作者: dalaoshi 時間: 2019-1-31 03:15
終于寫出來了,用串口助手從PC送字串給單片機(jī)UART2,接收后放進(jìn)緩沖,然后再送回UART2,由PC接收,對照一下沒有錯碼,應(yīng)該是OK了吧。
LED:
DJNZ 3AH, LED1 ;THIS IS FOR LEDSHOWDELAY
DJNZ 3BH, LED1
MOV P2, 3CH
DJNZ 3CH, LED1
JNB 39H, LEDA
CLR 39H
CPL P1.5 ;INDICATE LED LIGHTUP
MOV 3CH, #1
JMP LED1
LEDA:
SETB 39H
CPL P1.5
MOV 3CH, #2
LED1:
MOV A, R0
XRL A, R1
JZ LED
MOV A, @R0
MOV R4, A
LCALL SENTONEBYTE2
LCALL NEXTBUFFER0
JMP LED
NEXTBUFFER0:
CJNE R0, #LASTBUFFER, NEXTBUFFER0A
MOV R0, #FIRSTBUFFER
JMP NEXTBUFFER0EXIT
NEXTBUFFER0A:
INC R0 ;POINT TO NEXT BYTE
NEXTBUFFER0EXIT:
RET
NEXTBUFFER1:
CJNE R1, #LASTBUFFER, NEXTBUFFER1A
MOV R1, #FIRSTBUFFER
JMP NEXTBUFFER1EXIT
NEXTBUFFER1A:
INC R1 ;POINT TO NEXT BUFFER
NEXTBUFFER1EXIT:
RET
SENTONEBYTE2: ;SENT OUT DATA IN R4
PUSH ACC
PUSH PSW
CHECKTI:
MOV A, S2CON ;READ AND CHECK S2TI
ANL A, #00000010B ;MASK EXCEPT BIT1(S2TI)
JZ CHECKTI
MOV A, S2CON
ANL A, #11111101B ;CLEAR SECONDARY UART TRANSIMIT INTERRUPT FLAG
MOV S2CON, A
MOV S2BUF, R4
POP PSW
POP ACC
RET
UART2: ;THIS RECEIVED DATA AND STORE TO BUFFER FOR SENTOUT
;/*----------------------------
;UART2 INTERRUPT SERVICE ROUTINE
;----------------------------*/
PUSH ACC
PUSH PSW
MOV A, S2CON ;READ UART2 CONTROL REGISTER
ANL A, #00000001B ;ANL, IF S2RI=0 THEN 0
JZ UART2CHECKTI
MOV A, S2BUF
MOV @R1, A
LCALL NEXTBUFFER1
MOV A, S2CON ;READ UART2 CONTROL REGISTER AGAIN
ANL A, #11111110B ;CLEAR S2RI BIT
MOV S2CON, A ;SAVE BACK S2CON
JMP UART2EXIT
UART2CHECKTI: ;NOT USE
; --------DO NOTHING
UART2EXIT:
POP PSW
POP ACC
RETI
INITIAL_UART2: ;USE FOR CLOCK OUT MIDI DATA; USE BRT
MOV S2CON, #01010010B ;SET AS BAUD VERIABLE, NO ODD/EVEN CHECK, MUST SET S2TI TO 1 FOR TRANSMIT START
MOV BRT, #BRTLOAD ;RELOAD 1152000
ORL AUXR, #10H ;BRT START RUN
MOV IE2, #01H ;ENABLE UART2 INTERRUPT
RET 作者: dalaoshi 時間: 2019-2-2 13:32
上面那個程序?qū)τ趩蝹UART運作起來似乎沒有什么問題,但是當(dāng)有兩個UART需要同時收發(fā)就出問題了,原因是:兩個UART的接收標(biāo)志TI,S2TI都長時間置位,會互掐,就看誰的中斷優(yōu)先權(quán)高,低的那個接收到字符也不產(chǎn)生中斷,難怪我看到一些范例有BUSY BIT 的設(shè)置,啟用BUSY BIT 概念后,改寫一下,問題就解決了。
INITIAL_UART1:
MOV SCON, #01010000B ;SET AS BAUD VERIABLE, NO ODD/EVEN CHECK
MOV TH1, #RELOAD_COUNT
MOV TL1, #RELOAD_COUNT
SETB PS ;SERIAL PORT PRORITY HIGH
SETB TR1 ;RUN TIMER_1
SETB ES ;ENABLE UART1 INTERRUPT
RET
UART1:
;/*----------------------------
;UART1 INTERRUPT SERVICE ROUTINE
;----------------------------*/
PUSH ACC
PUSH PSW
JNB RI, UART1CHECKTI
CLR RI
MOV A, SBUF ;READ THE CHARACTER FROM THE SERIAL PORT
MOV @R1, A
CALL NEXTBUFFER1
JMP UART1EXIT
UART1CHECKTI:
CLR TI
CLR 40H ;CLEAR BUSY BIT
UART1EXIT:
POP PSW
POP ACC
RETI
SENTONEBYTE1: ;SENT OUT DATA IN R4
PUSH ACC
PUSH PSW
CHECKBUSY1:
JB 40H, CHECKBUSY1
SETB 40H ;MARK BUSY BIT
MOV SBUF, R4
POP PSW
POP ACC
RET
INITIAL_UART2:
MOV S2CON, #01010000B ;SET AS BAUD VERIABLE, NO ODD/EVEN CHECK
MOV BRT, #BRTLOAD ;RELOAD
ORL AUXR, #10H ;BRT START RUN
MOV IP2, #01H ;UART INTERUUPT PARITY HIGH
MOV IE2, #01H ;ENABLE UART2 INTERRUPT
RET
UART2:
;/*----------------------------
;UART2 INTERRUPT SERVICE ROUTINE
;----------------------------*/
PUSH ACC
PUSH PSW
MOV P0, #01010101B
MOV A, S2CON ;READ UART2 CONTROL REGISTER
ANL A, #00000001B ;ANL, IF S2RI=0 THEN 0
JZ UART2CHECKTI
MOV A, S2BUF
MOV @R1, A
LCALL NEXTBUFFER1
MOV A, S2CON ;READ UART2 CONTROL REGISTER AGAIN
ANL A, #11111110B ;CLEAR S2RI BIT
MOV S2CON, A ;SAVE BACK S2CON
JMP UART2EXIT
UART2CHECKTI:
MOV A, S2CON ;READ UART2 CONTROL REGISTER AGAIN
ANL A, #11111101B ;CLEAR S2TI BIT
MOV S2CON, A
CLR 41H ;CLEAR BUSY BIT
UART2EXIT:
POP PSW
POP ACC
RETI
SENTONEBYTE2: ;SENT OUT DATA IN R4
PUSH ACC
PUSH PSW
CHECKBUSY2:
JB 41H, CHECKBUSY2
SETB 41H ;MARK BUSY BIT
MOV A, S2CON
MOV S2BUF, R4
POP PSW
POP ACC
RET