找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 8074|回復(fù): 12
收起左側(cè)

51單片機(jī)的外部中斷函數(shù)里可以有if語句嗎

  [復(fù)制鏈接]
ID:72258 發(fā)表于 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. }
復(fù)制代碼
上面是代碼,現(xiàn)象是,中斷一次會產(chǎn)生兩個流水燈現(xiàn)象。而我要的是中斷一次只產(chǎn)生一個流水燈現(xiàn)象。并且只用一個中斷。

相關(guān)帖子

回復(fù)

使用道具 舉報

ID:73833 發(fā)表于 2015-4-9 09:00 | 顯示全部樓層
好像沒人說不可以
回復(fù)

使用道具 舉報

ID:73833 發(fā)表于 2015-4-9 09:01 | 顯示全部樓層
好像沒人說不可以在中斷服務(wù)程序里用IF
回復(fù)

使用道具 舉報

ID:76491 發(fā)表于 2015-4-9 10:56 | 顯示全部樓層
估計是中斷源的問題,如果中斷源是按鍵,就可能是按鍵抖動的問題,實(shí)際上產(chǎn)生了多次中斷?梢约觽消抖電路,不如加個電容之類

評分

參與人數(shù) 1黑幣 +35 收起 理由
admin + 35 回帖助人的獎勵!

查看全部評分

回復(fù)

使用道具 舉報

ID:632653 發(fā)表于 2019-11-12 16:23 | 顯示全部樓層
如果中斷源是按鈕的話,可以通過代碼延時來進(jìn)行按鈕的消抖操作
回復(fù)

使用道具 舉報

ID:640572 發(fā)表于 2019-11-12 17:21 | 顯示全部樓層
當(dāng)然可以呀
回復(fù)

使用道具 舉報

ID:411550 發(fā)表于 2019-11-12 17:53 | 顯示全部樓層
按鍵按下存在抖動,必須要采取硬件或者軟件延時來消除抖動
回復(fù)

使用道具 舉報

ID:636210 發(fā)表于 2019-11-12 17:54 | 顯示全部樓層
你這代碼沒問題,主要是外引腳觸發(fā)方式?jīng)]有定義吧,上升沿和下降沿都解發(fā)了中斷,所以就出現(xiàn)兩次了。
回復(fù)

使用道具 舉報

ID:640671 發(fā)表于 2019-11-12 21:17 | 顯示全部樓層
IT0默認(rèn)為0,上升沿中斷,下降沿也中斷,你所說的中斷一次實(shí)際上是觸發(fā)了兩次中斷,產(chǎn)生兩個流水燈現(xiàn)象沒毛病。
回復(fù)

使用道具 舉報

ID:637250 發(fā)表于 2019-11-12 21:54 | 顯示全部樓層
可以的,實(shí)在不知道,就試試嘛
回復(fù)

使用道具 舉報

ID:97424 發(fā)表于 2019-11-12 22:46 | 顯示全部樓層
可以的
回復(fù)

使用道具 舉報

ID:245004 發(fā)表于 2019-11-12 22:46 | 顯示全部樓層
根據(jù)你的代碼原文稍作精簡和修飾,你可以試一下(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;
  }
}



回復(fù)

使用道具 舉報

ID:245004 發(fā)表于 2019-11-12 23:14 | 顯示全部樓層
當(dāng)?shù)谝淮瓮獠恐袛?執(zhí)行的時候,外部中斷請求位IE0會自動被清零,中斷之所以執(zhí)行兩遍,很顯然是當(dāng)執(zhí)行第一次中斷的過程中再次有信號觸發(fā)了中斷,所以第一遍執(zhí)行完依然存在中斷標(biāo)志,繼而執(zhí)行第二次中斷并清除已存在的請求標(biāo)志。為什么沒有第三次?因?yàn)檫@個觸發(fā)信號顯然在第一次觸發(fā)的時候發(fā)生的,正如樓上幾位朋友分析的,是因?yàn)槎秳又貜?fù)觸發(fā)。
在中斷函數(shù)最后一個大括號前加一句:“IE0 = 0;”人為清除中斷請求標(biāo)志。

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

回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

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

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

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