PWM taaaanto

Nov 26, 2009 44 Replies

Anzi, a ben pensarci, non serve neanche il buffer in RAM se si sfruttano bene 4 registri dedicati. Naturalmente non ci si deve aspettare in uscita il classico PWM simmetrico.

Piccio.

[...]

Io sono rimasto che per fare un pwm ci vuole un contatore che serve per l'appunto a generare la rampa su cui fare gli N confronti relativi alle N uscite, quindi se il pwm ha risoluzione di 8bit sia contatore che registri su cui fare confronti saranno a 8bit (in questo caso l'utilizzo di locazioni ram sar=E0 N+1).......: proponevi qualcosa di diverso?

Pasu:

Assolutamente no, visto che poi anche il fronte di inizio sarebbe sfasato. Il punto è che due istruzioni ci mettono meno che non otto (2*4).

Argh! Lo hai evocato! Chissà che s'inventa, ora. :D

[Bertolazzi]

Credo di poter scrivere un prg per AVR per 8 (dicansi "otto") canali PWM a 5 bit con impegno CPU ridicolo senza tabelle. Appena finisco la piramide ci provo.

Piccio.

Rusty ha scritto:

perche' questa scelta ? dipende dal filtraggio successivo e dalla velocita' di assestamento o altro ?

lowcost

Piccio:

Anch'io, ma mi viene fuori una forma d'onda balenga. Mi sa anche a te. Ora finisco il mio sbrodolone e ti faccio vedere io!

Il MIO praticamente =E8 una sorta di convertitore parallelo-seriale ottuplo in cui i bit vengono emessi per un tempo proporzionale al loro peso. Una sorta di 8 seriali sincrone per porta...

Piccio.

Piccio:

C'ho messo mezz'ora a capirla. Che dire? Geniale. Anzi, di più, Picciale.

In pratica dici: per i 4 bit più bassi non c'è nulla da fare, bisogna spararli "dritti" come avevo suggerito sopra, tenendo la CPU sempre occupata (*).

Per gli altri 4 bit, invece, basta fare due conti ogni tanto.

Invece di elaborare i dati per i 4 port in parallelo, li sfasiamo di 1/4 di periodo in modo tale da distribuire il carico di lavoro. (*) Quindi anche quando la CPU è sempre occupata in realtà lo è solo ad un quarto.

Se dividiamo tutto il periodo in 16 parti e facciamo partire un interrupt ogni volta, avremo che una volta su 4 terremo occupata la CPU per tutta la durata della parte (*) per buttar fuori i byte mappati in RAM, mentre le altre volte dovremo solo prendere un bit per contatore, assemblarlo in una parola e sbatterla sulla porta.

Ho esplicitato meglio lo specchietto dei task da effettuare per ogni interrupt. Allego in fondo il disegno aggiornato, qui sotto lo specchietto dove ho indicato anche quali bit sono interessati.

t0: A7 B5 C6 t2: B4 t3: B3210 t4: B7 C5 D6 t6: C4 t7: C3210 t8: C7 D5 A6 t10: D4 t11: D3210 t12: D4 A5 B6 t14: A4 t15: A3210

Da questo salta all'occhio una prima miglioria: usare due interrupt, uno ogni 62,5 uS per aggiornare i bit alti ed uno ogni 125 uS per aggiornare quelli bassi.

Vedo due problemi: assemblare il byte di bit alti non è un'operazione così veloce come presumi e il fatto di dover aggiornare un numero variabile di port introdurrà uno skew del duty cycle, se non implementato correttamente.

In quali casi una forma d'onda "pulita", come la A riportata in fondo al disegno, avrà effetti da una arbitraria B, che ha, in complesso, la stessa "energia"? La prima risposta che mi viene in mente è "quando il t-on di un componente è diverso dal t-off", come con IGBT e fotoaccoppiatori. Se l'applicazione di Rusty non distinguesse tra A e B ci sarebbe un algoritmo facile e veloce. Ma, ohimè, temo sbagliato, nel senso che B al circuito di Rusty gli fa schifo...

A ben vedere, mi sa che neppure la tua proposta sia esente da questa pecca. E' però vero che, prendendo in considerazione solo il bit più alto ed andando di mappatura per tutti gli altri si risparmia metà tempo CPU e si hanno forme d'onda a bassa frequenza. Boh, sentiamo che vuol fare Rusty.

Ricordiamoci però che dalai lamah ha sempre ragione, salvo per chi, come me, non ha alcuno strumento per logiche programmabili uscite dopo il 1985.

