久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4521|回復: 8
收起左側

關于單片機中斷函數與while()程序執行的問題

[復制鏈接]
ID:482529 發表于 2019-3-1 18:08 | 顯示全部樓層 |閱讀模式
請教為何while(j<10)時,LED燈正常閃爍5次,但是將while(j<10)改成while(j<5),LED燈進入無限閃爍狀態?我本以為燈會閃爍2次。
  1. /*************************************************
  2. *實驗名:定時器實驗
  3. *實驗效果:第一個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; //定時器1選擇工作方式1
  12.         TH1 = 0x4C;  //設置初始值,定時50ms
  13.         TL1 = 0x00;
  14.         EA = 1;      //打開總中斷
  15.         ET1 = 1;     //打開定時器1中斷
  16.         TR1 = 1;     //啟動定時器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;         //設置初始值,定時50ms
  35.         TL1 = 0x00;  
  36.         i++;
  37.                
  38.         
  39.                         }
復制代碼



回復

使用道具 舉報

ID:345680 發表于 2019-3-1 19:49 | 顯示全部樓層
單片機編程不能這樣子吧,要加上while(1),否則會出錯,你這樣子改一下行不行
void main()
{
        led = 0;
        timer1_init();
       while(1)
      {
        while(j<10)
        {
                        if(i>=10)
                        {i=0;
                        led = ~led;
                                                j++;
                                                }
                }
      
}
}
回復

使用道具 舉報

ID:482529 發表于 2019-3-1 20:04 | 顯示全部樓層
aux123456789 發表于 2019-3-1 19:49
單片機編程不能這樣子吧,要加上while(1),否則會出錯,你這樣子改一下行不行
void main()
{

按照你說的試了一下,仍然是無限循環閃爍。不知其所以然。。。
回復

使用道具 舉報

ID:482430 發表于 2019-3-1 22:40 | 顯示全部樓層
個人感覺用不到j,同時,作為類似全局的計數器,用i,j來命名,也不合適。
試試這樣寫:

#include<reg52.h>

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

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

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

        while(1)
        {
                ;
        }
}

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

使用道具 舉報

ID:482430 發表于 2019-3-1 23:03 | 顯示全部樓層
不好意思,一開始沒注意你的要求。
你的要求,是程序開始后,只閃爍固定的次數,代碼應該這樣寫:

#include<reg52.h>

#define                FLASH_MAX_COUNT                5        //最大閃爍次數

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

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

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

        while(1)
        {
                ;
        }
}

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

這樣,你可以通過調整FLASH_MAX_COUNT的值,控制你實際希望led燈以500ms的間隔,閃爍幾次。
回復

使用道具 舉報

ID:346616 發表于 2019-3-1 23:56 | 顯示全部樓層
程序有問題,正常情況你這個程序會不停的來回執行main(),不管是j<10還是j<5都會無限閃爍。
還有請你明白j為什么用while循環10次,這個10指的是10次狀態的改變,滅是一個狀態,亮是一個狀態,閃爍5次就等于亮滅5次,一共是10次狀態改變。
所以你要閃兩次,應該改成j<4。
下面那個i循環指的是一次50ms,循環10次500ms.
程序解決辦法,可以按照你樓上的辦法,也可以在下面加一句,使語句停留,避免無限執行main()

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

評分

參與人數 1黑幣 +80 收起 理由
admin + 80 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

ID:469932 發表于 2019-3-2 00:48 | 顯示全部樓層
代碼沒問題,是你觀察不仔細,while(j<5)是三次,如果想看清楚,你用一下下面的代碼與仿真

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

void timer1_init()
{
        TMOD = 0x10; //定時器1選擇工作方式1
        TH1 = 0x4C;  //設置初始值,定時50ms
        TL1 = 0x00;
        EA =  1;      //打開總中斷
        ET1 = 1;     //打開定時器1中斷
        TR1 = 1;     //啟動定時器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;         //設置初始值,定時50ms
        TL1 = 0x00;  
        i++;       
}
回復

使用道具 舉報

ID:482529 發表于 2019-3-2 16:57 | 顯示全部樓層
boswell1983 發表于 2019-3-1 23:03
不好意思,一開始沒注意你的要求。
你的要求,是程序開始后,只閃爍固定的次數,代碼應該這樣寫:

謝謝回復。
我的問題是以下代碼在調試后出現以下情況:
while(j<9)中的 j改成小于9以下的7,5則出現循環閃爍現象,而當 j取大于9的奇數,如11,13。。。2n+1都能正常按照預設閃爍 n次,且n>=5.
我使用的單片機是STC89C52,這會不會與單片機內部運行機制相關?
  1. /*************************************************
  2. *實驗名:定時器實驗
  3. *實驗效果:第一個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; //定時器1選擇工作方式1
  12.     TH1 = 0x4C;  //設置初始值,定時50ms
  13.     TL1 = 0x00;
  14.     EA = 1;  //打開總中斷
  15.     ET1 = 1; //打開定時器1中斷
  16.     TR1 = 1; //啟動定時器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; //設置初始值,定時50ms
  35.     TL1 = 0x00;
  36.     i++;
  37. }
復制代碼
回復

使用道具 舉報

ID:482430 發表于 2019-3-2 19:51 | 顯示全部樓層
51童小白 發表于 2019-3-2 16:57
謝謝回復。
我的問題是以下代碼在調試后出現以下情況:
while(j=5.

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

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

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久久久激情 | 成人在线观看亚洲 | 国产91网址 | 欧美一级在线观看 | 亚洲午夜视频 | 欧美一级二级视频 | 亚洲夜射| 亚洲精品日韩视频 | h片在线看 | 国产一区二区久久久 | 欧美成人一区二免费视频软件 | 欧美一级欧美三级在线观看 | 狠狠插天天干 | 欧美激情视频一区二区三区在线播放 | 欧美一区二区三区在线观看 | 国产日韩欧美精品一区二区三区 | 狠狠做六月爱婷婷综合aⅴ 国产精品视频网 | 男人电影天堂 | h视频在线播放 | 国产在线永久免费 | 天天干狠狠操 | 亚洲精品福利在线 | 一区二区三区小视频 | 国产日韩久久久久69影院 | 岛国在线免费观看 | 欧美亚洲国产一区二区三区 | 久久久91精品国产一区二区精品 | 久久久久国产一区二区三区四区 | 好姑娘影视在线观看高清 | 中文字幕亚洲欧美日韩在线不卡 | 草久在线| 中文字幕 国产 | 妖精视频一区二区三区 | 九九九精品视频 | 日韩欧美不卡 | 久久丁香 | 国产亚韩 | 在线欧美激情 | 欧美日高清 | www.黄色在线观看 | 久久中文一区二区 |