BeHappy 发表于 2024-7-16 21:27:47

串口2仅使能超时功能和既使能超时又使能中断实验现象不一样

本帖最后由 BeHappy 于 2024-7-16 21:34 编辑

环境:

MCU:STC32G8K64
问题描述:
使能了串口2的接收超时功能,用以判断来自串口的数据何时结束,串口2每隔几秒才发几个字节。
每当串口2产生一次中断,对指示灯的状态取反一次,并且给UR2TOCR寄存器赋值。不理解的点出在给这个寄存器的赋值上。进了中断后:
(1)如果给它赋值为80H(使能串口2接收超时功能,但没有使能这个功能的中断),那么实验现象是指示灯常亮(也或许是这个指示灯状态翻转太快,人眼分辨不了?应该不会,因为只有进了串口2的超时中断才会翻转指示灯状态,并且会关闭超时中断,只有串口收到数据才会使能串口2超时中断,串口2每次接收间隔有几秒,很显然,我这眼睛还是能观测得到的);
(2)如果给它赋值为00H(禁用串口2的接收超时功能,也禁用串口2的接收超时中断),那么实验现象是每次进入超时中断,指示灯翻转一次,达到预期。
串口2中断函数代码:
UART2ISR:
      PUSH      ACC
      
      MOV                WR18, #WORD0 UR2TOSR
      MOV                WR16, #WORD2 UR2TOSR
      MOV                R11, @DR16
      JB                ACC.0, HANDLEUR2TO
      
      MOV                A, S2CON
      JNB                ACC.0, HANDLETI
      ; clean UART2 RI interrupt flag
      ANL                S2CON, #NOT 01H
      ; enable UR2 timeout func
      CALL      ENABLEUR2TOINT
      ; skip this interrupt request if CAN frame hasn't sent completed
      JB                UR2FRAMEVERIFIED, UART2ISREND
      
      MOV                R0, UART2WRITEPTR
      MOV                @R0, S2BUF
      ; received bytes number
      INC                UR2RECVCNT
      ; UART2 receiver address increase by 1
      INC                UART2WRITEPTR
      JMP                UART2ISREND
      HANDLETI:
                JNB                ACC.1, UART2ISREND
                ANL                S2CON, #NOT 02H
                JMP                UART2ISREND
      HANDLEUR2TO:
                CPL                RX_LED
                ; clean TOIF flag & reset TM
                MOV                A, #00H
                MOV                WR18, #WORD0 UR2TOSR
                MOV                WR16, #WORD2 UR2TOSR
                MOV                @DR16, R11
                ; disable UART2 timeout interrupt
                MOV                A, #80H
                MOV                WR18, #WORD0 UR2TOCR
                MOV                WR16, #WORD2 UR2TOCR
                MOV                @DR16, R11
                CALL      VERIFYUR2FRAME
      UART2ISREND:
                POP                ACC
                RETI这个是串口2每次RI中断开启接收超时中断的函数:
ENABLEUR2TOINT:
      MOV                WR18, #WORD0 UR2TOCR
      MOV                WR16, #WORD2 UR2TOCR
      MOV                R11, @DR16
      JB                ACC.6, ENABLEUR2TOINTEND
      ORL                A, #40H
      MOV                @DR16, R11
      ENABLEUR2TOINTEND:
                RET期望的现象是,在超时中断里不管给寄存器UR2TOCR赋值00H还是80H(肯定的,ENABLEUR2TOINT给寄存器的赋值也会跟随变化的),实验现象应该都一样的。

soma 发表于 2024-7-16 22:40:54

能用汇编的都是牛人啊。

DebugLab 发表于 2024-7-17 16:51:15

串口中断和串口超时中断入口地址相同,使用串口中断,每接收一个字节进入一次中断,串口超时再进入一次,如果在中断内反相某IO,进中断次数为偶数次则数据包发送前后IO状态一致,速度快无法分辨

DebugLab 发表于 2024-7-17 16:53:56

DebugLab 发表于 2024-7-17 16:51
串口中断和串口超时中断入口地址相同,使用串口中断,每接收一个字节进入一次中断,串口超时再进入一次,如 ...

关闭串口超时中断,中断次数-1,变为奇数,人眼观察LED才有变化,可以尝试打开串口超时中断的同时,数据包增加或减少1个字节,再观察LED

BeHappy 发表于 2024-7-17 22:54:58

本帖最后由 BeHappy 于 2024-7-17 23:05 编辑

DebugLab 发表于 2024-7-17 16:53
关闭串口超时中断,中断次数-1,变为奇数,人眼观察LED才有变化,可以尝试打开串口超时中断的同时,数据 ...
感谢指导 :-)
按说,我只在串口2的接收超时中断处理中,翻转IO状态,如果未使能接收超时中断(即,bit位ENTOI置零),那么位于超时中断处理中翻转IO状态的语句定然不会起作用。但,实际并非如此,除非把bit位ENTO也置零,才能阻止串口2中断函数翻转IO状态,实在不理解这种现象。明明未使能接收超时中断(bit位ENTO置位,ENTOI置零的情况下),为啥还会进入到接收超时中断的处理函数中去?

DebugLab 发表于 2024-7-17 23:08:08

BeHappy 发表于 2024-7-17 22:54
感谢指导 :-)
按说,我只在串口2的接收超时中断处理中,翻转IO状态,如果未使能接收超时中断(即,bit位EN ...

如果是因为串口接收或发送一个字节完毕进入中断,就不要翻转吧

乘风飞扬 发表于 2024-7-18 14:09:40

BeHappy 发表于 2024-7-17 22:54
感谢指导 :-)
按说,我只在串口2的接收超时中断处理中,翻转IO状态,如果未使能接收超时中断(即,bit位EN ...

串口超时中断跟串口接收RI中断、发送TI中断使用同一个中断地址。
如果你开启了接收超时功能ENTO,即便你没有开启接收超时中断ENTOI,在产生接收超时情况下,TOIF中断标志位也会置位。
虽然不会因此触发中断,但是如果是TI或者RI中断触发进入了中断函数,此时在中断函数里面判断TOIF是1而执行对应的中断函数,就会进入到接收超时中断的处理函数中去。

BeHappy 发表于 2024-7-18 22:02:21

乘风飞扬 发表于 2024-7-18 14:09
串口超时中断跟串口接收RI中断、发送TI中断使用同一个中断地址。
如果你开启了接收超时功能ENTO,即便你 ...

非常感谢!
实验现象也是这么个情况。
页: [1]
查看完整版本: 串口2仅使能超时功能和既使能超时又使能中断实验现象不一样