[FIDOCAD] TY 103 58 5 3 0 0 0 * 6 LI 95 60 96 55 LI 114 55 115 60 LI 115 60 114 65 LI 96 65 95 60 LI 96 55 114 55 LI 114 65 96 65 LI 55 60 56 55 LI 56 65 55 60 LI 94 55 95 60 LI 95 60 94 65 LI 56 55 94 55 LI 94 65 56 65 LI 115 60 116 55 LI 116 65 115 60 LI 124 55 125 60 LI 125 60 124 65 LI 116 55 124 55 LI 124 65 116 65 TY 119 58 5 3 0 0 0 * 5 LI 126 65 125 60 LI 125 60 126 55 LI 129 55 130 60 LI 130 60 129 65 LI 126 55 129 55 LI 126 65 129 65 TY 126 58 5 3 0 0 0 * 4 LI 130 60 131 55 LI 134 55 135 60 LI 135 60 134 65 LI 131 55 134 55 LI 131 65 130 60 LI 131 65 134 65 MC 133 49 1 0 074 TY 122 44 5 3 0 0 0 * 3,2,1,0 TY 38 57 5 3 0 0 0 * PORTA TY 123 88 5 3 0 0 0 * 6 LI 115 90 116 85 LI 134 85 135 90 LI 135 90 134 95 LI 116 95 115 90 LI 116 85 134 85 LI 134 95 116 95 LI 75 90 76 85 LI 76 95 75 90 LI 114 85 115 90 LI 115 90 114 95 LI 76 85 114 85 LI 114 95 76 95 TY 93 88 5 3 0 0 0 * 7 LI 95 120 96 115 LI 96 125 95 120 LI 134 115 135 120 LI 135 120 134 125 LI 96 115 134 115 LI 134 125 96 125 TY 113 118 5 3 0 0 0 * 7 LI 115 150 116 145 LI 116 155 115 150 TY 38 87 5 3 0 0 0 * PORTB TY 38 117 5 3 0 0 0 * PORTC TY 38 148 5 3 0 0 0 * PORTD LI 64 85 65 90 LI 65 90 64 95 LI 56 85 64 85 LI 64 95 56 95 TY 59 88 5 3 0 0 0 * 5 LI 66 95 65 90 LI 65 90 66 85 LI 69 85 70 90 LI 70 90 69 95 LI 66 85 69 85 LI 66 95 69 95 TY 66 88 5 3 0 0 0 * 4 LI 70 90 71 85 LI 74 85 75 90 LI 75 90 74 95 LI 71 85 74 85 LI 71 95 70 90 LI 71 95 74 95 LI 55 90 56 85 LI 56 95 55 90 TY 63 118 5 3 0 0 0 * 6 LI 55 120 56 115 LI 74 115 75 120 LI 75 120 74 125 LI 56 125 55 120 LI 56 115 74 115 LI 74 125 56 125 LI 75 120 76 115 LI 76 125 75 120 LI 84 115 85 120 LI 85 120 84 125 LI 76 115 84 115 LI 84 125 76 125 TY 79 118 5 3 0 0 0 * 5 LI 86 125 85 120 LI 85 120 86 115 LI 89 115 90 120 LI 90 120 89 125 LI 86 115 89 115 LI 86 125 89 125 TY 86 118 5 3 0 0 0 * 4 LI 90 120 91 115 LI 94 115 95 120 LI 95 120 94 125 LI 91 115 94 115 LI 91 125 90 120 LI 91 125 94 125 TY 83 148 5 3 0 0 0 * 6 LI 75 150 76 145 LI 94 145 95 150 LI 95 150 94 155 LI 76 155 75 150 LI 76 145 94 145 LI 94 155 76 155 LI 74 145 75 150 LI 75 150 74 155 LI 95 150 96 145 LI 96 155 95 150 LI 104 145 105 150 LI 105 150 104 155 LI 96 145 104 145 LI 104 155 96 155 TY 99 148 5 3 0 0 0 * 5 LI 106 155 105 150 LI 105 150 106 145 LI 109 145 110 150 LI 110 150 109 155 LI 106 145 109 145 LI 106 155 109 155 TY 106 148 5 3 0 0 0 * 4 LI 110 150 111 145 LI 114 145 115 150 LI 115 150 114 155 LI 111 145 114 145 LI 111 155 110 150 LI 111 155 114 155 LI 74 145 55 145 LI 74 155 55 155 LI 116 145 135 145 LI 135 155 116 155 TY 57 148 5 3 0 0 0 * 7 TY 131 148 5 3 0 0 0 * 7 MC 73 79 1 0 074 TY 62 74 5 3 0 0 0 * 3,2,1,0 MC 93 109 1 0 074 TY 82 104 5 3 0 0 0 * 3,2,1,0 MC 113 139 1 0 074 TY 102 134 5 3 0 0 0 * 3,2,1,0 LI 135 170 135 40 MC 55 45 3 0 074 TY 50 34 5 3 0 0 0 * 0us TY 127 34 5 3 0 0 0 * 500us TY 170 55 5 3 0 0 0 * t0: A7 B5 C6 TY 170 60 5 3 0 0 0 * t2: B4 LI 95 70 95 40 TY 86 34 5 3 0 0 0 * 250us TY 66 34 5 3 0 0 0 * 125us LI 75 99 75 40 TY 71 58 5 3 0 0 0 * 7 TY 170 40 5 3 0 0 0 * PORTC: PWM(16..23) TY 170 45 5 3 0 0 0 * PORTD: PWM(24..31) TY 170 35 5 3 0 0 0 * PORTB: PWM(8..15) TY 170 30 5 3 0 0 0 * PORTA: PWM(0..7) MC 150 170 0 0 074 LI 50 170 150 170 LI 60 170 60 173 LI 65 170 65 173 LI 70 170 70 173 LI 80 170 80 173 LI 85 170 85 173 LI 90 170 90 173 LI 100 170 100 173 LI 105 170 105 173 LI 110 170 110 173 LI 120 170 120 173 LI 125 170 125 173 LI 130 170 130 173 LI 95 170 95 175 LI 75 170 75 175 LI 115 170 115 175 TY 54 175 3 2 0 0 0 * 0 TY 59 175 3 2 0 0 0 * 1 TY 64 175 3 2 0 0 0 * 2 TY 69 175 3 2 0 0 0 * 3 TY 74 175 3 2 0 0 0 * 4 TY 79 175 3 2 0 0 0 * 5 TY 84 175 3 2 0 0 0 * 6 TY 89 175 3 2 0 0 0 * 7 TY 94 175 3 2 0 0 0 * 8 TY 99 175 3 2 0 0 0 * 9 TY 103 175 3 2 0 0 0 * 10 TY 108 175 3 2 0 0 0 * 11 TY 113 175 3 2 0 0 0 * 12 TY 118 175 3 2 0 0 0 * 13 TY 123 175 3 2 0 0 0 * 14 TY 128 175 3 2 0 0 0 * 15 TY 133 175 3 2 0 0 0 * 16 LI 55 45 55 175 RP 70 165 75 170 RP 110 165 115 170 RP 130 165 135 170 RP 90 165 95 170 RP 55 165 57 170 RP 65 165 67 170 RP 85 165 87 170 RP 105 165 107 170 RP 125 165 127 170 RP 75 165 77 170 RP 95 165 97 170 RP 115 165 117 170 TY 20 165 5 3 0 0 0 * Impegno CPU TY 70 15 5 3 0 0 0 * PWM 256 livelli TY 170 70 5 3 0 0 0 * t4: B7 C5 D6 TY 170 75 5 3 0 0 0 * t6: C4 TY 170 85 5 3 0 0 0 * t8: C7 D5 A6 TY 170 90 5 3 0 0 0 * t10: D4 TY 160 125 5 3 0 0 0 * I bit 7,6,5,4 sono aggiornati leggendo TY 160 130 5 3 0 0 0 * direttamente i contatori TY 160 140 5 3 0 0 0 * I bit 3,2,1,0 sono aggiornati tramite TY 160 145 5 3 0 0 0 * una mappatura in RAM (16 byte per canale) TY 170 65 5 3 0 0 0 * t3: B3210 TY 170 80 5 3 0 0 0 * t7: C3210 TY 170 105 5 3 0 0 0 * t14: A4 TY 170 100 5 3 0 0 0 * t12: D4 A5 B6 TY 170 95 5 3 0 0 0 * t11: D3210 TY 170 110 5 3 0 0 0 * t15: A3210 LI 55 200 55 195 LI 55 195 95 195 LI 95 195 95 200 LI 95 200 135 200 LI 135 200 135 195 LI 55 210 55 205 LI 55 205 70 205 LI 70 205 70 210 LI 70 210 75 210 LI 75 210 75 205 LI 75 205 80 205 LI 80 205 80 210 LI 80 210 100 210 LI 100 210 100 205 LI 100 205 110 205 LI 110 205 110 210 LI 130 210 130 205 LI 130 205 135 205 LI 135 205 135 210 LI 110 210 120 210 LI 120 210 120 205 LI 120 205 125 205 LI 125 205 125 210 LI 125 210 130 210 TY 40 195 5 3 0 0 0 * A TY 40 205 5 3 0 0 0 * B

