Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

[PIC18] Led e PWM: facile, veloce e senza timers.

Raccolta di codici sorgenti

Moderatore: Foto UtentePaolino

0
voti

[11] Re: [PIC18] Led e PWM: facile, veloce e senza timers.

Messaggioda Foto UtenteTheMrLucas » 30 set 2010, 11:52

TardoFreak ha scritto:In questo programma c'e' la variabile pos_pwm che va da 0 a 255 e si incrementa ogni ciclo. Ci sono poi tre variabili (una per ogni LED) che contengono il valore del tempo Ton (quindi la luminosita). Ad ogni ciclo viene fatta una comparazione fra la pos_pwm e il livello di ogni LED. Se pos_pwm e' piu' piccola del livello l' uscita corrispondente viene messa a 1, se e' piu' grande viene messa a 0.


Quando avevo provato io, avevo messo come fisso il tempo off,e poi avevo fatto 3 delay con 3 variabili distinte che venivano decrementate in un ordine tale da "in teoria" avere la sfumatura di colori...vabbè alla fine non è mai andato nulla :lol:

Hai detto che ci sono 3 variabili, una per ogni Led, e che contengono il valore del tempo on, quindi questo valore è fisso o viene in qualche modo modificato?

Ora per provarlo devo trovare il modo di fare la comparazione in assembler :-k
Avatar utente
Foto UtenteTheMrLucas
0 1
 
Messaggi: 4
Iscritto il: 29 set 2010, 10:53

0
voti

[12] Re: [PIC18] Led e PWM: facile, veloce e senza timers.

Messaggioda Foto UtenteTardoFreak » 30 set 2010, 14:32

Modificando il valore delle variabili associate a LEDS si cambia il duty cycle e quindi si regola la luminosita'. Come farle variare e' compito dell' applicazione.
"La follia sta nel fare sempre la stessa cosa aspettandosi risultati diversi".
"Parla soltanto quando sei sicuro che quello che dirai è più bello del silenzio".
Rispondere è cortesia, ma lasciare l'ultima parola ai cretini è arte.
Avatar utente
Foto UtenteTardoFreak
73,9k 8 12 13
-EY Legend-
-EY Legend-
 
Messaggi: 15754
Iscritto il: 16 dic 2009, 11:10
Località: Torino - 3° pianeta del Sistema Solare

0
voti

[13] Re: [PIC18] Led e PWM: facile, veloce e senza timers.

Messaggioda Foto Utentealex79 » 5 giu 2012, 11:59

Ciao,
devo implementare un algoritmo che simuli l'effetto candela elettronica.
Ho 3 led che si accendono/spengono contemporaneamente.
Ho preso spunto dal tuo interessante algoritmo e l'ho modificato un po' (vedi di seguito).
Ho usato solo il led G. Ho modificato P_SPETTRO e la funzione set_spettro, ho giocato un po' con la variabile pos_pwm (faccio si che non superi la soglia di 85).
L'effetto è molto buono (ho un micro che viaggia a 16Mhz) però la candela resta spenta per troppo tempo. Mi spiego, la candela passa molto dolcemente da accesa a spenta.
Io vorrei creare un effetto di leggere dissolvenza senza che l'occhio veda mai la candela spenta del tutto e velocizzare un po' il movimento di dissolvenza.
Non so dove modificare il tuo algoritmo per rendere questo effetto. Mi puoi dare qualche dritta?

Grazie

Alex

Codice: Seleziona tutto
//#define P_SPETTRO  767
#define P_SPETTRO  255

unsigned char pos_pwm;
unsigned char liv_G;  // livelli da 0 a 255 dei tre colori
unsigned short pos_spettro;       // posizione da 0 a 767 nello spettro
char base_tempi;                  // bit attivato al completamento di un' onda

