找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

一道單片機題,控制兩個LED燈輪流亮滅,求大佬給個大致算法

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:417624 發(fā)表于 2018-10-29 23:08 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
要求實現(xiàn)以下要求:(STC89C51單片機板子)
1.控制兩個LED燈輪流亮滅;
2.初始設(shè)定A燈與B燈等時間亮滅,A燈點亮?xí)r間+B燈點亮?xí)r間=1s;
3.隨后A燈點亮?xí)r間逐漸增加,B燈點亮?xí)r間逐漸減少,當B燈點亮?xí)r間小于某一闕值時,B燈點亮?xí)r間增加,同時A燈減少。(每次修改的步進為100ms,門闕值指定為100ms)如此循環(huán);
4.定時器隨意,模式隨意,盡量不用中斷

本人小白,沒學(xué)幾天,資質(zhì)平庸,剛了一個下午實在想不出,缺一個基本思路,求大佬指教


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

使用道具 舉報

沙發(fā)
ID:94031 發(fā)表于 2018-10-30 08:32 | 只看該作者
will(1)
{
if(dir==0) {
    A燈點亮
    延時m秒
    B燈點亮
    延時1-m秒
   m=m+0.1;
   if(m>1){m=1;dir=1}
  }
else
{
    A燈點亮
    延時m秒
    B燈點亮
    延時1-m秒
    m=m-0.1;
   if(m==0){m=0;dir=0}
  }


}


回復(fù)

使用道具 舉報

板凳
ID:320306 發(fā)表于 2018-10-30 08:43 | 只看該作者
就是A加B等于1S,A的時間到900MS之后,就減小,每次100MS,到100MS之后就增加,不用管B,B就等于1S-A的時間。
回復(fù)

使用道具 舉報

地板
ID:41713 發(fā)表于 2018-10-30 08:48 | 只看該作者
用定時器吧,根據(jù)晶振,用STC自帶的軟件算一下初值,還有一個系統(tǒng)的累加計算你要的闕值,判斷一下就OK的。具體程序自己想吧,初學(xué)者要學(xué)會一個功能一個功能的去試,人中找到成就感,并逐步提高。
回復(fù)

使用道具 舉報

5#
ID:415338 發(fā)表于 2018-10-30 08:52 | 只看該作者
我覺得簡單一點,直接使用if   else再加幾個延時就OK了,用定時器的話,外加中斷,在中斷還是用if else,中斷蠻簡單的,一一對應(yīng)就行
回復(fù)

使用道具 舉報

6#
ID:308437 發(fā)表于 2018-10-30 09:05 | 只看該作者
你這個定時器都可以不用,A和B都用一個延時函數(shù)就可以了。時間改變就是改延時函數(shù)的變量
回復(fù)

使用道具 舉報

7#
ID:417736 發(fā)表于 2018-10-30 09:30 | 只看該作者
B燈 1S減一次 ,減到 100后 ,下一秒開始增加,A燈減少
回復(fù)

使用道具 舉報

8#
ID:417727 發(fā)表于 2018-10-30 09:30 | 只看該作者
延時函數(shù)就可以了
回復(fù)

使用道具 舉報

9#
ID:276663 發(fā)表于 2018-10-30 09:36 | 只看該作者
  1. //首先你做一個延時函數(shù)
  2. void delay_1ms(void);
  3. //然后做一個延時函數(shù)
  4. void delay_Nms(unsigned int Value)
  5. {
  6.     while(Value--)delay_1ms();
  7. }

  8. //定義時間變量
  9. unsigned int TimeA=20;
  10. unsigned int TimeB=1000-TimeA;
  11. //定義方向變量
  12. unsigned char Direction = 1;
  13. //然后在主循環(huán)里就可以。
  14. while(1)
  15. {
  16.     if(Direction)        // LEDA時間增加
  17.     {           
  18.                 TimeA++;
  19.                 TimeB = 1000-TimeA;
  20.                 if (TimeA>=980)
  21.                 {
  22.                         Direction = 0;
  23.                 }
  24.     }
  25.     else                        // LEDA時間減少   
  26.     {
  27.             TimeA--;
  28.             TimeB = 1000-TimeA;
  29.             if (TimeA <=20)
  30.             {
  31.                     Direction = 1;                   
  32.             }
  33.     }
  34.     LEDA = 0; LEDB = 1;        // A燈亮B燈滅
  35.     delay_Nms(TimeA);
  36.     LEDA = 1; LEDB = 0;        // A燈滅B燈亮
  37.     delay_Nms(TimeB);
  38. }
復(fù)制代碼
回復(fù)

使用道具 舉報

10#
ID:276663 發(fā)表于 2018-10-30 09:36 | 只看該作者
我程序里面寫的是步進1ms應(yīng)該能看懂吧
回復(fù)

