www.mikrocontroller.net

Forum: Compiler & IDEs Interrupt beenden


Autor: Minime (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 8000000L
#define BAUD 9600L
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)      
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))         
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000)      

#if ((BAUD_ERROR>10)||(BAUD_ERROR<-10))
#error Systematischer Fehler in der Baudrate größer 1% und damit zu hoch!
#endif
volatile uint8_t a;


int main(void)
{
      UCSRB = (1<<TXEN)|(1<<RXEN)|(1<<RXCIE);              
       UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
       UBRRH = UBRR_VAL >> 8;
       UBRRL = UBRR_VAL & 0xFF;
      
    sei();

    while (1)      
         {
          }
}
 
 
ISR (USART_RXC_vect) 

{
    char string[4];
      ++a;
    if (a==1)
      {
      string [0]='A';  
      string [1]='U';
         string [2]='S';
         string [3]=0;
      }    
    if (a==2)
      {
      string [0]='E';  
      string [1]='I';
         string [2]='N';
         string [3]=0;
      a=0;
      }
    

    int i=0;
    
    while (i<6) 
    {
         while (!(UCSRA & (1<<UDRE)))      
         {
         }

         UDR =string[i];  
      ++i;                   
      }
  reti();
  }


Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Minime (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> char string[4];
> while (i<6)

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

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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
#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

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Minime (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mh

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

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Minime (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

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.