Non ho capito. Le passo mio marito. (Cit.)

Forse volevi dire: "Mi scuso per la rozzezza di questo modello non in scala..." (Cit.)

Il problema =E8 che salendo in frequenza ed in numero di bit, il tempo di risposta all'interrupt produce errori via via pi=F9 pesanti. Per avere una buona linearit=E0 occorrerebbe stare bassi in frequenza. Per migliorare il tempo di risposta all'interrupt si potrebbero usare i due COMPARE (COMPA & COMPB) in modo da sfasarli di qualche ciclo: il primo (grossolano) genera INT, l'altro =E8 il "gate" su poling per l'esecuzione vera e propria. Si evita cos=EC anche l'incertezza di rispondere all'INT mentre si eseguono istruzioni atomiche che richiedono un diverso numero di cicli. Oppure con due INT adiacenti nel tempo:

COMPA: nop nop nop nop ;qui dovrebbe cadere l'INT per COMPB nop ;oppure qui nop ;ti interrompi o no? rjmp COMPB ;vaffainterrupt!

COMPB: blabla r0,r1 ... reti

end: Piccio.

Beato te!

Su questo non ho avuto dubbi sin da prima di iniziare a leggere.

Avevo intuito qualcosa del genere, domani ci do un'occhiata, ora non sono in condizioni di connettere.

