Sto cercando di utilizzare Timer1 del microcontrollore Atmel AVR, AtMega328 come utilizzato in Arduino o ATTiny85, per emettere due segnali di clock che sono immagini speculari l'uno dell'altro. La frequenza che sto cercando di generare è una variabile da 1 MHz a 2 MHz o più che è troppo alta per farlo usando il codice per attivare / disattivare i pin di uscita a meno che non voglia fare quasi nient'altro nel controller. Quindi voglio usare l'uscita del timer direttamente sui pin associati. Sto usando la toolchain di GCC, quindi non limitato dalle librerie o dal linguaggio di Arduino.
Timer1 nell'Atmega328 ha due pin associati e posso ottenere due segnali identici da 1 MHz a 2 MHz. Anche se il foglio dati sembra dire che posso ottenere una forma d'onda invertita, mi confonde. Sono anche in grado di ottenere due segnali che sono cicli di lavoro diversi a 1 MHz, utilizzando le impostazioni PWM con Timer1, ma entrambi i segnali aumentano contemporaneamente, mentre quello più breve si abbassa prima. Questo non serve al mio progetto. Non ho nemmeno bisogno della variazione dell'ampiezza dell'impulso PWM, ho solo bisogno di due segnali identici di tipo "clock" di fase opposta, tutto qui.
Non sto chiedendo a nessuno di scrivere codice per farlo, ho solo bisogno di qualcuno che mi dica quale modalità / flag del timer dovrebbe darmi una semplice forma d'onda invertita su uno dei due pin associati al timer. Se possibile, voglio evitare di utilizzare un circuito di inversione esterno per una delle uscite, a meno che questa non sia l'unica opzione.
Se ciò è possibile in ATTiny, sarà ancora meglio. ATTiny ha anche 2 pin associati a un timer, ma non sono sicuro che abbia le stesse opzioni di ATMega.
Ho già un cristallo da 20 MHz e condensatori collegati sul PCB e l'orologio da 20 MHz funziona in modo affidabile su ATMega328. Sul PCB ATTiny85 ho un cristallo da 8 MHz e anche questo funziona in modo affidabile.
Per favore aiuto. Grazie.
AGGIORNAMENTO : Finora ci sono alcune ipotesi non valide nelle risposte e nei commenti, quindi forse dovrei chiarire: nota che nel mio post originale ho dichiarato che sto usando un clock a 20 MHz, non 8 MHz , e anche che non ho bisogno di PWM .
L'unica modalità che fornisce una frequenza di uscita sufficientemente elevata sembra essere la modalità CTC perché le modalità PWM non funzionano per l'uscita a 2 MHz. Esiste un modo per invertire l'uscita A del timer 1 o l'uscita B in modalità CTC?
Ora sono passato ad un Arduino Uno standard (ATMega328, 16 MHz) invece della mia scheda da 20 MHz per controllare il mio codice, e questo è il mio codice per un bel orologio stabile da 2 MHz in modalità CTC dai pin 9 e 10, il Timer 1 pin di uscita:
#define tick 9
#define tock 10
void setup() {
pinMode(tick, OUTPUT);
pinMode(tock, OUTPUT);
TCCR1A = _BV(COM1A0) | _BV(COM1B0) ; // activate both output pins
TCCR1B = _BV(WGM12)| 1; // set CTC mode, prescaler mode 1
// various frustrating attempts to invert OC1B failed. What do I put here?
OCR1A = 3; // set the counter max for 2 MHz
}
void loop() {
}
Le tracce dell'oscilloscopio per entrambi i pin sono identiche e sincronizzate, come posso invertire uno dei due segnali? La modalità di inversione nel foglio dati sembra non fare nulla in modalità CTC. Sto leggendo il foglio dati in modo errato, o sarò costretto a utilizzare una frequenza più bassa e la modalità PWM dopo tutto?
Per aggiungere una domanda "bounty" specifica alla mia query originale:
Quindi quali modifiche devo apportare al mio codice sopra, per fargli dare segnali perfettamente invertiti ai pin 9 e 11 alla massima frequenza possibile per un clock a 16 MHz , sia che che è 2 MHz o no?
Continuerò con un Arduino Uno standard per ora, in modo che non ci sia modalità di errore introdotta dalla mia scheda homespun e in modo che chiunque abbia un arduino possa provare il mio codice sopra e confermare che funziona come ho già detto e non come bisogno!