[技术问答] 发现一个中断奇怪的现象,一起研究研究

[复制链接]
914|8
 楼主| huangcunxiake 发表于 2020-8-2 16:35 | 显示全部楼层 |阅读模式


  1. #include "ML51.h"
  2. unsigned char c;

  3. void UART0_ISR(void) interrupt 4
  4. {
  5.         if((SCON&SET_BIT0)==SET_BIT0)
  6.         {
  7.                 c = SBUF;
  8.                 SBUF = c;
  9.                 clr_SCON_RI;
  10.         }
  11.                 P03 ^= 1;       
  12. }


  13. void main (void)
  14. {



  15.         MFP_P03_GPIO;
  16.         P03_PUSHPULL_MODE;
  17.         /**
  18.         For UART0 P0.5 asTXD output setting
  19.         * include uart.c in Common Setting for UART0
  20.         */
  21.         MFP_P31_UART0_TXD;                              /* set P3.1 and P3.0 as Quasi mode for UART0 trasnfer */
  22.         MFP_P30_UART0_RXD;
  23.         P31_QUASI_MODE;                                 
  24.         P30_QUASI_MODE;
  25.         UART_Open(24000000,UART0_Timer1,115200);      // Open UART0 use timer1 as baudrate generate and baud rate = 115200

  26.         UART_Interrupt_Enable(UART0,Enable);
  27.         ENABLE_GLOBAL_INTERRUPT;

  28.         while(1)
  29.         {
  30.         }

  31. }
注意中断函数,P03 ^= 1; 只能被执行一次,不知道为何。而把P03 ^= 1;放到前面判断的大括号里就可以运行到了,否则,只能被运行到一次就不再到这个位置了。这说明一个问题
 楼主| huangcunxiake 发表于 2020-8-2 16:36 | 显示全部楼层
什么问题呢,当中断连续发生的时候,如果你还没执行完,可能就二次进入中断了
 楼主| huangcunxiake 发表于 2020-8-2 16:36 | 显示全部楼层
因为你前面已经清理掉了中断标识,所以就可以二次响应中断信号。
 楼主| huangcunxiake 发表于 2020-8-2 16:39 | 显示全部楼层
经过测试还是不行的,那么怎么做可以解决这个问题呢
 楼主| huangcunxiake 发表于 2020-8-2 16:44 | 显示全部楼层
经过试验,只有全部放到判断里,才能正常运行,好奇怪啊,有人知道为何吗
  1. void UART0_ISR(void) interrupt 4
  2. {

  3.         if((SCON&SET_BIT0)==SET_BIT0)
  4.         {

  5.                 c = SBUF;
  6.                 SBUF = c;
  7.                 P03 ^= 1;
  8.                 clr_SCON_RI;
  9.         }
  10. }
 楼主| huangcunxiake 发表于 2020-8-2 16:45 | 显示全部楼层


  1. #include "ML51.h"
  2. unsigned char c;

  3. void UART0_ISR(void) interrupt 4
  4. {

  5.         if((SCON&SET_BIT0)==SET_BIT0)
  6.         {

  7.                 c = SBUF;
  8.                 SBUF = c;
  9.                 P03 ^= 1;
  10.                 clr_SCON_RI;
  11.         }
  12. }

  13. void main (void)
  14. {
  15.         //LED端口初始化为数字输出推挽模式
  16.         MFP_P03_GPIO;
  17.         P03_PUSHPULL_MODE;
  18.         /**
  19.         For UART0 P0.5 asTXD output setting
  20.         * include uart.c in Common Setting for UART0
  21.         */
  22.         MFP_P31_UART0_TXD;                              /* set P3.1 and P3.0 as Quasi mode for UART0 trasnfer */
  23.         MFP_P30_UART0_RXD;
  24.         P31_QUASI_MODE;                                 
  25.         P30_QUASI_MODE;
  26.         UART_Open(24000000,UART0_Timer1,115200);      // Open UART0 use timer1 as baudrate generate and baud rate = 115200
  27. //启用串口0中断,并开启全局中断
  28.         UART_Interrupt_Enable(UART0,Enable);
  29.         ENABLE_GLOBAL_INTERRUPT;

  30.         while(1)
  31.         {
  32.         }

  33. }
小灵通2018 发表于 2020-8-2 17:07 | 显示全部楼层
多谢分享。
小灵通2018 发表于 2020-8-2 17:18 | 显示全部楼层
试了一下,刚开始以为是楼主没处理发送中断。。结果不是 啊,好奇怪。


  1. #include "ML51.h"
  2. unsigned char c;

  3. void UART0_ISR(void) interrupt 4
  4. {

  5.         if((SCON&SET_BIT0)==SET_BIT0)
  6.         {
  7.                 c = SBUF;
  8.                 SBUF = c;
  9.                 clr_SCON_RI;
  10.         }
  11.         else if((SCON&SET_BIT1)==SET_BIT1)
  12.         {
  13.                 clr_SCON_TI;
  14.                 P03 ^= 1;
  15.         }
  16. }

  17. void main (void)
  18. {
  19.         //LED端口初始化为数字输出推挽模式
  20.         MFP_P03_GPIO;
  21.         P03_PUSHPULL_MODE;
  22.         /**
  23.         For UART0 P0.5 asTXD output setting
  24.         * include uart.c in Common Setting for UART0
  25.         */
  26.         MFP_P31_UART0_TXD;                              /* set P3.1 and P3.0 as Quasi mode for UART0 trasnfer */
  27.         MFP_P30_UART0_RXD;
  28.         P31_QUASI_MODE;                                 
  29.         P30_QUASI_MODE;
  30.         UART_Open(24000000,UART0_Timer1,115200);      // Open UART0 use timer1 as baudrate generate and baud rate = 115200
  31. //启用串口0中断,并开启全局中断
  32.         UART_Interrupt_Enable(UART0,Enable);
  33.         ENABLE_GLOBAL_INTERRUPT;

  34.         while(1)
  35.         {
  36.         }

  37. }
jasontu 发表于 2020-8-3 09:03 | 显示全部楼层
8051有ti 中斷及ri中斷。
傳送後也要清ti flag.
void Uart0_SendChar(unsigned char Udat)
{
        DISABLE_UART0_INTERRUPT;
        SBUF=Udat;                //蔚猁楷冞腔杅擂溫揹諳杅擂遣喳
        while(!TI);                //脹渾楷冞俇傖
  TI=0;         //錨TI楷冞俇傖梓暮               
  ENABLE_UART0_INTERRUPT;
}
您需要登录后才可以回帖 登录 | 注册

本版积分规则

223

主题

3745

帖子

11

粉丝
快速回复 在线客服 返回列表 返回顶部