22.04.2010, autor: Ing. Robert Krejčí, kategorie: Konstrukce

Plynulé řízení jasu tříbarevné LED pomocí softwarové PWM

Jednoduchý příklad pro začátečníky v programovacím jazyce C

Ukážeme si zdrojový kód programu napsaného v jazyce C pro plynulé řízení jasu tříbarevné LED pomocí softwarové pulzně-šířkové modulace (PWM). Program je napsaný primárně pro mikrokontrolér Atmel AVR ATMega88, ale s drobnými úpravami ho lze použít i pro jinou hardwarovou architekturu.

/*********************************************************************
Plynula zmena jasu LED

Jednoduchy program pro rizeni jasu LED pomoci softwarove PWM
**********************************************************************/

#if defined(__AVR__) // detekce AVR
  #define F_CPU 1000000UL // frekvence krystalu
  #include <avr/io.h> // zde je definovan napr. PORTB
  #include <avr/iom88.h> // konstanty pro konkretni typ mikrokontroleru
#else
  // includes pro jine architektury
#endif


// vystupni piny: na ktere vyvody portu B jsou pripojeny anody tribarevne LED
#define bitR 3
#define bitB 4
#define bitG 5

// po jakem intrvalu dojde ke zmene
#define tmrIntervalR 255
#define tmrIntervalG 220
#define tmrIntervalB 200

// rychlost zmeny
#define tmrSpeed 4

// rozsahy barev
#define pwmLimitR 255 // plny rozsah
#define pwmLimitG 255 // plny rozsah
#define pwmLimitB 100 // aby modra nesvitila moc

// makra pro operace s bity
#define mSetBit(a,bit) (a) |= (1<<(bit))
#define mClrBit(a,bit) (a) &= ~(1<<(bit))

/*
Hlavni program
*/
int main (void){ // hlavni funkce programu
  unsigned char pwm=0, r=128, g=64, b=0;
  unsigned char dirR=1, dirG=1, dirB=1;
  unsigned char tmrL=0, tmrH=0;

  /* init */
  DDRB=0xFF; // Data Direction Register PORTB: kazda nozicka bude vystup

  /* hlavni smycka */
  while(1){ // nekonecna smycka
    /* PWM */
    // red
    if(pwm<r){
      mSetBit(PORTB,bitR);
    }
    else{
      mClrBit(PORTB,bitR);
    }

    // green
    if(pwm<g){
      mSetBit(PORTB,bitG);
    }
    else{
      mClrBit(PORTB,bitG);
    }

    // blue
    if(pwm<b){
      mSetBit(PORTB,bitB);
    }
    else{
      mClrBit(PORTB,bitB);
    }

    // citac PWM se inkrementuje pri kazdem pruchodu
    pwm++;


    /* zmena jasu */
    // red
    if(tmrL == tmrIntervalR){
      if(r==0){dirR=1;}
      else if(r==pwmLimitR){dirR=0;}

      if(dirR){r++;}
      else{r--;}
    }

    // green
    if(tmrL == tmrIntervalG){
      if(g==0){dirG=1;}
      else if(g==pwmLimitG){dirG=0;}

      if(dirG){g++;}
      else{g--;}
    }

    // blue
    if(tmrL == tmrIntervalB){
      if(b==0){dirB=1;}
      else if(b==pwmLimitB){dirB=0;}

      if(dirB){b++;}
      else{b--;}
    }

    // inkrementace casovace zmeny
    if(tmrH++ > tmrSpeed){
      tmrH=0;
      tmrL++;
    }
  } // konec nekonecne smycky
} // konec main

Program můžete jednoduše překopírovat do AVR studia a zkompilovat. Pak ho nahrajte do mikroprocesoru a pozorujte plynulou změnu jasu.

Pozor: LEDku musíte připojit k vývodům mikrokontroléru přes odpory 300 ohmů! Jinak pravděpodobně dojde ke zničení výstupních obvodů mikrokontroléru nebo ke spálení LEDky příliš velkým proudem.

 
{e_like}
 
 
Nahoru