標(biāo)題: 一道單片機(jī)題,控制兩個(gè)LED燈輪流亮滅,求大佬給個(gè)大致算法 [打印本頁(yè)]

作者: y352715553    時(shí)間: 2018-10-29 23:08
標(biāo)題: 一道單片機(jī)題,控制兩個(gè)LED燈輪流亮滅,求大佬給個(gè)大致算法
要求實(shí)現(xiàn)以下要求:(STC89C51單片機(jī)板子)
1.控制兩個(gè)LED燈輪流亮滅;
2.初始設(shè)定A燈與B燈等時(shí)間亮滅,A燈點(diǎn)亮?xí)r間+B燈點(diǎn)亮?xí)r間=1s;
3.隨后A燈點(diǎn)亮?xí)r間逐漸增加,B燈點(diǎn)亮?xí)r間逐漸減少,當(dāng)B燈點(diǎn)亮?xí)r間小于某一闕值時(shí),B燈點(diǎn)亮?xí)r間增加,同時(shí)A燈減少。(每次修改的步進(jìn)為100ms,門(mén)闕值指定為100ms)如此循環(huán);
4.定時(shí)器隨意,模式隨意,盡量不用中斷

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



作者: xuyaqi    時(shí)間: 2018-10-30 08:32
will(1)
{
if(dir==0) {
    A燈點(diǎn)亮
    延時(shí)m秒
    B燈點(diǎn)亮
    延時(shí)1-m秒
   m=m+0.1;
   if(m>1){m=1;dir=1}
  }
else
{
    A燈點(diǎn)亮
    延時(shí)m秒
    B燈點(diǎn)亮
    延時(shí)1-m秒
    m=m-0.1;
   if(m==0){m=0;dir=0}
  }


}



作者: zsyzdx    時(shí)間: 2018-10-30 08:43
就是A加B等于1S,A的時(shí)間到900MS之后,就減小,每次100MS,到100MS之后就增加,不用管B,B就等于1S-A的時(shí)間。
作者: dingddhh    時(shí)間: 2018-10-30 08:48
用定時(shí)器吧,根據(jù)晶振,用STC自帶的軟件算一下初值,還有一個(gè)系統(tǒng)的累加計(jì)算你要的闕值,判斷一下就OK的。具體程序自己想吧,初學(xué)者要學(xué)會(huì)一個(gè)功能一個(gè)功能的去試,人中找到成就感,并逐步提高。
作者: 遠(yuǎn)小劉    時(shí)間: 2018-10-30 08:52
我覺(jué)得簡(jiǎn)單一點(diǎn),直接使用if   else再加幾個(gè)延時(shí)就OK了,用定時(shí)器的話,外加中斷,在中斷還是用if else,中斷蠻簡(jiǎn)單的,一一對(duì)應(yīng)就行
作者: yousunny    時(shí)間: 2018-10-30 09:05
你這個(gè)定時(shí)器都可以不用,A和B都用一個(gè)延時(shí)函數(shù)就可以了。時(shí)間改變就是改延時(shí)函數(shù)的變量
作者: Apolo    時(shí)間: 2018-10-30 09:30
B燈 1S減一次 ,減到 100后 ,下一秒開(kāi)始增加,A燈減少
作者: zhaovan    時(shí)間: 2018-10-30 09:30
延時(shí)函數(shù)就可以了
作者: IdeaMing    時(shí)間: 2018-10-30 09:36
  1. //首先你做一個(gè)延時(shí)函數(shù)
  2. void delay_1ms(void);
  3. //然后做一個(gè)延時(shí)函數(shù)
  4. void delay_Nms(unsigned int Value)
  5. {
  6.     while(Value--)delay_1ms();
  7. }

  8. //定義時(shí)間變量
  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時(shí)間增加
  17.     {           
  18.                 TimeA++;
  19.                 TimeB = 1000-TimeA;
  20.                 if (TimeA>=980)
  21.                 {
  22.                         Direction = 0;
  23.                 }
  24.     }
  25.     else                        // LEDA時(shí)間減少   
  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ù)制代碼

作者: IdeaMing    時(shí)間: 2018-10-30 09:36
我程序里面寫(xiě)的是步進(jìn)1ms應(yīng)該能看懂吧
作者: y352715553    時(shí)間: 2018-10-30 10:55
IdeaMing 發(fā)表于 2018-10-30 09:36

老哥,延時(shí)函數(shù)看懂了,但我主要想練一下定時(shí)器,如果用定時(shí)器的話,應(yīng)該怎么寫(xiě)呢?(    )
作者: y352715553    時(shí)間: 2018-10-30 10:57
zsyzdx 發(fā)表于 2018-10-30 08:43
就是A加B等于1S,A的時(shí)間到900MS之后,就減小,每次100MS,到100MS之后就增加,不用管B,B就等于1S-A的時(shí)間 ...

