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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren