Forum Moderator
Italy
Offline
Brattain Member
Karma: 219
Posts: 16504
Don't know what I do
|
 |
« Reply #15 on: December 26, 2012, 07:06:53 am » |
Se hai bisogno di 2 segnali simili ma invertiti, perché non li fai entrambi con la tecnica del bit-banging? Imposti il timer 2 in modalità contatore (la CTC, appunto) e ad ogni overflow del timer scambi i livelli dei 2 pin che ti servono.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 143
|
 |
« Reply #16 on: December 26, 2012, 09:27:37 am » |
ciao, ho guardato il link ma non ci ho capito tanto di più, nel senso che non capisco tutti quei simboli usati tipo la tilde o _BV() ecc.
Nel caso del modo CTC, non con overflow ma con compare register, a che frequenza posso arrivare? Mi accontento di 100KHz.
Ho provato ma non mi funziona con il timer 2.
No esiste una libreria in cui ti danno metodi per impostare il pin di uscita, freq e duty? Io ci sto sclerando con sti timer
|
|
|
|
« Last Edit: December 26, 2012, 09:50:06 am by ekjk »
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 143
|
 |
« Reply #17 on: December 26, 2012, 10:59:15 am » |
Ho passato 3 ore su questi timer ma non mi funziona nulla. Dovrebbe essere semplice creare due uscite invertite tra loro...non vorrei usare un componente in più per forza
|
|
|
|
|
Logged
|
|
|
|
|
Forum Moderator
Italy
Offline
Brattain Member
Karma: 219
Posts: 16504
Don't know what I do
|
 |
« Reply #18 on: December 26, 2012, 11:15:08 am » |
ciao, ho guardato il link ma non ci ho capito tanto di più, nel senso che non capisco tutti quei simboli usati tipo la tilde o _BV() ecc.
~ è il simbolo di inversione, quindi ~1 equivale a 0. Per cui se io faccio ~(1<<TOIE2) significa che metto ad 1 il bit TOIE2 in un byte di registro, e poi ne inverto il valore, quindi diventa tutto ad 1 ed a 0 solo il bit TOIE2. Facendo un AND logico poi spengo quel bit. No esiste una libreria in cui ti danno metodi per impostare il pin di uscita, freq e duty? Io ci sto sclerando con sti timer
Usa la PWM Frequency, è una lib che permette di avere un segnale PWM di una determinata frequenza su un qualsiasi pin: http://playground.arduino.cc/Code/PwmFrequency
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 143
|
 |
« Reply #19 on: December 26, 2012, 11:39:38 am » |
Grazie, ma per invertire poi tale segnale generato su un pin utilizzando quella libreria?
|
|
|
|
|
Logged
|
|
|
|
|
Rome (Italy)
Offline
Tesla Member
Karma: 74
Posts: 7379
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
|
 |
« Reply #20 on: December 26, 2012, 11:57:14 am » |
Ho necessità di generare due quadre complementari tutto qua. La frequenza e il duty vorrei poterli impostare. Ovviamente se aumenta il duty di una quello dell'altra deve diminuire.
Scordati di farlo direttamente col 328 a meno che non ti accontenti di bassi valori di frequenza, poche centinaia di Hz. Il solo modo è utilizzare un inverter esterno che ti fornisce il valore negato del PWM e di conseguenza i due pwm tra loro complementari.
|
|
|
|
|
Logged
|
|
|
|
|
Forum Moderator
Italy
Offline
Brattain Member
Karma: 219
Posts: 16504
Don't know what I do
|
 |
« Reply #21 on: December 26, 2012, 05:59:19 pm » |
Scordati di farlo direttamente col 328 a meno che non ti accontenti di bassi valori di frequenza, poche centinaia di Hz. Il solo modo è utilizzare un inverter esterno che ti fornisce il valore negato del PWM e di conseguenza i due pwm tra loro complementari.
Ubi major minor cessat 
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 143
|
 |
« Reply #22 on: December 28, 2012, 05:54:05 am » |
Quindi non esiste il modo con fastpwm per avere su un pin l'uscita che ne so a 40Khz e su un altro invertita?
|
|
|
|
|
Logged
|
|
|
|
|
Rome (Italy)
Offline
Tesla Member
Karma: 74
Posts: 7379
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
|
 |
« Reply #23 on: December 28, 2012, 06:13:44 am » |
Quindi non esiste il modo con fastpwm per avere su un pin l'uscita che ne so a 40Khz e su un altro invertita?
Col PWM hardware no, col PWM software si però vale solo per frequenze molto basse, poche centinaia di Hertz. Hai solo due possibilità, soluzione semplice usare un inverter sul pin pwm per sdoppiare il segnale e ottenere la sua versione negata, soluzione complicata usare un micro che prevede la modalità complementare per il pwm, non mi pare esista su nessuno degli AVR utilizzati per Arduino.
|
|
|
|
|
Logged
|
|
|
|
|
MC
Offline
God Member
Karma: 9
Posts: 670
|
 |
