Usart + Timer Interrupt Problem

OP #2842071
Hallo,
ich komme direkt zu meinem Problem: Es ist mir nicht möglich Zeichen 
über die USART Schnittstelle einzulesen und im Anschluss einen Timer 
laufen zu lassen.
Es handelt sich dabei um einen XMEGA128A3.
Ich lese via USART Schnittstelle Zeichen wie folgt ein
1
char usart_getc(void)
2
{
3
  char c;
4
  while (!( USARTF0.STATUS & USART_RXCIF_bm));
5
  c=USARTF0.DATA;
6

7
  return(c);
8
}
Lese ich nun ein oder mehrere Zeichen ein, so wird mein Timer overflow 
Interrupt im Anschluss nicht mehr ausgelöst.

Hat jemand eine Idee worran es liegen oder wie ich das Problem umgehen 
könnte?
OP
Die USART Schnittstelle initialisiere ich wie folgt
1
void USART_Init_intern(void) 
2
{
3
  // BSEL ausrechnen, Berechnung siehe Datenblatt Seite 238 (bscale = -5)
4
  // Berechnung für internen Oszillator f=32 MHz, RS232 Geschwindigkeit 256K0
5
  USARTF0.BAUDCTRLA = 218&0xff;          // siehe Seite 254 Datenblatt
6
  USARTF0.BAUDCTRLB = (-5<<4)|(218>>8);       // siehe Seite 254 Datenblatt
7
  USARTF0.CTRLA = 0x30;                 // USART_RXCINTLVL_HI_gc;   //RX interrupt high level
8
    USARTF0.CTRLB = 0x18;              // RX und TX enable, siehe Seite 251
9
    USARTF0.CTRLC = 0x03;              // Datenformat einstellen, ansynchron, keine Parity, 1 Stop-Bit, 8 Daten-Bits siehe Seite 252 ff
10
  PORTF.DIR |= (1<<PIN3); 
11
  PORTF.DIR &= ~(1<<PIN2); 
12
  PMIC.CTRL |= 0x04;              //set PMIC high level enable
13
}

Den Timer wie folgt
1
TCC0_INTCTRLA = TC_OVFINTLVL_HI_gc;  // enable interrupt

Routine
1
void move(uint16_t step)
2
.
3
.
4
.
5
  // start counter
6
  TCC0_CTRLA = TIMER_PRESCALE_gc;
7

8
  // acceleration phase
9
  accel_function = accelerate;
10
  while ( steps > threshold_2 )
11
  {
12
    TCC0_PER = accel_function();  // set new timer value
13
    while ( !timer_ovf );  // wait for timer
14
    CHOPPER_STEP();
15
  }

Timer Interrupt
1
ISR( TCC0_OVF_vect )
2
{
3
  timer_ovf = TRUE;
4
}

Meine main sieht wie folgt aus:
1
        Verschiedene Variablien Deklarationen
2
        .
3
        .
4
  clock_intern_32(); //Interner 32Mhz Oszillator
5
  USART_Init_intern();
6
  inputs_Init();  //Input Ports
7
  outputs_Init(); //Output Ports
8
        SPI_INIT_E();   //ADC Schnitstelle
9
  STEPPERMODE();  //Motor
10
  pullup();  //Pullup Widerstand
11
  init_move();    //Timer Initialisierung
12
  sei();
13
        while(1)
14
        {  
15
                switch((int)usartgetc())
16
                {
17
                  case '1':
18
        
19
                    CW();
20
                    move(15000);
21
                    CCW();
22
                    move(15000);
23
                }    
24
        }

Rufe ich usartgetc vorher nicht auf, funktioniert alles wunderbar, 
leider aber bin ich auf Benutzereingaben angewiesen.
Mit usart... hängt meine Routine move()... an
1
while ( !timer_ovf );
 da es nicht mehr zum Timer Interrupt kommt.

Ich hoffe ich konnte euch das Problem damit näher bringen
Slawa Kabanovic schrieb:


> Mit usart... hängt meine Routine move()... an
1
while ( !timer_ovf
2
> );
 da es nicht mehr zum Timer Interrupt kommt.

bist du sicher, dass das programm an dieser stelle hängt un nicht 
einfach nur hier drinnen?
1
char usart_getc(void)
2
{
3
  char c;
4
  while (!( USARTF0.STATUS & USART_RXCIF_bm));
5
  c=USARTF0.DATA;
6

7
  return(c);
8
}

Sprich: Hast du kontrolliert, ob du von der USART ein Zeichen bekommst 
und wenn ja, welches das ist?
OP
Karl Heinz Buchegger schrieb:
> Sprich: Hast du kontrolliert, ob du von der USART ein Zeichen bekommst
> und wenn ja, welches das ist?

Ich bin mir sogar sehr sicher, da bei richtiger Eingabe in die 
Switch-Case Anweisung/Schleife gesprungen wird und ich per Ausgabe via 
USART getestet habe an welcher Stelle das Programm hängt.

Karl Heinz Buchegger schrieb:
> timer_ovf ist hoffentlich volatile definiert?

Kann ich leider erst morgen genauer sagen, weil ich gerade wieder zu 
hause bin. Wenn es daran scheitern sollte, warum hat das Ganze dann aber 
ohne USART so wunderbar geklappt?
OP
Ich werde gleich weiter an meinem Problem Arbeiten und timer_ovf auf 
volatile prüfen, auch wenn nicht denke das es daran liegt.
Ich kann mir im Grunde nur vorstellen, dass
> while (!( USARTF0.STATUS & USART_RXCIF_bm));
irgendwie im Konflikt mit dem Timerinterrupt steht, kann das sein? Lasse 
ich nämlich die USART-Funktion weg, klappt das ganze wunderbar.
OP
Ich habe den Fehler inzwischen gefunden es lag an der Initialisierung 
der USART Schnittstelle
1
USARTF0.CTRLA = 0x30;  // USART_RXCINTLVL_HI_gc;   //RX interrupt high level
Da ich auf den Interrupt nicht angewiesen war/bin, habe ich auch nicht 
daran gedacht ihn zu definieren, hätte also entweder eine leere 
Interruptroutine erstellen müssen oder aber den Interrupt ausstellen mit
1
USARTF0.CTRLA = USART_RXCINTLVL_OFF_gc;
Ich bedanke mich bei den Helfern, der Thread kann geschlossen werden 
/closed

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 14 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.