PhilSU
09.11.2012, 21:43
Hallo Zusammen : )
Ich arbeite gerade an einem größeren Projekt, in der ich 2 Timer benötige. Timer1 für einen Sekundenzähler, Timer0 zum Tastenentprellen. Dabei ist mir aufgefallen, dass die beiden ISR nicht zusammen laufen.
Zu Testzwecken habe ich mal ein kleines Programm zum Timer-Test gemacht, in der lediglich Variablen hochgezählt werden sollen um dann auf einem Display ausgegeben zu werden. Es handelt sich um einen ATmega64 mit 16MHz.
Die ISR(TIMER0_OVF_vect) läuft nur, wenn das Compare Interrupt Enable Flag von Timer1 deaktiviert ist. Setze ich TIMSK |= (1<<OCIE1A) geht nur die ISR(TIMER1_COMPA_vect). Er zählt nie beide Variablen auf dem Display hoch. Je nach OCIE1A-Bit die eine oder die andere. Es scheint als würden die sich gegenseitig blockieren.
Weiß jemand Rat?
#include <stdint.h> // Standard data types
#include "dogm.h" // Routinen für das DOGM LCD Module
#include <avr/pgmspace.h> // PROGMEM
#include <avr/eeprom.h> // EEPROM
#include <stdlib.h>
#include <stdio.h> // sprintf
#include <inttypes.h>
#include <util/delay.h>
#include <avr/io.h> //I/O Ports
#include <avr/interrupt.h>
//Port und Pinnummer für LEDs:
#define LED1_OFF (PORTG&=~(1<<PG0))
#define LED1_ON (PORTG|=(1<<PG0))
#define LED2_OFF (PORTG&=~(1<<PG1))
#define LED2_ON (PORTG|=(1<<PG1))
#define LED3_OFF (PORTG&=~(1<<PG2))
#define LED3_ON (PORTG|=(1<<PG2))
#define LED4_OFF (PORTG&=~(1<<PG3))
#define LED4_ON (PORTG|=(1<<PG3))
#define LED5_OFF (PORTG&=~(1<<PG4))
#define LED5_ON (PORTG|=(1<<PG4))
static volatile uint8_t DELAY_1 = 0;
static volatile uint8_t DELAY_2 = 0;
// ************************************************** **********
// D E L A Y _ T I M E R S
// ************************************************** **********
ISR(TIMER1_COMPA_vect)
{
char cSREG;
cSREG = SREG;
DELAY_1++;
PORTG ^= ( 1 << PG4 ); //LED5 Blinken
SREG = cSREG;
}
ISR(TIMER0_OVF_vect)
{
char cSREG;
cSREG = SREG;
DELAY_2++;
PORTG ^= ( 1 << PG3 ); //LED5 Blinken
SREG = cSREG;
}
// ************************************************** **********
// M A I N
// ************************************************** **********
int main(void)
{
//Ausgänge
DDRG = 0x1F; //PORTG als Ausgang (LED1-5)
dogm_init(); //Initialisierung DOGM
//Timer1 16Bit
TCCR1B |= (1 << WGM12); //CTC Modus (Mode 4)
TCCR1B |= (1 << CS12) | (1 << CS10); //Prescaler 1024
TCCR1B&=~(1<<CS11);
OCR1A = 15624; //Output Compare: OCR = (Sekunden * FCPU/Prescaler) -1
TIMSK |= (1<<OCIE1A); //<<<<<------ Sobald ich den Interrupt disable funktioniert die ISR des Timer0, ist es enabled, get nur die ISR Timer1
//Timer0 8Bit
TCCR0 |= (1<<CS02)|(1<<CS00); //Prescaler 256 -> t = (2^8 *1024)/16MHz = 4,1ms
TIMSK |= (1<<TOIE0); //Enable timer interrupt
//Für die Ausgabe am DIsplay
char DELAY_CHAR_1[6];
char DELAY_CHAR_2[6];
sei(); //Interrupts aktivieren
while(1)
{
dogm_clear();
//Ausgabe DELAY
dogm_gotoxy(0,1);
itoa (DELAY_1,DELAY_CHAR_1,10);
dogm_puts(DELAY_CHAR_1);
dogm_gotoxy(6,1);
itoa (DELAY_2,DELAY_CHAR_2,10);
dogm_puts(DELAY_CHAR_2);
LED3_ON;
_delay_ms(50);
LED3_OFF;
}
}
Ich arbeite gerade an einem größeren Projekt, in der ich 2 Timer benötige. Timer1 für einen Sekundenzähler, Timer0 zum Tastenentprellen. Dabei ist mir aufgefallen, dass die beiden ISR nicht zusammen laufen.
Zu Testzwecken habe ich mal ein kleines Programm zum Timer-Test gemacht, in der lediglich Variablen hochgezählt werden sollen um dann auf einem Display ausgegeben zu werden. Es handelt sich um einen ATmega64 mit 16MHz.
Die ISR(TIMER0_OVF_vect) läuft nur, wenn das Compare Interrupt Enable Flag von Timer1 deaktiviert ist. Setze ich TIMSK |= (1<<OCIE1A) geht nur die ISR(TIMER1_COMPA_vect). Er zählt nie beide Variablen auf dem Display hoch. Je nach OCIE1A-Bit die eine oder die andere. Es scheint als würden die sich gegenseitig blockieren.
Weiß jemand Rat?
#include <stdint.h> // Standard data types
#include "dogm.h" // Routinen für das DOGM LCD Module
#include <avr/pgmspace.h> // PROGMEM
#include <avr/eeprom.h> // EEPROM
#include <stdlib.h>
#include <stdio.h> // sprintf
#include <inttypes.h>
#include <util/delay.h>
#include <avr/io.h> //I/O Ports
#include <avr/interrupt.h>
//Port und Pinnummer für LEDs:
#define LED1_OFF (PORTG&=~(1<<PG0))
#define LED1_ON (PORTG|=(1<<PG0))
#define LED2_OFF (PORTG&=~(1<<PG1))
#define LED2_ON (PORTG|=(1<<PG1))
#define LED3_OFF (PORTG&=~(1<<PG2))
#define LED3_ON (PORTG|=(1<<PG2))
#define LED4_OFF (PORTG&=~(1<<PG3))
#define LED4_ON (PORTG|=(1<<PG3))
#define LED5_OFF (PORTG&=~(1<<PG4))
#define LED5_ON (PORTG|=(1<<PG4))
static volatile uint8_t DELAY_1 = 0;
static volatile uint8_t DELAY_2 = 0;
// ************************************************** **********
// D E L A Y _ T I M E R S
// ************************************************** **********
ISR(TIMER1_COMPA_vect)
{
char cSREG;
cSREG = SREG;
DELAY_1++;
PORTG ^= ( 1 << PG4 ); //LED5 Blinken
SREG = cSREG;
}
ISR(TIMER0_OVF_vect)
{
char cSREG;
cSREG = SREG;
DELAY_2++;
PORTG ^= ( 1 << PG3 ); //LED5 Blinken
SREG = cSREG;
}
// ************************************************** **********
// M A I N
// ************************************************** **********
int main(void)
{
//Ausgänge
DDRG = 0x1F; //PORTG als Ausgang (LED1-5)
dogm_init(); //Initialisierung DOGM
//Timer1 16Bit
TCCR1B |= (1 << WGM12); //CTC Modus (Mode 4)
TCCR1B |= (1 << CS12) | (1 << CS10); //Prescaler 1024
TCCR1B&=~(1<<CS11);
OCR1A = 15624; //Output Compare: OCR = (Sekunden * FCPU/Prescaler) -1
TIMSK |= (1<<OCIE1A); //<<<<<------ Sobald ich den Interrupt disable funktioniert die ISR des Timer0, ist es enabled, get nur die ISR Timer1
//Timer0 8Bit
TCCR0 |= (1<<CS02)|(1<<CS00); //Prescaler 256 -> t = (2^8 *1024)/16MHz = 4,1ms
TIMSK |= (1<<TOIE0); //Enable timer interrupt
//Für die Ausgabe am DIsplay
char DELAY_CHAR_1[6];
char DELAY_CHAR_2[6];
sei(); //Interrupts aktivieren
while(1)
{
dogm_clear();
//Ausgabe DELAY
dogm_gotoxy(0,1);
itoa (DELAY_1,DELAY_CHAR_1,10);
dogm_puts(DELAY_CHAR_1);
dogm_gotoxy(6,1);
itoa (DELAY_2,DELAY_CHAR_2,10);
dogm_puts(DELAY_CHAR_2);
LED3_ON;
_delay_ms(50);
LED3_OFF;
}
}