使用道具 舉報

11#
ID:417624 發(fā)表于 2018-10-30 10:55 來自觸屏版 | 只看該作者
IdeaMing 發(fā)表于 2018-10-30 09:36

老哥,延時函數(shù)看懂了,但我主要想練一下定時器,如果用定時器的話,應(yīng)該怎么寫呢?(    )
回復(fù)

使用道具 舉報

12#
ID:417624 發(fā)表于 2018-10-30 10:57 來自觸屏版 | 只看該作者
zsyzdx 發(fā)表于 2018-10-30 08:43
就是A加B等于1S,A的時間到900MS之后,就減小,每次100MS,到100MS之后就增加,不用管B,B就等于1S-A的時間 ...

判斷條件怎么設(shè)置?(((//Д//)))
回復(fù)

使用道具 舉報

13#
ID:225048 發(fā)表于 2018-10-30 11:23 | 只看該作者
最簡單的就是加個延時
回復(fù)

使用道具 舉報

14#
ID:225048 發(fā)表于 2018-10-30 11:23 | 只看該作者
加個延時就好了
回復(fù)

使用道具 舉報

15#
ID:417841 發(fā)表于 2018-10-30 11:39 | 只看該作者
will(1)
{
if(dir==0) {
    A燈點亮
    延時m秒
    B燈點亮
    延時1-m秒
   m=m+0.1;
   if(m>1){m=1;dir=1}
  }
else
{
    A燈點亮
    延時m秒
    B燈點亮
    延時1-m秒
    m=m-0.1;
   if(m==0){m=0;dir=0}
  }


}
回復(fù)

使用道具 舉報

16#
ID:417914 發(fā)表于 2018-10-30 15:01 | 只看該作者
如果只是單純的實現(xiàn)題目要求的話,用延時函數(shù)就可以,用方法的話還是用學(xué)一下定時器中斷計時
回復(fù)

使用道具 舉報

17#
ID:410942 發(fā)表于 2018-10-30 17:06 | 只看該作者
你或者參照pwm這個程序,然后改改參數(shù)CYCLE=600的數(shù)值。應(yīng)該可以的。
/*-----------------------------------------------

------------------------------------------------*/
#include<reg52.h> //包含頭文件,一般情況不需要改動,頭文件包含特殊功能寄存器的定義

sbit LED0=P1^0;// 用sbit 關(guān)鍵字 定義 LED到P1.0端口,LED是自己任意定義且容易記憶的符號
sbit LED1=P1^1;

void Delay(unsigned int t); //函數(shù)聲明
/*------------------------------------------------
                    主函數(shù)
------------------------------------------------*/
void main (void)
{
                  
unsigned int CYCLE=600,PWM_LOW=0;//定義周期并賦值
while (1)         //主循環(huán)
  {
LED0=1;
Delay(60000);        //特意加延時,可以看到熄滅的過程
for(PWM_LOW=1;PWM_LOW<CYCLE;PWM_LOW++){ //PWM_LOW表示低
//電平時間,這個循環(huán)中低電平時長從1累加到CYCLE(周期)的值,即600次

                   LED0=0;        //點亮LED  
                   Delay(PWM_LOW);//延時長度,600次循環(huán)中從1加至599
                   LED1=1;        //熄滅LED
              Delay(CYCLE-PWM_LOW);//延時長度,600次循環(huán)中從599減至1
     
   }
LED0=0;
for(PWM_LOW=CYCLE-1;PWM_LOW>0;PWM_LOW--){ //與逐漸變亮相反的過程

                   LED1=0;
                   Delay(PWM_LOW);
                   LED0=1;
              Delay(CYCLE-PWM_LOW);
     
   }
                     //主循環(huán)中添加其他需要一直工作的程序
  }
}
/*------------------------------------------------
延時函數(shù),含有輸入?yún)?shù) unsigned int t,無返回值
unsigned int 是定義無符號整形變量,其值的范圍是
0~65535
------------------------------------------------*/
void Delay(unsigned int t)
{
while(--t);
}
回復(fù)

使用道具 舉報

18#
ID:417624 發(fā)表于 2018-10-30 18:02 | 只看該作者
這是我編的程序,感覺挺對的,但實際卻是兩個燈閃爍時間一樣,為什么。
#include<reg51.h>
#include<stdio.h>

sbit ledA=P2^0;
sbit ledB=P2^1;
typedef unsigned int u16;
typedef unsigned char u8;


void main()
{
u16 i=0;
u16 b=2000;
u16 c=0;
   ledA=0;
   ledB=1;
   TMOD|=0X02;  //工作方式2
   TH0=0X06;        //0.25ms一次
   TL0=0X06;
   TR0=1;
   
           while(1){       
        if(TF0==1)
         {
          TF0=0;
          i++;}

                  while(b<4000){       
                if(i==b){
                i=0;
                ledA=~ledA;
                ledB=~ledB;               
                }
                if(i==4000-b){
                 ledA=~ledA;
                ledB=~ledB;
                i=0;               
                }
                b=b+400;          
        }
         b=b-800;
                   while(b>0){
                 if(i==b) {
                                         i=0;
                ledA=~ledA;
                ledB=~ledB;
               
                }
                if(i==4000-b){
                 ledA=~ledA;
                ledB=~ledB;
                i=0;
                 }
                 b=b-400;
                 } b=b+800;}           }
                        
回復(fù)

使用道具 舉報

19#
ID:418122 發(fā)表于 2018-10-30 19:46 | 只看該作者
用個延時函數(shù),在while循環(huán)里先點亮再延時再滅掉延時
回復(fù)

使用道具 舉報

20#
ID:418171 發(fā)表于 2018-10-30 21:10 | 只看該作者
可以參考SPWM波的程序吧
回復(fù)

使用道具 舉報

21#
ID:276663 發(fā)表于 2018-10-31 09:43 | 只看該作者
y352715553 發(fā)表于 2018-10-30 10:55
老哥,延時函數(shù)看懂了,但我主要想練一下定時器,如果用定時器的話,應(yīng)該怎么寫呢?(    )

你能不能別眼高手低,就用延時的你實現(xiàn)了嗎?
然后,你條件里寫了,定時器隨意。大家都覺得用延時函數(shù)就行了。
定時器的話就是把延時用定時器處理。
回復(fù)

使用道具 舉報

22#
ID:417624 發(fā)表于 2018-10-31 12:41 | 只看該作者
IdeaMing 發(fā)表于 2018-10-31 09:43
你能不能別眼高手低,就用延時的你實現(xiàn)了嗎?
然后,你條件里寫了,定時器隨意。大家都覺得用延時函數(shù)就 ...

很抱歉,老哥,是我表意不明,我說的定時器隨意是定時器1或定時器0都行,我也不是眼高手低,延時函數(shù)的程序我之前就已經(jīng)編過了。。。
回復(fù)

使用道具 舉報

23#
ID:375201 發(fā)表于 2018-10-31 13:25 | 只看該作者
加個延時
回復(fù)

使用道具 舉報

24#
ID:89515 發(fā)表于 2018-10-31 15:32 | 只看該作者
y352715553 發(fā)表于 2018-10-30 18:02
這是我編的程序,感覺挺對的,但實際卻是兩個燈閃爍時間一樣,為什么。
#include
#include

你用查詢的方式,那用定時器還有什么意義。……用中斷,在中斷函數(shù)里設(shè)定你需要的單位時間,然后在主函數(shù)里更改你需要的時間值。但是你的led兩個狀態(tài)時間值不一樣,所以必須分開,if-else語句就可以了,在里面設(shè)定不同的時間值,并設(shè)定一個交替執(zhí)行的標志就可以。大家都叫你用軟件延時函數(shù),因為那樣更好理解,而且你這個確實沒必要,也沒有意義。表面上看起來像模擬PWM,實際上又不是,所以………………
回復(fù)

使用道具 舉報

25#
ID:418559 發(fā)表于 2018-10-31 15:41 | 只看該作者
加個延時函數(shù)
回復(fù)

使用道具 舉報

26#
ID:417624 發(fā)表于 2018-11-2 12:27 | 只看該作者
#include <reg51.h>
#include<math.h>
typedef unsigned int u16;          
typedef unsigned char u8;

sbit led1=P2^0;
sbit led2=P2^1;
u16 b=2000;
u16 shuZu;
u16 ciShu=0;
u16 k;
u16 text[]={0,1,2,3,4,5,6,7,8,7,6,5,4,3,2,1,0,(-1),(-2),(-3),(-4),(-5),(-6),(-7),(-8),(-7),(-6),(-5),(-4),(-3),(-2),(-1)};
void InitTimer0(void)
{
TMOD = 0x02;
TH0 = 0x06;
TL0 = 0x06;//0.25ms中斷
EA = 1;
ET0 = 1;
TR0 = 1;
}

void main(void)
{
led1=0;
led2=1;
InitTimer0();
while(1);
}
void Timer0Interrupt(void) interrupt 1
{static int i=0;

i++;
if(i==b)
{led1=~led1;
led2=~led2;
i=0;

shuZu=ciShu%32;
k=text[shuZu];
b=b+pow((-1),(ciShu+1))*400*k;
ciShu++;

}
}

終于跑出來了,雖然用了中斷。。
回復(fù)

使用道具 舉報

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

本版積分規(guī)則

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

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

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