找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 4503|回復(fù): 8
打印 上一主題 下一主題
收起左側(cè)

關(guān)于單片機(jī)中斷函數(shù)與while()程序執(zhí)行的問題

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:482529 發(fā)表于 2019-3-1 18:08 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
請(qǐng)教為何while(j<10)時(shí),LED燈正常閃爍5次,但是將while(j<10)改成while(j<5),LED燈進(jìn)入無限閃爍狀態(tài)?我本以為燈會(huì)閃爍2次。
  1. /*************************************************
  2. *實(shí)驗(yàn)名:定時(shí)器實(shí)驗(yàn)
  3. *實(shí)驗(yàn)效果:第一個(gè)led燈以500ms一次的精確頻率閃爍,共閃爍5次;

  4. *************************************************/
  5. #include<reg52.h>

  6. sbit led = P1^6;
  7. int i = 0;
  8. int j=0;

  9. void timer1_init()
  10. {
  11.         TMOD = 0x10; //定時(shí)器1選擇工作方式1
  12.         TH1 = 0x4C;  //設(shè)置初始值,定時(shí)50ms
  13.         TL1 = 0x00;
  14.         EA = 1;      //打開總中斷
  15.         ET1 = 1;     //打開定時(shí)器1中斷
  16.         TR1 = 1;     //啟動(dòng)定時(shí)器1
  17. }

  18. void main()
  19. {
  20.         led = 0;
  21.         timer1_init();
  22.         while(j<10)
  23.         {
  24.                         if(i>=10)
  25.                         {i=0;
  26.                         led = ~led;
  27.                                                 j++;
  28.                                                 }
  29.                 }
  30.       
  31. }

  32. void timer1() interrupt 3
  33. {
  34.           TH1 = 0x4C;         //設(shè)置初始值,定時(shí)50ms
  35.         TL1 = 0x00;  
  36.         i++;
  37.                
  38.         
  39.                         }
復(fù)制代碼



分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:345680 發(fā)表于 2019-3-1 19:49 | 只看該作者
單片機(jī)編程不能這樣子吧,要加上while(1),否則會(huì)出錯(cuò),你這樣子改一下行不行
void main()
{
        led = 0;
        timer1_init();
       while(1)
      {
        while(j<10)
        {
                        if(i>=10)
                        {i=0;
                        led = ~led;
                                                j++;
                                                }
                }
      
}
}
回復(fù)

使用道具 舉報(bào)

