Newsgroup: it.hobby.elettronica.digitale
Titolo: PWM con 16f84

Riposto questo listato che oltre essere utile (ho visto qualcuno lo cercava
cose simili) mi ha fatto venire un dubbio.
Nel ciclo PWM_1 c'e' la seguente istruzione
 ADDWF PWM_DUTY, W  ; accum = accum + duty
ma W nn lo azzera ad ogni nuova chiamata della routine PWM, e lasciando un
valore qualsiasi dentro W, il giochino
che sfrutta il carry per fare il Duty funziona uguale??
; Program PWM.ASM
;
; Illustrates use of the PWM command.  Average voltage at PORTB.0 is
; ramped up from zero and then down from near +5.0.  Process repeats.
;
; Peter H. Anderson, MSU, August 7, '97
;
 LIST p=16c84
#include <c:\mplab\p16c84.inc>
        __CONFIG 11h
 CONSTANT  BASE_VAR=0CH
PWM_DUTY EQU BASE_VAR+0
PWM_LOOP EQU BASE_VAR+1
MAIN:
 BSF STATUS, RP0
 BSF TRISB, 0   ; make pin RB.0 an input, high impedance
 BCF STATUS, RP0
 CLRF PWM_DUTY   ; start duty cycle at minimum
MAIN_1:
 CALL PWM
 INCFSZ PWM_DUTY, F  ; and ramp up
 GOTO MAIN_1
MAIN_2:
 CALL PWM    ; now, ramp down
 DECFSZ PWM_DUTY, F
 GOTO MAIN_2
 GOTO MAIN
PWM:
 CLRF PWM_LOOP    ; 256 counter
 BSF STATUS, RP0   ; bank 1
 BCF TRISB, 0    ; make PORTB.0 an output
 BCF STATUS, RP0   ; back to bank 0
PWM_1:
 ADDWF PWM_DUTY, W  ; accum = accum + duty
 BTFSS STATUS, C
 BCF PORTB, 0
 BTFSC STATUS, C
 BSF PORTB, 0
    ; a delay may be inserted here
 DECFSZ PWM_LOOP, F  ; do this 256 times
 GOTO PWM_1
 BSF STATUS, RP0
 BSF TRISB, 0    ; make PORTB.0 an input
 BCF STATUS, RP0
 RETURN
 END

 il Duty funziona uguale??
Per me ci sono diverse cose... intanto non vedo la necessita' di continuare
a cambiare la configurazione del pin, anzi, mi sembra che in certi casi
potrebbe portare a qualche effetto collaterale. Poi la variabile pwm_duty
non viene gestita in modo proprio corretto se si vuole ottenere un andamento
a triangolo... sale da 0 a 255, torna a 0 e poi subito a 255 per cominciare
a ridiscendere. Ed infine la questione sollevata da te... a meno che non ci
sia un'alchimia con la rappresentazione binaria, tale per cui il valore di W
e' indifferente, si tratta di un clamoroso errore... secondo me non funziona
un tubo... oppure non ho capito affatto l'algoritmo.
Per me sarebbe invece corretto confrontare il valore di pwm_duty con quello
di pwm_loop, quindi una sottrazione tra questi due valori.
Claudio F

 ha scritto nel messaggio
news:LndTa.1488$Df5....@news1.tin.it...


Dimenticavo, il fatto che nel programma PWM_duty sale fino a 255 e poi torno
giu'..nn è perche' vuole fare un andamnto triangolare, è a scopo
dimostrativo...
nel senso se si pilota un motorino con quel programma, vedremo il motorino
fermo, poi che va sempre piu' veloce fino ad avere un Duty del 100%, e poi
ridiscendere.

 azzerare..c'e' l'alchimia sotto:))
Posso anche apprezzarla in se'stessa, ma resta il fatto che mi sembra tirato
per i capelli chiamarlo segnale PWM... che richiederebbe un T costante
suddiviso in UN Ton e UN Toff...
Comunque e' cosi' particolare questa cosa che quando avro' un po' di tempo
(e soprattutto voglia) la provero';)
ciao
Claudio F

 ha scritto nel messaggio
news:rzzTa.6191$Df5.1...@news1.tin.it...


Sarebbe opportuno che vi sforziate un pò di capire il modo di funzionamento
della routine in questione. Soltanto quando si sbatte un pò il muso sulle
cose si riescono ad imparare cose nuove. Scusate il tono ma, la routine
illustrata funziona benissimo e mi ha risolto in passato un sacco di
problemi ogni qualvolta mi serviva un'uscita analogica da un PIC16F84.
Per aiutarvi vi dirò che l'uscita interessata viene settata come ingresso
per porla in alta impedenza ed evitare che la durata del MAIN in cui questa
routine è inserita possa influenzare il valore della tensione di uscita.
Naturalmente per avere l'uscita analogica occorre mettere sul pin relativo
un circuito RC (10 K ed 1 uF). Se avrete ancora problemi fatemi un fischio e
vedremo di approfondire ulteriormente la questione. Saluti, Giuseppe.
Taccio <ingegnerc...@MiaoMiao.com> wrote in message
tzBTa.10180$Za4.2...@news2.tin.it...


 occorre mettere sul pin relativo un circuito RC (10 K ed 1 uF).
Ok, il modo "hardware" di usarla chiarisce le cose, il gruppo RC si
considera come una sorta di memoria integratrice da rinfrescare di tanto in
tanto con un pacchetto di 256 iterazioni su cui si suddividono alcuni
periodi on e altri off. La precisione nella ripetizione periodica di questi
rinfreschi non e' determinante come pure la posizione degli impulsi
all'interno di essi (anche se questo aumenta comunque il rumore rispetto ad
un PWM a frequenza fissa). Il gruppo RC va letto con un ingresso ad alta
impedenza, per esempio un voltage follower.
Il valore iniziale di W non influenza il numero di impulsi Ton generati, che
corrispondono esattamente al valore di pwm_duty. L'unica cosa e' che non si
riesce mai a raggiungere esattamente il duty del 100% perche' al massimo
vengono generati 255 impulsi su 256 iterazioni (max duty out=99,6%).
Diciamo che se invece di presentarlo come un generatore PWM fosse stato
intitolato "modo per ottenere una tensione analogica" avrebbe suscitato
(almeno in me) meno tentativi di analizzarlo secondo l' ortodossia;)
Come sistema in se'stesso e' veramente interessante.
ciao
Claudio F
PS simulato con il programma:
procedure elabora;
var pwm_loop,pwm_duty,W,iw,C:integer;
    f:text;
begin
  assign(f,'output.txt'); rewrite(f);
  for pwm_duty:=0 to 255 do begin
    writeln(f,'---------------------------------------------');
    writeln(f,'Duty '+inttostr(pwm_duty));
    writeln(f,'---------------------------------------------');
    for iw:=0 to 255 do begin  {iw=valore iniziale di w}
      W:=iw;
      C:=0;
      for pwm_loop:=1 to 256 do begin
        W:=W+pwm_duty;
        if W > 255 then begin inc(C); W:=W-256 end;
      end;
      writeln(f,'W='+inttostr(iw)+'  C='+inttostr(C));
    end; {for iw}
  end; {for duty}
  close(f);
end;

 > MAIN in cui questa routine è inserita possa influenzare il valore
