Forum: Mikrocontroller und Digitale Elektronik Seltsames Verhalten bei verschiedenen Timer Prescalern-Atmega 328P


von Andre (Gast)


Lesenswert?

Hallo,

ich bin beim Programmieren auf ein Problem gestossen, welches ich mir 
nicht erklären kann. Würde es allerdings gern verstehen wollen.

Für mein STK500 habe ich folgendes programmiert: Ein Taster an PD0 wird 
zyklisch abgefragt (gesteuert durch Timer2) und schaltet eine LED an PB0 
ein und aus und setzt die Interuptfreigabe vom Timer0.

An der LED an PB1 wird die die Timer2 Frequenz ausgeben.Das klappt 
immer.

Wenn ich den Prescaler von Timer0 auf 1/64 setze, klappt alles wie 
gewünscht,
bei jedem Tastendruck wird die LED an PB0 getoggelt.

Setze ich den Prescaler an Timer0 auf 1/1024, funktioniert das nicht 
nicht mehr. Die Led geht beim Tastendruck kurz aus und dann sofort 
wieder an.

Und dieses Verhalten kann ich mir nicht erklären. Ich bin davon 
ausgegangen, dass ein größerer Prescaler nur dazu führt, das der OCR0A 
Interrupt von Timer0 seltener kommt. Und das sollte keine Auswirkung auf 
das restliche Programm haben. Zumal der ISR dazu gar nicht programmiert 
ist.

Aber irgendwas scheine ich zu übersehen bzw nicht zu wissen. Hat dazu 
jemand eine Erklärung?

MfG Andre
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
/* jflags*/
5
#define taster_einlesen 0
6
#define Rampe 1
7
8
/* tflags */
9
#define pwm_start 0
10
11
12
13
/* Globale Variablen*/
14
15
volatile uint8_t jflags = 0;
16
volatile uint8_t tflags = 0;
17
volatile uint8_t taster_old = 0;
18
volatile uint8_t Rampenschritt = 0;
19
volatile uint16_t Schrittzaehler = 0;
20
21
22
volatile uint8_t hochlauframpe[86] = {255,255,106,106,81,81,68,68,60,60,54,54,50,50,47,47,44,44,41,41,39,39,38,38,37,37,36,36,35,35,34,34,33,33,32,32,31,31,30,30,
23
                     29,29,28,28,27,27,26,26,25,25,24,24,23,23,22,22,21,21,20,20,19,19,18,18,17,17,16,16,15,15,14,14,13,13,12,12,11,11,10,10,9,9,8,8,7,7};
24
  
25
26
ISR(TIMER2_COMPA_vect)
27
{
28
  cli();
29
  jflags |= (1<<taster_einlesen);
30
  PORTB ^= (1<<PB1);
31
  sei();
32
}
33
void _taster_einlesen()
34
{
35
  jflags &= ~(1<<taster_einlesen);  //Jobflag löschen
36
  uint8_t taster_new;    //Hilfsvariable1
37
  uint8_t taster_temp;    //Hilfsvariable2
38
  taster_new = (PIND & (1<<pwm_start));
39
  taster_temp = taster_new;
40
  taster_new &= ~(taster_old);  // Auf steigende Flanke prüfen
41
  
42
  tflags = taster_new;    // Taster flags schreiben
43
  taster_old = taster_temp;
44
}
45
void _setup()
46
{
47
  // Timer0 initialisieren
48
  TCCR0A |= (WGM01);
49
  TCCR0B |= ((1<<CS02) | (1<<CS00));    //Prescaler 64
50
  OCR0A = hochlauframpe[0];
51
  
52
  //Timer2 initialisieren (10ms)
53
  TCCR2A |= (1<<WGM21);      //CTC Modus
54
  TCCR2B |= ((1<<CS20) | (1<<CS21) | (1<<CS22));  //Prescaler 1024
55
  OCR2A = 77;
56
  TIMSK2 |= (1<<OCIE2A);      //Timer2 aktivieren
57
  sei();
58
  
59
  //Ein- und Ausgänge initialisieren
60
  DDRB = 0xFF;                        //PORTB als Ausgänge
61
  PORTB = 0xFF;
62
  
63
  DDRC = 0xFF;                        //PortC als Ausgänge
64
  PORTC = 0xFF;
65
  
66
  DDRD = 0x00;                        //PORTD als Eingänge
67
}
68
69
int main(void)
70
{
71
  
72
  _setup();
73
  
74
  while (1)
75
  {
76
    if(jflags &= (1<<taster_einlesen))
77
    {
78
      _taster_einlesen();
79
    }
80
    
81
    if(tflags &= (1<<pwm_start))
82
    {
83
      tflags &= ~(1<<pwm_start);
84
      jflags |= (1<<Rampe);
85
      PORTB ^= (1<<PB0);
86
      TIMSK0 ^= (1<<OCIE0A);
87
    }
88
    
89
  }
90
}

von Peter D. (peda)


Lesenswert?

Andre schrieb:
> TIMSK0 ^= (1<<OCIE0A);

Interruptfreigabe ohne Handler bewirkt ein Restart (jump 0x0000).

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.