板凳
ID:482529 發(fā)表于 2019-3-1 20:04 | 只看該作者
aux123456789 發(fā)表于 2019-3-1 19:49
單片機(jī)編程不能這樣子吧,要加上while(1),否則會(huì)出錯(cuò),你這樣子改一下行不行
void main()
{

按照你說的試了一下,仍然是無限循環(huán)閃爍。不知其所以然。。。
回復(fù)

使用道具 舉報(bào)

地板
ID:482430 發(fā)表于 2019-3-1 22:40 | 只看該作者
個(gè)人感覺用不到j(luò),同時(shí),作為類似全局的計(jì)數(shù)器,用i,j來命名,也不合適。
試試這樣寫:

#include<reg52.h>

sbit led = P1^6;
int count = 0;

void timer1_init()
{
        TMOD = 0x10; //定時(shí)器1選擇工作方式1
        TH1 = 0x4C;  //設(shè)置初始值,定時(shí)50ms
        TL1 = 0x00;
        EA = 1;      //打開總中斷
        ET1 = 1;     //打開定時(shí)器1中斷
        TR1 = 1;     //啟動(dòng)定時(shí)器1
}

void main()
{
        led = 0;
        count=0;
        timer1_init();

        while(1)
        {
                ;
        }
}

void timer1() interrupt 3
{
        TH1 = 0x4C;         //設(shè)置初始值,定時(shí)50ms
        TL1 = 0x00;  
        count++;
        if(count>=10)
        {
                count=0;
                led = ~led;
        }
}
回復(fù)

使用道具 舉報(bào)

5#
ID:482430 發(fā)表于 2019-3-1 23:03 | 只看該作者
不好意思,一開始沒注意你的要求。
你的要求,是程序開始后,只閃爍固定的次數(shù),代碼應(yīng)該這樣寫:

#include<reg52.h>

#define                FLASH_MAX_COUNT                5        //最大閃爍次數(shù)

sbit led = P1^6;
int count = 0;
int flashCount = 0;                //閃爍次數(shù)

void timer1_init()
{
        TMOD = 0x10; //定時(shí)器1選擇工作方式1
        TH1 = 0x4C;  //設(shè)置初始值,定時(shí)50ms
        TL1 = 0x00;
        EA = 1;      //打開總中斷
        ET1 = 1;     //打開定時(shí)器1中斷
        TR1 = 1;     //啟動(dòng)定時(shí)器1
}

void main()
{
        led = 0;
        flashCount=0;
        timer1_init();

        while(1)
        {
                ;
        }
}

void timer1() interrupt 3
{
        TH1 = 0x4C;         //設(shè)置初始值,定時(shí)50ms
        TL1 = 0x00;  
        count++;
        if(count>=10)
        {
                count=0;
                if(flashCount<FLASH_MAX_COUNT)
                {
                        led = ~led;
                        flashCount++;
                }               
        }
}

這樣,你可以通過調(diào)整FLASH_MAX_COUNT的值,控制你實(shí)際希望led燈以500ms的間隔,閃爍幾次。
回復(fù)

使用道具 舉報(bào)

6#
ID:346616 發(fā)表于 2019-3-1 23:56 | 只看該作者
程序有問題,正常情況你這個(gè)程序會(huì)不停的來回執(zhí)行main(),不管是j<10還是j<5都會(huì)無限閃爍。
還有請(qǐng)你明白j為什么用while循環(huán)10次,這個(gè)10指的是10次狀態(tài)的改變,滅是一個(gè)狀態(tài),亮是一個(gè)狀態(tài),閃爍5次就等于亮滅5次,一共是10次狀態(tài)改變。
所以你要閃兩次,應(yīng)該改成j<4。
下面那個(gè)i循環(huán)指的是一次50ms,循環(huán)10次500ms.
程序解決辦法,可以按照你樓上的辦法,也可以在下面加一句,使語句停留,避免無限執(zhí)行main()

void main()
{
        led = 0;
        timer1_init();
        while(j<10)
        {
                        if(i>=10)
                        {i=0;
                        led = ~led;
                                                j++;
                                                }
                }
       while(1);
}

評(píng)分

參與人數(shù) 1黑幣 +80 收起 理由
admin + 80 回帖助人的獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

7#
ID:469932 發(fā)表于 2019-3-2 00:48 | 只看該作者
代碼沒問題,是你觀察不仔細(xì),while(j<5)是三次,如果想看清楚,你用一下下面的代碼與仿真

001.rar (15.87 KB, 下載次數(shù): 6)
#include<reg52.h>
sbit led = P1^6;
int i = 0;
int j = 0;

void timer1_init()
{
        TMOD = 0x10; //定時(shí)器1選擇工作方式1
        TH1 = 0x4C;  //設(shè)置初始值,定時(shí)50ms
        TL1 = 0x00;
        EA =  1;      //打開總中斷
        ET1 = 1;     //打開定時(shí)器1中斷
        TR1 = 1;     //啟動(dòng)定時(shí)器1
}

void main()
{
        led = 0;

        timer1_init();

        while(j<5)
        {
                if(i>=10)
                {
                i=0;
                led = ~led;
                j++;
         
                }
       
        }
                while(1) ;
       
}

void timer1() interrupt 3
{
        TH1 = 0x4C;         //設(shè)置初始值,定時(shí)50ms
        TL1 = 0x00;  
        i++;       
}
回復(fù)

使用道具 舉報(bào)

8#
ID:482529 發(fā)表于 2019-3-2 16:57 | 只看該作者
boswell1983 發(fā)表于 2019-3-1 23:03
不好意思,一開始沒注意你的要求。
你的要求,是程序開始后,只閃爍固定的次數(shù),代碼應(yīng)該這樣寫:

謝謝回復(fù)。
我的問題是以下代碼在調(diào)試后出現(xiàn)以下情況:
while(j<9)中的 j改成小于9以下的7,5則出現(xiàn)循環(huán)閃爍現(xiàn)象,而當(dāng) j取大于9的奇數(shù),如11,13。。。2n+1都能正常按照預(yù)設(shè)閃爍 n次,且n>=5.
我使用的單片機(jī)是STC89C52,這會(huì)不會(huì)與單片機(jī)內(nèi)部運(yùn)行機(jī)制相關(guān)?
  1. /*************************************************
  2. *實(shí)驗(yàn)名:定時(shí)器實(shí)驗(yàn)
  3. *實(shí)驗(yàn)效果:第一個(gè)led燈以500ms一次的精確頻率閃爍,共閃爍5次;

  4. *************************************************/
  5. #include <reg52.h>

  6. sbit led = P1 ^ 6;
  7. int i = 0;
  8. int j = 0;

  9. void timer1_init()
  10. {
  11.     TMOD = 0x10; //定時(shí)器1選擇工作方式1
  12.     TH1 = 0x4C;  //設(shè)置初始值,定時(shí)50ms
  13.     TL1 = 0x00;
  14.     EA = 1;  //打開總中斷
  15.     ET1 = 1; //打開定時(shí)器1中斷
  16.     TR1 = 1; //啟動(dòng)定時(shí)器1
  17. }

  18. void main()
  19. {
  20.     led = 0;
  21.     timer1_init();
  22.     while (j < 9)
  23.     {
  24.         if (i >= 10)
  25.         {
  26.             i = 0;
  27.             led = ~led;
  28.             j++;
  29.         }
  30.     }
  31. }

  32. void timer1() interrupt 3
  33. {
  34.     TH1 = 0x4C; //設(shè)置初始值,定時(shí)50ms
  35.     TL1 = 0x00;
  36.     i++;
  37. }
復(fù)制代碼
回復(fù)

使用道具 舉報(bào)

9#
ID:482430 發(fā)表于 2019-3-2 19:51 | 只看該作者
51童小白 發(fā)表于 2019-3-2 16:57
謝謝回復(fù)。
我的問題是以下代碼在調(diào)試后出現(xiàn)以下情況:
while(j=5.

我覺得你現(xiàn)在出現(xiàn)這種無法解釋的情況,應(yīng)該是程序邏輯沒理清楚。建議不要太鉆牛角尖。
你可以自己把你原來的程序,主循環(huán),寫一個(gè)程序流程圖;中斷寫一個(gè)程序流程圖。然后自己分析問題出在哪里,這樣收貨會(huì)更大。

正常的單片機(jī)程序編寫,主循環(huán)根本不用參與控制led燈這類事情。
一般控制led燈的閃爍,都是在定時(shí)器中斷里完成的。
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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