找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 7700|回复: 12
收起左侧

51单片机的外部中断函数里可以有if语句吗

  [复制链接]
ID:72258 发表于 2015-4-8 20:20 | 显示全部楼层 |阅读模式
  1. /* 通过中断来控制流水灯 */

  2. #include <reg52.h>
  3. #include <intrins.h>

  4. #define  LED  P0
  5. #define  uchar  unsigned char

  6. //uchar count;

  7. void delay_100ms()                //@11.0592MHz
  8. {
  9.         unsigned char i, j, k;

  10.         _nop_();
  11.         _nop_();
  12.         i = 5;
  13.         j = 52;
  14.         k = 195;
  15.         do
  16.         {
  17.                 do
  18.                 {
  19.                         while (--k);
  20.                 } while (--j);
  21.         } while (--i);
  22. }

  23. void liushuideng1()
  24. {
  25.        
  26.         uchar i,led;
  27.         led = 0xfe;
  28. //        while(1)
  29. //        {
  30.                 for(i=0;i<8;i++)
  31.                 {
  32.                         LED = _crol_(led,i);
  33.                         delay_100ms();
  34.                         if(i==8)
  35.                                 i = 0;
  36.                         EX0 = 1;       
  37.                 }
  38. //        }
  39. }

  40. void liushuideng2()
  41. {
  42.         uchar led,i;
  43.         led = 0xff;
  44. //        while(1)
  45. //        {
  46.                 for(i=0;i<8;i++)
  47.                 {
  48.                         led >>= 1;
  49.                         LED = led;
  50.                         delay_100ms();
  51.                         if(i==8)
  52.                         {        i = 0;
  53.                                 led = 0x7f;}
  54.                 }
  55. //        }
  56. }

  57. void liushuideng3()
  58. {
  59.         uchar led;
  60.         led = 0xaa;
  61. //        while(1)
  62. //        {
  63.                 LED = led;
  64.                 delay_100ms();
  65.                 LED = ~led;
  66.                 delay_100ms();
  67. //        }

  68. }

  69. void ZD_init()
  70. {
  71.         EA = 1;
  72.         EX0 = 1;
  73.         IT0 = 1;
  74. }

  75. void main()
  76. {
  77. //        uchar i;
  78.         ZD_init();
  79.         while(1)
  80.         {
  81.                 LED = 0xff;
  82.                 delay_100ms();
  83.                 LED = 0x00;
  84.                 delay_100ms();
  85.         }
  86. }


  87. void waibuZD0()        interrupt 0
  88. {
  89.         static count = 0;
  90.         count++;
  91.         if(count == 1)
  92.                 {       
  93.                         liushuideng1();        
  94. //                        delay_100ms();
  95.                 }
  96.         else if(count == 2)
  97.                 {       
  98.                         liushuideng2();
  99. //                        delay_100ms();
  100.                 }
  101.         else if(count == 3)
  102.                 {       
  103.                         liushuideng3();
  104. //                        delay_100ms();
  105.                 }
  106.         else
  107.                 { count = 0;
  108.                 }
  109.        
  110. }
复制代码
上面是代码,现象是,中断一次会产生两个流水灯现象。而我要的是中断一次只产生一个流水灯现象。并且只用一个中断。
回复

使用道具 举报

ID:73833 发表于 2015-4-9 09:00 | 显示全部楼层
好像没人说不可以
回复

使用道具 举报

ID:73833 发表于 2015-4-9 09:01 | 显示全部楼层
好像没人说不可以在中断服务程序里用IF
回复

使用道具 举报

ID:76491 发表于 2015-4-9 10:56 | 显示全部楼层
估计是中断源的问题,如果中断源是按键,就可能是按键抖动的问题,实际上产生了多次中断。可以加个消抖电路,不如加个电容之类

评分

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

查看全部评分

回复

使用道具 举报

ID:632653 发表于 2019-11-12 16:23 | 显示全部楼层
如果中断源是按钮的话,可以通过代码延时来进行按钮的消抖操作
回复

使用道具 举报

ID:640572 发表于 2019-11-12 17:21 | 显示全部楼层
当然可以呀
回复

使用道具 举报

ID:411550 发表于 2019-11-12 17:53 | 显示全部楼层
按键按下存在抖动,必须要采取硬件或者软件延时来消除抖动
回复

使用道具 举报

ID:636210 发表于 2019-11-12 17:54 | 显示全部楼层
你这代码没问题,主要是外引脚触发方式没有定义吧,上升沿和下降沿都解发了中断,所以就出现两次了。
回复

使用道具 举报

ID:640671 发表于 2019-11-12 21:17 | 显示全部楼层
IT0默认为0,上升沿中断,下降沿也中断,你所说的中断一次实际上是触发了两次中断,产生两个流水灯现象没毛病。
回复

使用道具 举报

ID:637250 发表于 2019-11-12 21:54 | 显示全部楼层
可以的,实在不知道,就试试嘛
回复

使用道具 举报

ID:97424 发表于 2019-11-12 22:46 | 显示全部楼层
可以的
回复

使用道具 举报

ID:245004 发表于 2019-11-12 22:46 | 显示全部楼层
根据你的代码原文稍作精简和修饰,你可以试一下(while里面注释掉的代码也可以取消注释):
/* 通过中断来控制流水灯 */

#include <intrins.h>
#include <reg52.h>

#define LED P0
#define uchar unsigned char

void Delay_100ms(void) {
  unsigned char i, j, k;

  _nop_();
  _nop_();
  i = 5;
  j = 52;
  k = 195;
  do {
    do {
      while (--k)
        ;
    } while (--j);
  } while (--i);
}

void LiuShuiDeng1(void) {
  uchar i;

  for (i = 0; i < 8; i++) {
    LED = ~(0x01 << i);
    Delay_100ms();
  }
}

void LiuShuiDeng2(void) {
  uchar i;
  uchar temp = ~0x80;

  for (i = 0; i < 8; i++) {
    LED = temp >> i;
    Delay_100ms();
  }
}

void LiuShuiDeng3(void) {
  LED = 0xaa;
  Delay_100ms();
  LED = ~0xaa;
  Delay_100ms();
}

void ExInt0_init(void) {
  IT0 = 1;
  EX0 = 1;
  EA = 1;
}

void main(void) {
  ExInt0_init();
  while (1) {
    // LED = 0xff;
    // Delay_100ms();
    // LED = 0x00;
    // Delay_100ms();
  }
}

void ExInt0(void) interrupt 0 {
  static uchar count;

  count++;
  switch (count) {
    case 1:
      LiuShuiDeng1();
      break;
    case 2:
      LiuShuiDeng2();
      break;
    case 3:
      LiuShuiDeng3();
      count = 0;
      break;
    default:
      count = 0;
      break;
  }
}



回复

使用道具 举报

ID:245004 发表于 2019-11-12 23:14 | 显示全部楼层
当第一次外部中断0执行的时候,外部中断请求位IE0会自动被清零,中断之所以执行两遍,很显然是当执行第一次中断的过程中再次有信号触发了中断,所以第一遍执行完依然存在中断标志,继而执行第二次中断并清除已存在的请求标志。为什么没有第三次?因为这个触发信号显然在第一次触发的时候发生的,正如楼上几位朋友分析的,是因为抖动重复触发。
在中断函数最后一个大括号前加一句:“IE0 = 0;”人为清除中断请求标志。

void ExInt0(void) interrupt 0 {
  ...
  ...
  ...
  IE0 = 0;
}

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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