找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1794|回复: 8
打印 上一主题 下一主题
收起左侧

STC单片机串口2字符传送程序效率的问题

[复制链接]
跳转到指定楼层
楼主
ID:283954 发表于 2019-1-25 13:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
这是我从STC说明书抄下来用UART2发送字符的程序,虽然用起来没问题,但对于其必须在那里白白等待(UART2_Send_Wait)字符传送完毕,产生中断置位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
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:283954 发表于 2019-1-25 13:32 | 只看该作者
另一个问题是,如果这个串口只是单纯用来传送字符就没有问题,如果还要同时接收字符,那么在传送等待期间如果有接收到字符,由于串口中断(IE2)被关掉了,无法产生接收中断RI, 那不是要丢失接收到的字符了吗?
回复

使用道具 举报

板凳
ID:303394 发表于 2019-1-25 14:57 | 只看该作者
可以啊,配置中断发送和接收,在中断中去处理不就好了,在有发送完成中断时,再放入下一个字节,不过这样就需要你先开一个缓冲区或者队列,对于51来说,RAM都比较小,这么开缓冲区,对你的RAM的使用来说是个问题。

评分

参与人数 1黑币 +60 收起 理由
admin + 60 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

地板
ID:283954 发表于 2019-1-26 02:59 | 只看该作者
这么说来说明书上的范例不是最好的串口传送方法了,我的程序是已经有缓冲区了,而STC12的内存是很够的,我还没学过一个串口同时发送和接收,有点担心写不出。我是想用“放了就走,要再放之前先看看是否已经传完(TI已经置位)的方式试一下,而且整个过程不关中断,不知是否可行。
回复

使用道具 举报

5#
ID:123289 发表于 2019-1-27 10:34 | 只看该作者
范例的目标是:说明一个问题。
把程序写的科学合理是:综合性的问题。
目的不同,手法不同而矣。不要认为范例是最好的,就可以了。学习不能太机械。
关于串行通讯,串行一个字节,对于CPU来说,需要很久时间,CPU在此时间内可以执行上千条指令,所以楼主的想法是对的。也是通用的。
回复

使用道具 举报

6#
ID:250700 发表于 2019-1-28 15:32 | 只看该作者
答案是肯定的,你只要开出一个字符串发送缓冲区就可以了,在串口发送字符串时先把字符串送入缓冲区加结束符,启动串口发送,产生发送中断后发送下一字节直到发送结束,有接收中断照样可以接收。
回复

使用道具 举报

7#
ID:283954 发表于 2019-1-30 01:51 | 只看该作者
谢谢各位指导,看来得用这个新年写一个收发的程序看看,串口通讯已经发明了很多年,不能充分掌握实在不能算是掌握单片机,初学单片机自然把说明书上的范例当成权威标准,不敢稍微改动,熟悉后就想打主意了。
回复

使用道具 举报

8#
ID:283954 发表于 2019-1-31 03:15 | 只看该作者
终于写出来了,用串口助手从PC送字串给单片机UART2,接收后放进缓冲,然后再送回UART2,由PC接收,对照一下没有错码,应该是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
回复

使用道具 举报

9#
ID:283954 发表于 2019-2-2 13:32 | 只看该作者
上面那个程序对于单个UART运作起来似乎没有什么问题,但是当有两个UART需要同时收发就出问题了,原因是:两个UART的接收标志TI,S2TI都长时间置位,会互掐,就看谁的中断优先权高,低的那个接收到字符也不产生中断,难怪我看到一些范例有BUSY BIT 的设置,启用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
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表