判斷條件怎么設(shè)置?(((//Д//)))
作者: 路亦為天    時(shí)間: 2018-10-30 11:23
最簡(jiǎn)單的就是加個(gè)延時(shí)
作者: 路亦為天    時(shí)間: 2018-10-30 11:23
加個(gè)延時(shí)就好了

作者: czhml    時(shí)間: 2018-10-30 11:39
will(1)
{
if(dir==0) {
    A燈點(diǎn)亮
    延時(shí)m秒
    B燈點(diǎn)亮
    延時(shí)1-m秒
   m=m+0.1;
   if(m>1){m=1;dir=1}
  }
else
{
    A燈點(diǎn)亮
    延時(shí)m秒
    B燈點(diǎn)亮
    延時(shí)1-m秒
    m=m-0.1;
   if(m==0){m=0;dir=0}
  }


}

作者: 874152822    時(shí)間: 2018-10-30 15:01
如果只是單純的實(shí)現(xiàn)題目要求的話,用延時(shí)函數(shù)就可以,用方法的話還是用學(xué)一下定時(shí)器中斷計(jì)時(shí)
作者: hzh2008    時(shí)間: 2018-10-30 17:06
你或者參照pwm這個(gè)程序,然后改改參數(shù)CYCLE=600的數(shù)值。應(yīng)該可以的。
/*-----------------------------------------------

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

sbit LED0=P1^0;// 用sbit 關(guān)鍵字 定義 LED到P1.0端口,LED是自己任意定義且容易記憶的符號(hào)
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);        //特意加延時(shí),可以看到熄滅的過(guò)程
for(PWM_LOW=1;PWM_LOW<CYCLE;PWM_LOW++){ //PWM_LOW表示低
//電平時(shí)間,這個(gè)循環(huán)中低電平時(shí)長(zhǎng)從1累加到CYCLE(周期)的值,即600次

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

                   LED1=0;
                   Delay(PWM_LOW);
                   LED0=1;
              Delay(CYCLE-PWM_LOW);
     
   }
                     //主循環(huán)中添加其他需要一直工作的程序
  }
}
/*------------------------------------------------
延時(shí)函數(shù),含有輸入?yún)?shù) unsigned int t,無(wú)返回值
unsigned int 是定義無(wú)符號(hào)整形變量,其值的范圍是
0~65535
------------------------------------------------*/
void Delay(unsigned int t)
{
while(--t);
}
作者: y352715553    時(shí)間: 2018-10-30 18:02
這是我編的程序,感覺(jué)挺對(duì)的,但實(shí)際卻是兩個(gè)燈閃爍時(shí)間一樣,為什么?
#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;}           }
                        

作者: modal    時(shí)間: 2018-10-30 19:46
用個(gè)延時(shí)函數(shù),在while循環(huán)里先點(diǎn)亮再延時(shí)再滅掉延時(shí)
作者: SINILION    時(shí)間: 2018-10-30 21:10
可以參考SPWM波的程序吧
作者: IdeaMing    時(shí)間: 2018-10-31 09:43
y352715553 發(fā)表于 2018-10-30 10:55
老哥,延時(shí)函數(shù)看懂了,但我主要想練一下定時(shí)器,如果用定時(shí)器的話,應(yīng)該怎么寫(xiě)呢?(    )

你能不能別眼高手低,就用延時(shí)的你實(shí)現(xiàn)了嗎?
然后,你條件里寫(xiě)了,定時(shí)器隨意。大家都覺(jué)得用延時(shí)函數(shù)就行了。
定時(shí)器的話就是把延時(shí)用定時(shí)器處理。
作者: y352715553    時(shí)間: 2018-10-31 12:41
IdeaMing 發(fā)表于 2018-10-31 09:43
你能不能別眼高手低,就用延時(shí)的你實(shí)現(xiàn)了嗎?
然后,你條件里寫(xiě)了,定時(shí)器隨意。大家都覺(jué)得用延時(shí)函數(shù)就 ...

很抱歉,老哥,是我表意不明,我說(shuō)的定時(shí)器隨意是定時(shí)器1或定時(shí)器0都行,我也不是眼高手低,延時(shí)函數(shù)的程序我之前就已經(jīng)編過(guò)了。。。
作者: 849104803    時(shí)間: 2018-10-31 13:25
加個(gè)延時(shí)
作者: mengzhixinheng    時(shí)間: 2018-10-31 15:32
y352715553 發(fā)表于 2018-10-30 18:02
這是我編的程序,感覺(jué)挺對(duì)的,但實(shí)際卻是兩個(gè)燈閃爍時(shí)間一樣,為什么?
#include
#include

你用查詢的方式,那用定時(shí)器還有什么意義!弥袛,在中斷函數(shù)里設(shè)定你需要的單位時(shí)間,然后在主函數(shù)里更改你需要的時(shí)間值。但是你的led兩個(gè)狀態(tài)時(shí)間值不一樣,所以必須分開(kāi),if-else語(yǔ)句就可以了,在里面設(shè)定不同的時(shí)間值,并設(shè)定一個(gè)交替執(zhí)行的標(biāo)志就可以。大家都叫你用軟件延時(shí)函數(shù),因?yàn)槟菢痈美斫猓夷氵@個(gè)確實(shí)沒(méi)必要,也沒(méi)有意義。表面上看起來(lái)像模擬PWM,實(shí)際上又不是,所以………………
作者: 省略號(hào)    時(shí)間: 2018-10-31 15:41
加個(gè)延時(shí)函數(shù)
作者: y352715553    時(shí)間: 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++;

}
}

終于跑出來(lái)了,雖然用了中斷。。





歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1