找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 2172|回復(fù): 8
打印 上一主題 下一主題
收起左側(cè)

STC單片機(jī)串口2字符傳送程序效率的問(wèn)題

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:283954 發(fā)表于 2019-1-25 13:10 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
這是我從STC說(shuō)明書(shū)抄下來(lái)用UART2發(fā)送字符的程序,雖然用起來(lái)沒(méi)問(wèn)題,但對(duì)于其必須在那里白白等待(UART2_Send_Wait)字符傳送完畢,產(chǎn)生中斷置位TI才能離開(kāi)不很理解,為何不是放下字符R4后馬上離開(kāi)去干別的事,讓中斷來(lái)通知你可以再來(lái)傳字符呢?有沒(méi)有更有效率的串口傳送程序?各位論壇大佬有何高見(jiàn)呢?


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
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:283954 發(fā)表于 2019-1-25 13:32 | 只看該作者
另一個(gè)問(wèn)題是,如果這個(gè)串口只是單純用來(lái)傳送字符就沒(méi)有問(wèn)題,如果還要同時(shí)接收字符,那么在傳送等待期間如果有接收到字符,由于串口中斷(IE2)被關(guān)掉了,無(wú)法產(chǎn)生接收中斷RI, 那不是要丟失接收到的字符了嗎?
回復(fù)

使用道具 舉報(bào)

板凳
ID:303394 發(fā)表于 2019-1-25 14:57 | 只看該作者
可以啊,配置中斷發(fā)送和接收,在中斷中去處理不就好了,在有發(fā)送完成中斷時(shí),再放入下一個(gè)字節(jié),不過(guò)這樣就需要你先開(kāi)一個(gè)緩沖區(qū)或者隊(duì)列,對(duì)于51來(lái)說(shuō),RAM都比較小,這么開(kāi)緩沖區(qū),對(duì)你的RAM的使用來(lái)說(shuō)是個(gè)問(wèn)題。

評(píng)分

參與人數(shù) 1黑幣 +60 收起 理由
admin + 60 回帖助人的獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

地板
ID:283954 發(fā)表于 2019-1-26 02:59 | 只看該作者
這么說(shuō)來(lái)說(shuō)明書(shū)上的范例不是最好的串口傳送方法了,我的程序是已經(jīng)有緩沖區(qū)了,而STC12的內(nèi)存是很夠的,我還沒(méi)學(xué)過(guò)一個(gè)串口同時(shí)發(fā)送和接收,有點(diǎn)擔(dān)心寫(xiě)不出。我是想用“放了就走,要再放之前先看看是否已經(jīng)傳完(TI已經(jīng)置位)的方式試一下,而且整個(gè)過(guò)程不關(guān)中斷,不知是否可行。
回復(fù)

使用道具 舉報(bào)

5#
ID:123289 發(fā)表于 2019-1-27 10:34 | 只看該作者
范例的目標(biāo)是:說(shuō)明一個(gè)問(wèn)題。
把程序?qū)懙目茖W(xué)合理是:綜合性的問(wèn)題。
目的不同,手法不同而矣。不要認(rèn)為范例是最好的,就可以了。學(xué)習(xí)不能太機(jī)械。
關(guān)于串行通訊,串行一個(gè)字節(jié),對(duì)于CPU來(lái)說(shuō),需要很久時(shí)間,CPU在此時(shí)間內(nèi)可以執(zhí)行上千條指令,所以樓主的想法是對(duì)的。也是通用的。
回復(fù)

使用道具 舉報(bào)

6#
ID:250700 發(fā)表于 2019-1-28 15:32 | 只看該作者
答案是肯定的,你只要開(kāi)出一個(gè)字符串發(fā)送緩沖區(qū)就可以了,在串口發(fā)送字符串時(shí)先把字符串送入緩沖區(qū)加結(jié)束符,啟動(dòng)串口發(fā)送,產(chǎn)生發(fā)送中斷后發(fā)送下一字節(jié)直到發(fā)送結(jié)束,有接收中斷照樣可以接收。
回復(fù)

使用道具 舉報(bào)

7#
ID:283954 發(fā)表于 2019-1-30 01:51 | 只看該作者
謝謝各位指導(dǎo),看來(lái)得用這個(gè)新年寫(xiě)一個(gè)收發(fā)的程序看看,串口通訊已經(jīng)發(fā)明了很多年,不能充分掌握實(shí)在不能算是掌握單片機(jī),初學(xué)單片機(jī)自然把說(shuō)明書(shū)上的范例當(dāng)成權(quán)威標(biāo)準(zhǔn),不敢稍微改動(dòng),熟悉后就想打主意了。
回復(fù)

使用道具 舉報(bào)

8#
ID:283954 發(fā)表于 2019-1-31 03:15 | 只看該作者
終于寫(xiě)出來(lái)了,用串口助手從PC送字串給單片機(jī)UART2,接收后放進(jìn)緩沖,然后再送回UART2,由PC接收,對(duì)照一下沒(méi)有錯(cuò)碼,應(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
回復(fù)

使用道具 舉報(bào)

9#
ID:283954 發(fā)表于 2019-2-2 13:32 | 只看該作者
上面那個(gè)程序?qū)τ趩蝹(gè)UART運(yùn)作起來(lái)似乎沒(méi)有什么問(wèn)題,但是當(dāng)有兩個(gè)UART需要同時(shí)收發(fā)就出問(wèn)題了,原因是:兩個(gè)UART的接收標(biāo)志TI,S2TI都長(zhǎng)時(shí)間置位,會(huì)互掐,就看誰(shuí)的中斷優(yōu)先權(quán)高,低的那個(gè)接收到字符也不產(chǎn)生中斷,難怪我看到一些范例有BUSY BIT 的設(shè)置,啟用BUSY BIT 概念后,改寫(xiě)一下,問(wèn)題就解決了。

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
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表