U001
30.10.2016, 00:19
Liebe Forengemeinde,
nachdem ich mehrere Abende vergeblich versucht habe, den Fehler in meinem Programm zu finden, bitte ich ergebenst um Hilfe:
(ich bin Anfänger beim Mikroprozessor-Programmieren)
Ich verwende einen Arduino mit Atmega328P und das AtmelStudio 7 zum Programmieren.
Mit dem Timer1 möchte ich ein PWM-Signal erzeugen mit 500ms Taktzeit. Am PortB Pin1 soll 25% rauskommen und am PortB Pin2 75% Tastverhältnis. Um das Arbeiten des OCIE1A-Interrupts zu testen, will ich zusätzlich am PortB Pin4 eine LED im gleichen Takt wie am PortB Pin2 blinken lassen.
Das Programm sieht so aus:
# define F_CPU 16000000UL //CPU-Frequenz
#define PRESCALER 256
#define MS500 F_CPU/PRESCALER/1000 * 500
void INITialisierung(void)
{
//Wir verwenden den Timer1, der auf die Pins 9 und 10 des Arduino geht
DDRB |= (1<<DDB1) |(1<<DDB2)|(1 << DDB4);
// PB1, PB2 and PB4 are now output
// Entspricht PIN9, 10 und 12 am Arduino
ICR1 = MS500;
// set MAX auf 500ms
OCR1A = MS500/5;
// set PWM for 20% duty cycle @ 16bit
OCR1B = MS500/4*3;
// set PWM for 75% duty cycle @ 16bit
// Setzen Modus 14... Fast PWM mit Timerruecksetzen bei OCR1A-Vergleich und ICR1 als MAXwert)
TCCR1A |= (1<<WGM11)|(1 << COM1A1)|(1 << COM1B1);
TCCR1B |= (1<<WGM12)|(1<<WGM13);
TIMSK1 |= (1<<OCIE1A); //enable Interrupt bei OCR1A-Vergleich
TCCR1B |= (1<<CS12);
// START the timer with prescaler 256
// Ein Timertick ist dann 16 µs
sei();
}
ISR(TIMER1_COMPA_vect)
{
PORTB ^= (1 << PB4); //Pin12 Togglen
}
int main(void)
{
INITialisierung();
while (1){}
}
Das Programm funktioniert insoweit, als am Pin 1 und 2 des PortB die richtigen Signale ankommen.
Am Pin4 des PortB entsteht jedoch ein PWM-Signal mit 500ms High und 500ms Low. D.h. die ISR wird nicht beim Compare-Match aufgerufen, sondern beim Rücksetzen des Timers beim Erreichen des ICR1-Registerwertes.
Hat jemand eine Erklärung für dieses Verhalten?
Das Programm hier ist nur ein Testprogramm, später möchte ich in der ISR das Register OCR1A beschreiben und so die Pulsweite des PWM-Signals aktualisieren.
Danke schon mal...
Gruß Alfred
nachdem ich mehrere Abende vergeblich versucht habe, den Fehler in meinem Programm zu finden, bitte ich ergebenst um Hilfe:
(ich bin Anfänger beim Mikroprozessor-Programmieren)
Ich verwende einen Arduino mit Atmega328P und das AtmelStudio 7 zum Programmieren.
Mit dem Timer1 möchte ich ein PWM-Signal erzeugen mit 500ms Taktzeit. Am PortB Pin1 soll 25% rauskommen und am PortB Pin2 75% Tastverhältnis. Um das Arbeiten des OCIE1A-Interrupts zu testen, will ich zusätzlich am PortB Pin4 eine LED im gleichen Takt wie am PortB Pin2 blinken lassen.
Das Programm sieht so aus:
# define F_CPU 16000000UL //CPU-Frequenz
#define PRESCALER 256
#define MS500 F_CPU/PRESCALER/1000 * 500
void INITialisierung(void)
{
//Wir verwenden den Timer1, der auf die Pins 9 und 10 des Arduino geht
DDRB |= (1<<DDB1) |(1<<DDB2)|(1 << DDB4);
// PB1, PB2 and PB4 are now output
// Entspricht PIN9, 10 und 12 am Arduino
ICR1 = MS500;
// set MAX auf 500ms
OCR1A = MS500/5;
// set PWM for 20% duty cycle @ 16bit
OCR1B = MS500/4*3;
// set PWM for 75% duty cycle @ 16bit
// Setzen Modus 14... Fast PWM mit Timerruecksetzen bei OCR1A-Vergleich und ICR1 als MAXwert)
TCCR1A |= (1<<WGM11)|(1 << COM1A1)|(1 << COM1B1);
TCCR1B |= (1<<WGM12)|(1<<WGM13);
TIMSK1 |= (1<<OCIE1A); //enable Interrupt bei OCR1A-Vergleich
TCCR1B |= (1<<CS12);
// START the timer with prescaler 256
// Ein Timertick ist dann 16 µs
sei();
}
ISR(TIMER1_COMPA_vect)
{
PORTB ^= (1 << PB4); //Pin12 Togglen
}
int main(void)
{
INITialisierung();
while (1){}
}
Das Programm funktioniert insoweit, als am Pin 1 und 2 des PortB die richtigen Signale ankommen.
Am Pin4 des PortB entsteht jedoch ein PWM-Signal mit 500ms High und 500ms Low. D.h. die ISR wird nicht beim Compare-Match aufgerufen, sondern beim Rücksetzen des Timers beim Erreichen des ICR1-Registerwertes.
Hat jemand eine Erklärung für dieses Verhalten?
Das Programm hier ist nur ein Testprogramm, später möchte ich in der ISR das Register OCR1A beschreiben und so die Pulsweite des PWM-Signals aktualisieren.
Danke schon mal...
Gruß Alfred