« Reply #24 on: December 28, 2012, 06:22:04 am » |
Mi intrometto per un chiarimento semi off topic, che alla fine non lo è.
Mi sono sempre domandato una cosa, una porta logica invertente non altera in alcun modo (anche se trascurabile) il timing del segnale? Mi riferisco ad un leggero ritardo sui fronti di salita e discesa.
|
|
|
|
|
Logged
|
Vi è una spiegazione scientifica a tutto. La fede è solo quell'anello che si porta al dito dopo il matrimonio.
|
|
|
|
Rome (Italy)
Offline
Tesla Member
Karma: 74
Posts: 7379
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
|
 |
« Reply #25 on: December 28, 2012, 06:29:02 am » |
Mi sono sempre domandato una cosa, una porta logica invertente non altera in alcun modo (anche se trascurabile) il timing del segnale?
Il timing no, inteso come frequenza portante e durata del duty cycle, però introduce un piccolo delay, dovuto al tempo di propagazione della porta, nei cambi fronte della porzione di segnale che passa attraverso la porta. In pratica il pwm che passa attraverso l'inverter cambia di stato con un delay di svariati nanosecondi rispetto al segnale originale, a seconda della frequenza del pwm questa cosa può essere trascurabile oppure può essere necessario compensare con una qualche tipo di linea di ritardo sul pwm originale.
|
|
|
|
|
Logged
|
|
|
|
|
Forum Moderator
Italy
Offline
Brattain Member
Karma: 219
Posts: 16504
Don't know what I do
|
 |
« Reply #26 on: December 28, 2012, 07:14:56 am » |
usare un micro che prevede la modalità complementare per il pwm, non mi pare esista su nessuno degli AVR utilizzati per Arduino.
L'Attiny85 ha 4 uscite PWM di cui 2 collegate allo stesso timer ed invertite l'una rispetto all'altra. Come si vede dalla figura qui sotto, i pin OC1B e /OC1B sono collegati al timer 1 ma con uscita invertita.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 143
|
 |
« Reply #27 on: December 28, 2012, 02:19:51 pm » |
Forse possiamo dire TOPIC RISOLTO Ho trovato un codice in rete di un tizio inglese penso, che ha fatto un modulazione pwm in push pull...allora copio lo sketch e vedo in realtà con l'oscilloscopio che effettivamente una uscita è dritta e una negata...molto bene, ma la frequenza intorno ai 16Khz. Così smanetto un pò e riesco a modificare la frequenza portandola a 50Khz ed inoltre controllo il duty di entrambe in modo indipendente, non come se avessi una sola uscita e l'avessi negata perchè in quel caso avrei che se il duty di una è 90% l'altra è 10%. Invece così vario il duty tramite la variabile count da un minimo di 2% ad un max di 95% circa...aggiustabile a piacimento...però bisogna avere un oscillo perchè se non lo avevo col cavolo che riuscivo solo via software a far combaciare i valori dei reigistri OCR1A e B.. Questo è un semplice controllo pwm molto abbozzato...comunque la parte di variazione di duty funziona. #define PIN_PRI_A 9 // OCR1A - high-active primary drive #define PIN_PRI_B 10 // OCR1B - low-active primary drive
#define PUSH_PULL true // false = OCR1A only, true = OCR1A + OCR1B
#define TIMER1_PRESCALE 1 // clock prescaler value #define TCCR1B_CS20 0x01 // CS2:0 bits = prescaler selection
#define PERIOD_US 20 #define PERIOD_TICKS (microsecondsToClockCycles(PERIOD_US / 2) / TIMER1_PRESCALE)
int count=0; int duty=2; float Verror=0;
float Vset=512.0; float Vact;
unsigned long last=0; unsigned long wait=20; boolean first=true;
void setup() { pinMode(A0, INPUT); //input tensione digitalWrite(A0, LOW); analogWrite(PIN_PRI_A,128); // let Arduino setup do its thing analogWrite(PIN_PRI_B,128);
TCCR1B = 0x00; // stop Timer1 clock for register updates // Clear OC1A on match, P-F Corr PWM Mode: lower WGM1x = 00 TCCR1A = 0x80 | 0x00;
// Configure Timer 1 for Freq-Phase Correct PWM // Timer 1 + output on OC1A, chip pin 15, Arduino PWM9 // Timer 1 - output on OC1B, chip pin 16, Arduino PWM10
// If push-pull drive, set OC1B on match
TCCR1A |= 0x30;
ICR1 = PERIOD_TICKS; // PWM period OCR1A = duty; // ON duration = drive pulse width//ucita 9 OCR1B = duty+156; // ditto - use separate load due to temp buffer reg //usita 10 TCNT1 = OCR1A - 1; // force immediate OCR1x compare on next tick
// upper WGM1x = 10, Clock Sel = prescaler, start Timer 1 running TCCR1B = 0x10 | TCCR1B_CS20; }
void loop() { OCR1A = duty+count; // con count vario il duty delle due uscite nello stesso modo OCR1B = duty+156-count; if(first) { delay(2000); first=false; } Vact=analogRead(A0); Verror=100.0*(Vset-(float)(Vact))/Vset; if(millis()-last>=wait) { last=millis(); if(Verror<0) count--; if(Verror>0) count++;
if(count<0) count=0; //min duty 2% if(count>=70) count=70; //max duty 95% }
}
|
|
|
|
« Last Edit: December 29, 2012, 04:40:46 am by ekjk »
|
Logged
|
|
|
|
|
|