Interrupt in Endlosschleife

OP #2208005
Lesenswert?
• ▲
▼
Hallo,

ich hab ein Problem mit meinen Interrupt. Er soll auslösen, sobald ein 
Zeichen über die UART empfangen wird. Das funktionert, doch wenn er 
einmal in der ISR-Routine ist, verlässt er diese nicht mehr und sendet 
den Text "Interrupt immer und immer weider. Ich versende lediglich ein 
einziges Zeichen. Ich hab schon einige Befehle durchprobiert, doch ich 
kriege das nicht hin. Was mache ich falsch ?


Gruss

1
#define F_CPU 3686400      //Taktfrquenz
2
#define BAUD 9600        //einstellte Baudrate
3
//-----------------------------
4
#include <string.h>
5
#include <stdio.h>
6
#include <stdlib.h>
7
#include <avr\io.h>
8
#include <avr\delay.h>
9
#include <avr/interrupt.h>
10
//----------------------------------------------------------------------
11
void Senden(char buffer[]);
12
void Debug(char buffer[]);
13
//----------------------------------------------------------------------
14

15
void initPorts() 
16
{
17
  DDRB   = 11111111;                     // PORTB = Ausgang
18
  DDRC   = 11111111;                     // PORTC = Ausgang
19
  DDRD   = 00000000;                     // PORTD = Eingang
20
  PORTD  = 00001000;              // PORTD = PULL-UP für den Taster
21
}
22

23
void initUART() 
24
{
25
  UBRRL  = (F_CPU / BAUD - 16) / 16;    //Baudberchnnung
26
  UCSRB  = 0x98;                   //Transmitter/Receiver/Receiver Interrupt Enable
27
  sei();                  // Interrupts zulassen
28
}
29

30
ISR(USART_RXC_vect) 
31
{
32
  Debug("Interrupt");
33
}
34

35
//----------------------------------------------------------------------
36
void putChar(char data) 
37
{
38
  while (!(UCSRA&32));        //warte bis UDR leer ist
39
  UDR = data;              //senden
40
}
41
//----------------------------------------------------------------------
42
char getChar()
43
{
44
  char data=0;
45
  while (!(UCSRA&128)); //warte bis RX-complete RXC UCSRA
46
  data=UDR; //empfangen
47

48
  return data;
49
}
50
//----------------------------------------------------------------------
51
void Senden(char buffer[]) 
52
{
53
  for (int i=0 ; buffer[i] !=0 ; i++)
54
    putChar(buffer[i]);
55
}
56

57
void Debug(char buffer[])
58
{
59
  Senden(buffer);
60
}
61

62
//----------------------------------------------------------------------
63
//----------------------------------------------------------------------
64
main()
65
{
66
  initPorts();
67
  initUART();
68

69
  int i=0;
70
  char text[5];
71
  do
72
  {
73
    /*
74
    char zeichen;
75
    zeichen = getChar();
76
    text[i] = getChar();
77
    i++;
78
    */
79

80
    //Debug ("main");
81
    //wenn 5 Zeichen (z.B. BTR1C) geschrieben sind, wird die variable zurückgesetzt
82
    if(i==5) 
83
    {
84
      i=0;
85

86
      if (text[3] == '1') 
87
      {
88
        PORTB |= (1 << PB0);
89
        Senden("BTR11A\n");
90

91
        waitMs(1000);
92
        PORTB &= ~(1 << PB0);
93
        Senden("BTR10A\n");
94
      }
95

96
      if (text[3] == '2') 
97
      {
98
        PORTB |= (1 << PB1);
99
        Senden("BTR21A\n");
100

101
        waitMs(1000);
102
        PORTB &= ~(1 << PB1);
103
        Senden("BTR20A\n");  
104
      }
105

106
      if (text[3] == '3') 
107
      {
108
        PORTB |= (1 << PB2);
109
        Senden("BTR31A\n");
110

111
        waitMs(1000);
112
        PORTB &= ~(1 << PB2);
113
        Senden("BTR30A\n");  
114
      }
115

116
    }
117
  }
118
  while (true);
119
}
Gast #2208011
Lesenswert?
• ▲
▼
Wenn du den UART Transmit Interrupt freigibts, erzeugt das erste 
empfangene Zeichen einen explodierenden Rattenschwanz von 
Transmit-Interrupts, weil für jedes Zeichen deiner Debug-Ausgabe nach 
erfolgreichem Aussenden ein neuer Transmit Interrupt ausgelöst wird, der 
wieder den Text "Interrupt" aussenden möchte.
MfG
#2208022
Lesenswert?
• ▲
▼
Das hier

  UCSRB  = 0x98;

ist fast due dümmste SChreibweise, die du wählen kannst. Noch dümmer 
wäre nur noch eine Dezimalangabe

Warum nicht
1
  UCSRB = ( 1 << RXEN ) | ( 1 << TXEN ) | ( 1 << RXCIE );

da würde man auf einen Blick sehen, was du eigentlich eingestellt und 
freigegeben hast.
OP #2208056
Lesenswert?
• ▲
▼
Karl Heinz Buchegger schrieb:
> Warum nicht  UCSRB = ( 1 << RXEN ) | ( 1 << TXEN ) | ( 1 << RXCIE );
>
> da würde man auf einen Blick sehen, was du eigentlich eingestellt und
> freigegeben hast.

Danke für den Tipp, das werde ich verwenden.

Karl Heinz Buchegger schrieb:
> Du musst das Zeichen in der ISR auch abholen.
> Erst durch das Auslesen von UDR wird die Interruptanforderung wieder
> gelöscht.

Wie hole ich das empfangene Zeichen den ab ?

Antwort schreiben

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.

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.