/******************************************************************************/
/*  set_spettro                                                               */
/*      calcola la configurazione dei tre colori in base alla posizione nello */
/*      spettro                                                               */
/******************************************************************************/
void set_spettro(void)
{
  short p;
 
  p = pos_spettro;
  if (p < /*256*/ 128)
  {
    liv_G = p;

  }
  else if (p < /*512*/ 256)
  {
    p &= 0xff;
    liv_G = 255 - p;
      
      //p &= 0x7f;
      //liv_G = 127 - p;

  }
  else
  {
    p &= 0xff;
    liv_G = 0;

  }
}

/******************************************************************************/
/*  inc_spettro                                                               */
/*      incrementa la posizione dello spettro in modo circolare               */
/******************************************************************************/
void inc_spettro(void)
{
  if (pos_spettro != P_SPETTRO) pos_spettro++; else pos_spettro = 0;
}

/******************************************************************************/
/*  inc_spettro                                                               */
/*      decrementa la posizione dello spettro in modo circolare               */
/******************************************************************************/
void dec_spettro(void)
{
  if (pos_spettro) pos_spettro--; else pos_spettro = P_SPETTRO;
}

#endif




/**
  * @brief  Main program.
  * @param  None
  * @retval None
  */
void main(void)
{
   uint32_t i,dato;
   
   // SetUp Clock from external quartz that must be 16MHz
   CLK_DeInit();
   CLK_SYSCLKConfig(CLK_PRESCALER_HSIDIV1);   /* Configure the Fcpu to DIV1*/

        gpioSetup();
   
   /* Enable Interrupts */
        enableInterrupts();
   
#ifdef TEST_LED_PWM
// prova
  liv_G = 255;
   
  base_tempi = 0; 
  pos_spettro = 0;
#endif
 
  while(1)
  {
   
   
   #ifdef TEST_LED_PWM
    // gestione forme d' onda PWM
   
    if (pos_pwm < liv_G)
         dato = 0x80000000;
      else
         dato = 0;
      lumen_PWM_test(dato);
   
    pos_pwm++;
      if (pos_pwm > 85)
         pos_pwm = 0;
    if (!pos_pwm)
    {
      // accensione impulso di base tempi al completamento dell' onda
      base_tempi = 1;

    }
   
   
    // programma di dissolvenza incrociata
    if (base_tempi)
    {
      base_tempi = 0;      
      inc_spettro();
      set_spettro();
    }
      
   
#endif
  }


}
Avatar utente
Foto Utentealex79
0 1
 
Messaggi: 1
Iscritto il: 5 giu 2012, 11:42

0
voti

[14] Re: [PIC18] Led e PWM: facile, veloce e senza timers.

Messaggioda Foto UtenteTardoFreak » 5 giu 2012, 12:25

Come puoi notare i valori R,G e B vanno da 0 a 255, calcolati nella funzione set_spettro.
Se non chiami quella funzione tu puoi controllare i tre livelli come ti pare facendoli partire dal valore che decidi tu fino ad arrivare al massimo.
Per quanto riguarda la temporizzazione è necessario ricordare che questo programma è più che altro un esperimento. Serve per far vedere come un loop infinito di funzionamento può essere sfruttato per regolare più canali PWM e generare una temporizzazione senza usare timers.
Chiaramente la temporizzazione dipende dal tempo di esecuzione del loop principale e quindi può essere regolata in modo empirico, facendo diverse prove cambiando la base tempi. Non essendoci un riferimento preciso come un timer, questo è un programma che funziona un po' come un elastico di gomma. :mrgreen:

Ti suggerisco la lettura di QUESTO ARTICOLO di Foto UtentePaolino dove il PWM viene implementato in modo più serio.
"La follia sta nel fare sempre la stessa cosa aspettandosi risultati diversi".
"Parla soltanto quando sei sicuro che quello che dirai è più bello del silenzio".
Rispondere è cortesia, ma lasciare l'ultima parola ai cretini è arte.
Avatar utente
Foto UtenteTardoFreak
73,9k 8 12 13
-EY Legend-
-EY Legend-
 
Messaggi: 15754
Iscritto il: 16 dic 2009, 11:10
Località: Torino - 3° pianeta del Sistema Solare

Precedente

Torna a Firmware e programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 4 ospiti