Ist es möglich, Timer1 auf einem ATMega zu verwenden, um einen Vergleichs-Interrupt auf OCR1A und einen PWM-Ausgang auf OCR1B zu erzeugen? Ich habe es ähnlich wie folgt versucht, aber beides funktioniert nicht mit allem, was ich versucht habe.
TCCR1A = _BV(COM1B1) | _BV(WGM11) | _BV(WGM10);
TCCR1B = PRESCALE1_8;
OCR1B = 0;
// set compare match register for 1000Hz
OCR1A = 2000;
// turn on CTC mode
TCCR1B |= _BV(WGM12);
Nebenbemerkung: Ich weiß, dass dies einer anderen meiner eigenen Fragen sehr ähnlich ist , aber das betraf PWM bei einem Timer und Interrupts bei einem anderen. Diesmal habe ich Probleme, beide aus dem GLEICHEN Timer zu bekommen.
Ihr Code setzt den Zähler für den phasenrichtigen PWM-Betrieb mit dem Höchstwert 0x3FF, sodass das erste Problem, mit dem Sie konfrontiert werden, darin besteht, dass die Interrupts zum Vergleichen von Übereinstimmungen aufgrund der Funktionsweise dieses Modus, der nach oben zählt, nicht in gleichen Intervallen ausgelöst werden dann Richtung ändern und rückwärts zählen.
Das andere Problem ist, dass der Zähler bis 1023 (0x3ff) und zurück auf 0 zählt, sodass es keine Möglichkeit gibt, jemals einen Match-Interrupt für einen Wert von 2000 (OCR1A = 2000) zu erhalten.
phasenrichtiger PWM-Betrieb:
Dies ist ein Mindestcode für Mega328, der bei 16 MHz läuft, der Timer 1 so einstellt, dass er eine schnelle PWM mit einer Frequenz von etwa 1 kHz erzeugt (Frequenz von ICR1 eingestellt und Tastverhältnis von OCR1B eingestellt) und auch einen Timer 1-Überlauf-Interrupt mit einer Rate von 1 kHz ausgibt
#include <avr/io.h>
#include <avr/interrupt.h>
// Timer1 overflow interrupt service routine
ISR(TIMER1_OVF_vect)
{
PORTB ^= 1; // invert PORTB.0
}
int main(void)
{
// Port B initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=Out Bit1=In Bit0=Out
DDRB = 0x05;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 2000,000 kHz
// Mode: Fast PWM top=ICR1
// OC1A output: Disconnected
// OC1B output: Non-Inverted PWM
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer Period: 1,0245 ms
// Output Pulse(s):
// OC1B Period: 1,0245 ms Width: 0,12806 ms
// Timer1 Overflow Interrupt: On
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A = (0 << COM1A1) | (0 << COM1A0) | (1 << COM1B1) | (0 << COM1B0) | (1 << WGM11) | (0 << WGM10);
TCCR1B = (0 << ICNC1) | (0 << ICES1) | (1 << WGM13) | (1 << WGM12) | (0 << CS12) | (1 << CS11) | (0 << CS10);
TCNT1 = 0;
ICR1 = 2048;
OCR1A = 0;
OCR1B = 256;
// Timer/Counter 1 Interrupt(s) initialization
TIMSK1 = (0 << ICIE1) | (0 << OCIE1B) | (0 << OCIE1A) | (1 << TOIE1);
// Global enable interrupts
sei();
while(1)
{
// Place your code here
}
}
Adam Haile
alexan_e
Adam Haile
alexan_e
Adam Haile
alexan_e
Adam Haile
alexan_e
TCCR1A = _BV(WGM11) | _BV(WGM10);
PWM, Phase Correct, 10-Bit , diese 10 Bit bedeuten, dass der TOP-Wert 0x03FF ist (es steht im Datenblatt) und stellt tatsächlich die PWM-Frequenz ein.Adam Haile
Adam Haile
alexan_e
TIMSK1=(1<<TOIE1);
und fügen Sie den Interrupt-Handler hinzu. Er wird jedes Mal mit einer Rate von 917 Hz aufgerufen, wenn der Zähler den unteren Rand (0) erreicht. Timer2 ist unabhängig von Timer1, keiner der oben genannten Effekte wirkt sich darauf aus.Adam Haile
alexan_e
alexan_e
David Norman
alexan_e
David Norman
alexan_e
David Norman