標(biāo)題: STC單片機(jī)串口2字符傳送程序效率的問題 [打印本頁]

作者: dalaoshi    時間: 2019-1-25 13:10
標(biāo)題: STC單片機(jī)串口2字符傳送程序效率的問題
這是我從STC說明書抄下來用UART2發(fā)送字符的程序,雖然用起來沒問題,但對于其必須在那里白白等待(UART2_Send_Wait)字符傳送完畢,產(chǎn)生中斷置位TI才能離開不很理解,為何不是放下字符R4后馬上離開去干別的事,讓中斷來通知你可以再來傳字符呢?有沒有更有效率的串口傳送程序?各位論壇大佬有何高見呢?


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





歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1