mikrocontroller.net

Forum: Compiler & IDEs Atmega32 + ISR funktioniert nicht


Autor: Storm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich bin noch ziemlicher anfänger in der c- und mikrocontroller 
-programmierung und versuche zur Zeit, eine Servosteuerung mittels 
pwm-signal zu realisieren. Dabei soll Timer2 die pwm-signale erzeugen, 
was auch gut funktioniert. Allerdings möchte ich dem Servo mittels 
timer1 (16-bit-timer) ein gewisses "zeitgefühl" geben, also die 
verschiedenen Servopositionen sollen verschieden lange (zw. 3 und 8 
sek.) angesteuert werden.

Hier Ausschnitte vom Code:
#include <avr/io.h>
#include <stdint.h> //was ist das??
#include <avr/interrupt.h>

struct {
  unsigned Interrupt_BIT_1:1;
} volatile x; 

// Initialisierung für Timer1 
void timer_warte_initial (void) {
  
  TCNT1 = 0x0000;                     //Startwert 0 setzen
  TIMSK = (1<<OCIE1A);            //Output Compare Interrupt enable
  sei();                             //Enable Global Interrupt 
  TCCR1A = 0x00;       
  TCCR1B = ((1<<WGM12) | (1<<CS12));   //CTC-Mode, Prescaler 256
}

//Interrupt-service- Routine
ISR(TIMER1_COMPA_vect) {      //Compare Match A - Vector 
  x.Interrupt_BIT_1 = 1;   
  reti();                    // beendet die ISR
}

int main(void) {
sei();
     
  timer2_initial();
  OCR2 = 0x3A;

  while(1) {
  
 if (ADWert > 624) {
    OCR2 = 0x99; 
    OCR1A = 0x5b8d; // 23437,5 (3 Sek.) Output-compare-register, soll     Interrupt auslösen
    timer_warte_initial();            // startet timer1
 }

  if (x.Interrupt_BIT_1 ==1) {
    OCR2 = 0x19;  
  } 
 }
}

Dazu muss ich noch erwähnen, dass an den AD_wandler ein Abstandssensor 
angeschlossen ist, welcher Werte in ADWert schreibt. Der AD-wandler und 
die gelieferten Werte stimmen aber alle.

also was das Programm manchen soll, ist Folgendes: Wenn der AD-Wandler 
einen Wert >624 liefert, soll die Servoposition 0x99 angefahren werden, 
Timer1 soll gestartet werden, welcher nach 3 Sekunden (OCR1A = 0x5b8d, 
CTC-Mode, Prescaler 256, CPU-Takt 2 MHz) einen Interrupt auslöst.
In der Interrupt-Routine wird die Variable x.Interrupt_BIT_1 auf 1 
gesetzt und die Routine wird verlassen. Im Hauptprogramm wird der Wert 
dieser Varablen abgefragt und wenn der Wert = 1 ist, soll die 
Servoposition
OCR2 = 0x19 angefahren werden.
Das funktioniert aber nicht, irgendwie wird scheinbar die Variable 
x.Interrupt_BIT_1 nie auf 1 gesetzt, denn die position OCR2 = 0x19 wird 
nie angefahren, sondern immer nur die position OCR2 = 0x3A, das 
allerdings nach den gewünschten 3 sek.(s.3.Zeile der main-funktion, wenn 
ich diese Zeile weg lasse, bleibt der Servo allerdings immer in der 
Position OCR2 = 0x99).
Jetzt ist meine Frage warum das nicht funktioniert.
ich hoffe mein Problem ist deutlich geworden und bin für alle Hinweise 
dankbar,
Grüße,
Storm

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das reti() hat in der ISR nichts verloren. Das zerstört dir den Stack.

Autor: gerro (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du mußt das Interrupt_BIT_1 wieder auf 0 setzen.

 if (x.Interrupt_BIT_1 ==1) {
    OCR2 = 0x19;
    x.Interrupt_BIT_1 = 0;
  }


Gerro

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.