Vai al contenuto
PLC Forum


Dimmer pwm pic16f628a


NanoFarad

Messaggi consigliati

Da qualche tempo a questa parte, per la realizzazione di fori su pcb, ho rispolverato il mio minitrapano, ed in tempi di coronavirus si aguzza l'ingegno.

In breve ho realizzato, anche se solo su millefori per poi passare al pcb vero e proprio, un generatore di pwm sfruttando un classico dei pic: il 16f628a.

La peculiarità risiede nel visualuzzare su leda a che frequenza e a che % di duty cycle sta lavornado il pic ma senza l'ausulio di display;

e nel variare sia frequenza che duty cycle tramite due pulsanti così configurati:

il primo a sx sotto i led gialli mi varia il duty cycle a step di 10% a premuta. Il secondo a dx sotto i led rossi mi varia la frequenza a step di 500hz a premuta.

appena alimentato il duty si configura al 10% e la frequenza a 1kHz.

Sopra abbiamo i led: 5 gialli e 5 rossi.

come detto prima i gialli per il duty visualizzano così la percentuale di lavoro:

Primo Led lampeggiante = 10%

Primo Led fisso = 20%

Primo Led fisso e Secondo Led lampeggiante = 30% 

Primo e Secondo Led fisso  = 40%

Primo e Secondo Led fisso, Terzo Led lampeggiante = 50%

e così via fino al 100 % con tutti e 5 i led accesi fissi.

la successiva pressione del pulsante spegne il duty cycle e riparte daccapo.

Stessa cosa avviene per la frequenza che invece parte dal 1000 hz primo led rosso fisso e incrementa di 500 visualizzando come per il duty cycle la scala dei led illuminata.

Ovviamente la sezione di massa verso tip 35c sia in Emettitore che in Collettore vanno dimensionati in base alla corrente da gestire come anche il positivo di alimentazione che da Vcc va al carico.

Vi allego il listato in mikrobasic ed un video dimostrativo.

Dimmer.thumb.jpg.71e490c4f1216ba95b7d28140a33e676.jpg

 

program Pwm
'for pic16f628a
' Declarations section 
 
 sub procedure pausa
 delay_ms(100)
 end sub

dim dut as byte
fr as word
duti as integer

