Forum: Mikrocontroller und Digitale Elektronik Atmega88: Frage zum Overflow-ISR


von Michael (Gast)



Lesenswert?

Ich hab da mal ein kleines, merkwürdiges Verhalten.

Ich will zwei Schrittmotoren (später mit unterschiedlicher 
Geschwindigkeit) ansteuern. Dazu hab ich ne Platine auf der ich die 
Drehrichtung, den Takt und ein Enable-Signal mittels TTL vorgeben kann.

Da die Motoren später unterschiedlich schnell sein sollen und die Timer 
sonst nicht gebraucht werden habe ich jedem Motor seinen eigenen Timer 
geschenkt und toggel schlichtweg den entsprechenden Pin des jeweiligen 
Motors im jeweiligen Timer-Overflow.

Die Motoren sollen nur eine bestimmte Weite fahren, daher hab ich eine 
Variable angelegt in der ich die Takte zähle und vergleiche diese mit 
einer anderen Variablen in der die Takte stehen, die gemacht werden 
sollen.

Mein Problem ist nun in den Bildern zu sehen: Bei den ISRs mit der 
Schleife entsteht das erste Bild 
(Bildschirmfoto_2011-03-26_um_09.06.37.png). Kommentiere ich die 
Schleifen raus entsteht das zweite Bild was auch meiner Erwartung 
entspricht: Beide Signale sind gleich.

Die Bilder zeigen den Takt an den jeweilgen Pins. Oben (blau) ist der 
Takt der durch Timer1 erzeugt wird, unten (gelb) ist Timer2.

Ich hätte eigentlich erwartet, dass beide Signale gleich aussehen aber 
wie man sehen kann ist das Signal von Timer1 mit den Schleifen deutlich 
unterschiedlich zu dem anderen und mich verwirrt die. Wo kommt das her 
und warum ist das so? Ich steh hier irgendwie auf dem Schlauch und bin 
mir aber sicher, dass es hier jemanden gibt der Rat weiß.

Grüße Michael

Fusebits:   Extended: 0xF9, High: 0xDF, Low: 0xCE

Quelltext:
1
#define F_CPU 8000000L  //Taktfrequenz in Hz
2
#include <avr/io.h>
3
#include <avr/interrupt.h>
4
#include <avr/wdt.h>
5
6
//Definitionen
7
//    Bezeichnung    µC-Pin    Funktion
8
// Schlittenmotor
9
#define Motor1_Speed   PB1      //Output
10
#define Motor1_Richtung  PC0      //Output
11
#define  Achse_End    PD2      //Input
12
#define  Achse_Home    PD3      //Input
13
#define Motor1_Start  PD4      //Input
14
#define Motor1_EN    PD5      //Output
15
16
// Wendelmotor
17
#define Motor2_Speed   PB2      //Output
18
#define  Motor2_Start  PB3      //Input
19
#define  Motor2_EN    PB4      //Output
20
21
#define RTS        PD6      //Input
22
#define CTS        PD7      //Output
23
24
//sonstige Definitionen und Einstellungen
25
#define BAUDRATE    9600L    //Baudrate einstellen
26
27
volatile uint8_t TIMERLADEWERT0 = 248;    //Frequenzvoreinstellung für ca. 2kHz
28
volatile uint16_t TIMERLADEWERT1 = 65528;  //Frequenzvoreinstellung für ca. 2kHz
29
volatile uint16_t Motor1_Count = 0;
30
volatile uint16_t rounds_Motor1 = 400;
31
volatile uint16_t Motor2_Count = 0;
32
volatile uint16_t rounds_Motor2 = 400;
33
34
int main (void) {
35
36
  
37
38
39
  //Watchdog aus
40
  wdt_disable();
41
  
42
  //Ausgänge definieren
43
  DDRB |= ((1 << Motor1_Speed) | (1 << Motor2_Speed) | (1 << Motor2_EN));
44
  DDRC |= (1 << Motor1_Richtung);
45
  DDRD |= ((1 << Motor1_EN)|(1 << CTS));
46
  
47
  //Zähler konfigurieren für Motor Vorschub
48
  TCCR0B |= (1 << CS02);      //Prescaler auf 256
49
  TCNT0 = TIMERLADEWERT0;  //Wert vorladen
50
  TIMSK0 |= (1 << TOIE0);      //Overflow_ISR Zähler 0 aktivieren
51
52
  //Zähler konfigurieren für Motor Drehen
53
  TCCR1B |= (1 << CS12);      //Prescaler auf 256
54
  TCNT1 = TIMERLADEWERT1;  //Wert vorladen
55
  TIMSK1 |= (1 << TOIE1);      //Overflow_ISR Zähler 1 aktivieren
56
57
  //interrupts an
58
  sei();
59
60
61
  while(1) {
62
63
  }
64
}
65
66
ISR(TIMER0_OVF_vect){
67
//  if(Motor1_Count < rounds_Motor1){
68
    PORTB ^= (1 << Motor1_Speed);
69
    TCNT0 = TIMERLADEWERT0;  //Wert vorladen
70
    Motor1_Count++;
71
/*  }
72
  else{
73
  
74
    PORTB &= ~(1 << Motor1_EN);
75
    Motor1_Count = 0;
76
  }*/
77
}
78
ISR(TIMER1_OVF_vect){
79
  if(Motor2_Count < rounds_Motor2){
80
    PORTB ^= (1 << Motor2_Speed);
81
    TCNT1 = TIMERLADEWERT1;  //Wert vorladen
82
    Motor2_Count++;
83
  }
84
  else{
85
  
86
    PORTB &= ~(1 << Motor2_EN);
87
    Motor2_Count = 0;
88
  }
89
}

von Stefan E. (sternst)


Lesenswert?

Im else-Zweig wird der Timer nicht vorgeladen, also entsteht eine 
längere Pause bis zum nächsten Overflow. Und bei Timer1 ist diese Pause 
dann VIEL länger als bei Timer0.

Wieso überhaupt Vorladen? Beide Timer unterstützen den CTC-Mode.

von Michael (Gast)


Lesenswert?

Stefan Ernst schrieb:
> Wieso überhaupt Vorladen? Beide Timer unterstützen den CTC-Mode.

Weil ich mich damit nicht auskenne aber schon am "basteln" damit bin 
(Google mich grad durchs Netz)...das mit der Else ist mir irgendwie 
entgangen...da war ich wieder betriebsblind. Dank dir schonmal.

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.