P.

Piccio:

In pratica prendi il primo contatore, lo shifti attraverso il carry, shifti il byte di output prendendo dal carry, prendi il secondo contatore, lo shifti attraverso il carry, shifti il byte di output prendendo dal carry e così via. Due cicli per leggere il contatore nel registro, due cicli per gli shift, due cicli per riscrivere il contatore. Insomma: 48+1 cicli per port.

Ma poi hai, all'uscita, per ogni ciclo, un coso così: __ _____ _____ |__| |____| |

Anzichè un bel __________ |__________|

F. Bertolazzi:

Boh. Si capisce?

Visto ora. L'onda, bella o brutta, deve aver valor medio giusto. Comunque mi sto chiedendo anche io se effettivamente dopo un passabasso si presenta lo stesso valore di tensione. Si potrebbe fare un esperimento molto semplice: collegare un passabasso sulla RS232 del PC e mandar fuori dei caratteri aventi lo stesso numero di bit ad 1 e 0. Ad esempio 0xF0 dovrebbe dare la stessa tensione di 0xAA oppure 0xA5. Naturalmente la costante di tempo dell'RC deve essere adeguatamente alta.

Piccio.

"lowcost" ha scritto nel messaggio news:heu5vd$dfm$ snipped-for-privacy@nnrp-beta.newsland.it...

Il PWM controlla dei led rgb alta luminosità, attualmente le schede di controllo che usiamo vanno a 2 Khz, sono delle 4 canali rgba, partendo un progetto nuovo devo mettere a punto un hardware per 96 canali!!!! ho proposto di dividere su tre schede da 32:-))

(anche perchè una maxischeda da 96 canali da 700mA si troverebbe a gestire correnti mica da ridere da fare girare on board)

Si potrebbe andare anche a 200Hz, non sotto altrimenti si vededono i flicker , ma non voglio peggiorare le prestazioni delsistema attuale, solo che ora uso 16 schede, con 16 micro ecc ecc , vorremmo ridurre il numero delle "intelligenze" a bordo:-)

Cmq l'idea è di usare i dispositivi I2C, con tre schede posso spopolare due scede dal micro, il primo micro si gestisce le due seriali per la comunicazione esterna e creo un bus I2C sulle tre schede che sono cmq montate vicine :-) ciao Rusty

ire

Basta dividere la sola potenza su pi=F9 schede, non il controllo.

ker

a

Gi=E0 andare a 400 Hz sarebbe un bel successo.

Quanti livelli ti servono? Sono sufficienti 256?

Piccio.

Infatti parlo di tre schede da 32 anziche 1 da 96:-))

Certo che si, non è un videowall, con 8 bit ho risoluzione sufficente:-) ciao Rusty

"Rusty" ha scritto nel messaggio news:54wPm.99942$ snipped-for-privacy@twister1.libero.it...

Non vorrei aver capito male, e dire na c.....a, ma se servono solo 32 uscite separate con stessi parametri elettrici e di frequenza, credo che 32 diodi con anodo in parallelo siano la soluzione e dei BAT45 sei vuoi essere più sicuro nella risposta.

32

re

Hai capito male. Le 32 uscite devono essere indipendenti, produrre segnali diversi gli uni dagli altri simultaneamente, real-time.

Piccio.

Piccio:

Direi proprio di sì. Il problema viene fuori se invece vuole comandare un transistor in saturazione per parzializzare senza disperdere potenza.

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required