Forum: Compiler & IDEs Interrupt beenden


von Minime (Gast)


Lesenswert?

Grüß Gott

ich hab folgendes problem

ich will über USART ein zeichen senden egal welches wenn es ankommt soll 
der text EIN kommen wenn ich wieder eins sende soll der text AUS kommen 
wenn ich wieder eins schik kommt wieder EIN usw...

wenn ich bei meinem programm ein zeichen schick dann schreibt es 
abwechselnt EIN AUS EIN AUS un das un unterbrochen

was muss ich ändern damit sich der interrupt programmabschnitt erst 
neustartet wenn ich wieder ein zeichen an den micro sende

1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#define F_CPU 8000000L
4
#define BAUD 9600L
5
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)      
6
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))         
7
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000)      
8
9
#if ((BAUD_ERROR>10)||(BAUD_ERROR<-10))
10
#error Systematischer Fehler in der Baudrate größer 1% und damit zu hoch!
11
#endif
12
volatile uint8_t a;
13
14
15
int main(void)
16
{
17
      UCSRB = (1<<TXEN)|(1<<RXEN)|(1<<RXCIE);              
18
       UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
19
       UBRRH = UBRR_VAL >> 8;
20
       UBRRL = UBRR_VAL & 0xFF;
21
      
22
    sei();
23
24
    while (1)      
25
         {
26
          }
27
}
28
 
29
 
30
ISR (USART_RXC_vect) 
31
32
{
33
    char string[4];
34
      ++a;
35
    if (a==1)
36
      {
37
      string [0]='A';  
38
      string [1]='U';
39
         string [2]='S';
40
         string [3]=0;
41
      }    
42
    if (a==2)
43
      {
44
      string [0]='E';  
45
      string [1]='I';
46
         string [2]='N';
47
         string [3]=0;
48
      a=0;
49
      }
50
    
51
52
    int i=0;
53
    
54
    while (i<6) 
55
    {
56
         while (!(UCSRA & (1<<UDRE)))      
57
         {
58
         }
59
60
         UDR =string[i];  
61
      ++i;                   
62
      }
63
  reti();
64
  }

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Minime schrieb:

> ISR (USART_RXC_vect)
> {
>   ... Restcode ...
>   reti(); // <===== Mach so was nicht.
> }

Der Compiler kümmert sich um das reti nach der abschliessenden } der 
ISR, nachdem er gerettete Register restauriert hat.

von Peter (Gast)


Lesenswert?

kann das sein das du ein zeichen zu viel sendest?

> char string[4];
> while (i<6)


über die serielle schnittstelle wird auch selten ein 0 als abschluss 
gesendet, da nimmt man lieber ein CR

Aber das ist nicht die Lösung deines Problemes.

Eventuell musst du das empfangen byte auch abrufen.

von Minime (Gast)


Lesenswert?

> char string[4];
> while (i<6)

ich hab erst was anderes geschickt das 5zeichen+ ne 0 hatte...

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Minime schrieb:
>   reti();

**argl**

-- Zum "Beenden" einfach ein return.
-- String ist nur 4 Zeichen lang, keine 6.
-- Der Präprozessor macht keine Fehlerbehandlung, da für ihn 9600L
   keine Zahl ist. Daher macht
1
#if ((BAUD_ERROR>10)||(BAUD_ERROR<-10))
nicht was du willst. Dito für das L in F_CPU.

-- DU solltest nicht in einer ISR auf zwichen warten sondern in der 
nächsten ISR ein weiteres Zeichen speichern etc.

Johann

von Falk B. (falk)


Lesenswert?

@  Johann L. (gjlayde) Benutzerseite

>-- Der Präprozessor macht keine Fehlerbehandlung, da für ihn 9600L
>   keine Zahl ist. Daher macht

Der Präprozessor macht das sowieso nicht, der ersetzt nur Text. Der 
Compiler kümmert sich um die Makros.

>#if ((BAUD_ERROR>10)||(BAUD_ERROR<-10))

>nicht was du willst. Dito für das L in F_CPU.

Aber sicher, das ist mehrfach getestet und belegt. Probiers aus ;-)

>-- DU solltest nicht in einer ISR auf zwichen warten sondern in der
>nächsten ISR ein weiteres Zeichen speichern etc.

In der Tat, siehe Interrupt.

MfG
Falk

von Minime (Gast)


Lesenswert?

mh

alles kla :D:D ich werd mich ma noch ein bissel einlesen wenns garnet 
klappt meld ich mich wieder :D

von Simon K. (simon) Benutzerseite


Lesenswert?

Falk Brunner schrieb:
> @  Johann L. (gjlayde) Benutzerseite
>
>>-- Der Präprozessor macht keine Fehlerbehandlung, da für ihn 9600L
>>   keine Zahl ist. Daher macht
>
> Der Präprozessor macht das sowieso nicht, der ersetzt nur Text. Der
> Compiler kümmert sich um die Makros.
Der Compiler kümmert sich um die Makros? Ne, stimmt auch nicht. Der 
Präprozessor kann schon rechnen. In kleinem Umfang. Und Zahlvergleiche 
anstellen kann er auch.

>>#if ((BAUD_ERROR>10)||(BAUD_ERROR<-10))
>
>>nicht was du willst. Dito für das L in F_CPU.
>
> Aber sicher, das ist mehrfach getestet und belegt. Probiers aus ;-)
Bin mir auch sicher, dass das funktioniert. Der Präprozessor sollte das 
mit dem L eigentlich parsen können. Oder nicht Georg? In dem 
Artikel-UART Beispiel geht das nämlich auch.

von Karl H. (kbuchegg)


Lesenswert?

Peter schrieb:

> Eventuell musst du das empfangen byte auch abrufen.

Nicht eventuell. Ganz sicher sogar.
Solange UDR nicht ausgelesen wird, wird die Interrupt Anforderung nicht 
zurückgesetzt.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Falk Brunner schrieb:
>>#if ((BAUD_ERROR>10)||(BAUD_ERROR<-10))
>>nicht was du willst. Dito für das L in F_CPU.
>
> Aber sicher, das ist mehrfach getestet und belegt. Probiers aus ;-)

hmmm... stimmt. Ich erinnere mich, mal Probleme damit gehabt zu haben. 
Ist aber schon ewas her ;-) Jedenfalls geht's mit GNU-C.

Johann

von Minime (Gast)


Lesenswert?

vielen dank... ich hab nur ne variable hinugefügt in der ich UDR 
reinschreibe
un nichts mit mache :D:D un ketzt funktioniert einwandfrei

von Karl H. (kbuchegg)


Lesenswert?

Minime schrieb:
> vielen dank... ich hab nur ne variable hinugefügt in der ich UDR
> reinschreibe
> un nichts mit mache :D:D un ketzt funktioniert einwandfrei

Zeig mal.
Wenn da nur halb soviele Fehler wie weiter oben drinn sind, sind immer 
noch eine Menge Fehler drinnen.

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.