main:
'   Main program 

  CMCON=7
  
   trisa=%00110000
   trisb=%00000000
   portb=%11110111
   porta=%11001111

 dut=10
 duti=10
 fr=1000
 
 pwm1_init(1000)
 pausa
 
 PWM1_Start()
 pausa

 PWM1_Set_Duty(duti)
 pausa
 
 while true

    portb.4=0
    pausa
    portb.4=1
    pausa
   
    if porta.4=0 then
     pausa
     gosub duty
    end if
    
      if porta.5=0 then
       pausa
       gosub freq
      end if
      
    if dut=10 then
    porta.2=0
    pausa
    porta.2=1
    end if

   if dut=30 then
   porta.3=0
   pausa
   porta.3=1
   end if

   if dut=50 then
   portb.0=0
   pausa
   portb.0=1
   end if

  if dut=70 then
   portb.1=0
   pausa
   portb.1=1
   end if

  if dut=90 then
   portb.2=0
   pausa
   portb.2=1
   end if

   
    if fr = 1500 then
    porta.0=0
    pausa
    porta.0=1
    end if
    
    if fr = 2500 then
    porta.7=0
    pausa
    porta.7=1
    end if
   
    if fr = 3500 then
    porta.6=0
    pausa
    porta.6=1
   end if
   
   if fr = 4500 then
    portb.7=0
    pausa
    portb.7=1
    end if
   
   if fr=1000 then
    porta.1=0
    porta.0=1
    porta.7=1
    porta.6=1
    portb.7=1
   end if

  wend
  
  duty:
  dut=dut+10
  if dut > 100 then
  dut=0
  end if
  if dut=0 then
   porta.2=1
   porta.3=1
   portb.0=1
   portb.1=1
   portb.2=1
  end if

   if dut=20  then
   porta.2=0
  end if

   if dut= 40 then
   porta.2=0
   porta.3=0
  end if

   if dut=60  then
   porta.2=0
  porta.3=0
  portb.0=0
  end if

   if dut=80   then
   porta.2=0
   porta.3=0
   portb.0=0
   portb.1=0
  end if
  
  if dut=100 then
   porta.2=0
   porta.3=0
   portb.0=0
   portb.1=0
   portb.2=0
  end if
    duti= ((dut*255)/100)
  PWM1_Set_Duty(duti)
  return
  

  freq:
   fr=fr+500
   if fr > 5000 then
    fr=0
    pwm1_stop()
    pausa
    porta.1=1
    porta.0=1
    porta.7=1
    porta.6=1
    portb.7=1
   end if
   
   if fr=1000 then
    porta.1=0
    porta.0=1
    porta.7=1
    porta.6=1
    portb.7=1
    pwm1_init(1000)
   end if
   
   if fr=2000 then
    porta.1=0
    porta.0=0
    pwm1_init(2000)
   end if
   
   if fr=3000 then     'port a2
    porta.1=0
    porta.0=0
    porta.7=0
    pwm1_init(3000)
   end if
   
    if fr=4000 then     'port a3
    porta.1=0
    porta.0=0
    porta.7=0
    porta.6=0
    pwm1_init(4000)
   end if
   
   if fr = 5000 then
    porta.1=0
    porta.0=0
    porta.7=0
    porta.6=0
    portb.7=0          'port a6
    pwm1_init(5000)
   end if

   if fr = 1500 then
    porta.0=0
    pausa
    porta.0=1
    pwm1_init(1500)
   end if
   if fr = 2500 then
    porta.7=0
    pausa
    porta.7=1
    pwm1_init(2500)
   end if
    if fr = 3500 then
    porta.6=0
    pausa
    porta.6=1
    pwm1_init(3500)
   end if
   if fr = 4500 then
    portb.7=0
    pausa
    portb.7=1
    pwm1_init(4500)
   end if

   pwm1_start()
   PWM1_Set_Duty(duti)
   return

end.

 

Ovviamente sotto con i suggerimenti e le modifiche. Ben accetto quanto di costruttivo sia. Spero solo di aver postato nella sezione giusta. E' il mio primo post.  Grazie a tutti.

Link al commento
Condividi su altri siti


Scusate ma mi sono accorto in ritardo di aver inviato il listato senza commenti. rimedio.

 

program Pwm
'for pic16f628a
' Declarations section 
 
 sub procedure pausa   ' definizione procedura di ritardo 200 millisecondi
 delay_ms(100)
 end sub

dim dut as byte    ' variabile controllo duty cycle
fr as word          ' variabile setting frequenza
duti as integer     ' variabile setting duty cycle %

main:
'   Main program 

  CMCON=7
  
   trisa=%00110000    ' imposto pin port a come ingressi(1) e uscite (0)
   trisb=%00000000    ' tutti i pin port b come uscite
   portb=%11110111    ' forzo gli stati dei pin port b a livello logico 1 o 0
   porta=%11001111    ' forzo gli stati dei pin port a a livello logico 1 o 0

 dut=10                      ' setto duty cycle al 10%
 duti=10
 fr=1000                       ' setto la frequenza ad 1 KHz
 
 pwm1_init(1000)              ' inizializzo il pwm
 pausa
 
 PWM1_Start()                ' avvio pwm
 pausa

 PWM1_Set_Duty(duti)          ' con duty cycle come nella variabile assegnatagli
 pausa
 


while true

    portb.4=0                'questo led mi segnala l'operatività
    pausa
    portb.4=1
    pausa
   
    if porta.4=0 then          ' Pulsane variazione duty cycle
     pausa
     gosub duty
    end if
    
      if porta.5=0 then         ' pulsante variazione frequenza
       pausa
       gosub freq
      end if
      
    if dut=10 then            ' da qui fini al wend imposto in base al valore frequenza
    porta.2=0                 ' e duty cycle quali led accendere e/o far lampeggiare
    pausa
    porta.2=1
    end if

   if dut=30 then
   porta.3=0
   pausa
   porta.3=1
   end if

   if dut=50 then
   portb.0=0
   pausa
   portb.0=1
   end if

  if dut=70 then
   portb.1=0
   pausa
   portb.1=1
   end if

  if dut=90 then
   portb.2=0
   pausa
   portb.2=1
   end if

   
    if fr = 1500 then
    porta.0=0
    pausa
    porta.0=1
    end if
    
    if fr = 2500 then
    porta.7=0
    pausa
    porta.7=1
    end if
   
    if fr = 3500 then
    porta.6=0
    pausa
    porta.6=1
   end if
   
   if fr = 4500 then
    portb.7=0
    pausa
    portb.7=1
    end if
   
   if fr=1000 then
    porta.1=0
    porta.0=1
    porta.7=1
    porta.6=1
    portb.7=1
   end if

  wend
  
  duty:                          ' impostazione del duty cycle  trmaite il pulsante e accensione e/o lampeggio led relativi al valore letto.
  dut=dut+10
  if dut > 100 then
  dut=0
  end if
  if dut=0 then
   porta.2=1
   porta.3=1
   portb.0=1
   portb.1=1
   portb.2=1
  end if

   if dut=20  then
   porta.2=0
  end if

   if dut= 40 then
   porta.2=0
   porta.3=0
  end if

   if dut=60  then
   porta.2=0
  porta.3=0
  portb.0=0
  end if

   if dut=80   then
   porta.2=0
   porta.3=0
   portb.0=0
   portb.1=0
  end if
  
  if dut=100 then
   porta.2=0
   porta.3=0
   portb.0=0
   portb.1=0
   portb.2=0
  end if
    duti= ((dut*255)/100)          ' calcolo percentuale duty cycle partendo dal valore impostato
  PWM1_Set_Duty(duti)              '  trasmissione del parametro duty cycle al pic
  return
  

  freq:               ' impostazione della frequenza duty cycle  trmaite il pulsante e accensione e/o lampeggio led relativi al valore letto.
   fr=fr+500
   if fr > 5000 then
    fr=0
    pwm1_stop()
    pausa
    porta.1=1
    porta.0=1
    porta.7=1
    porta.6=1
    portb.7=1
   end if
   
   if fr=1000 then
    porta.1=0
    porta.0=1
    porta.7=1
    porta.6=1
    portb.7=1
    pwm1_init(1000)
   end if
   
   if fr=2000 then
    porta.1=0
    porta.0=0
    pwm1_init(2000)
   end if
   
   if fr=3000 then
    porta.1=0
    porta.0=0
    porta.7=0
    pwm1_init(3000)
   end if
   
    if fr=4000 then
    porta.1=0
    porta.0=0
    porta.7=0
    porta.6=0
    pwm1_init(4000)
   end if
   
   if fr = 5000 then
    porta.1=0
    porta.0=0
    porta.7=0
    porta.6=0
    portb.7=0
    pwm1_init(5000)
   end if

   if fr = 1500 then
    porta.0=0
    pausa
    porta.0=1
    pwm1_init(1500)
   end if
   if fr = 2500 then
    porta.7=0
    pausa
    porta.7=1
    pwm1_init(2500)
   end if
    if fr = 3500 then
    porta.6=0
    pausa
    porta.6=1
    pwm1_init(3500)
   end if
   if fr = 4500 then
    portb.7=0
    pausa
    portb.7=1
    pwm1_init(4500)
   end if

   pwm1_start()             ' attivazione pwm
   PWM1_Set_Duty(duti)      ' con duty cycle impostato e trasmesso.
   return

end.

Modificato: da NanoFarad
Link al commento
Condividi su altri siti

Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora
×
×
  • Crea nuovo/a...