Forum: Compiler & IDEs UART Interrupt kurzeitig beenden??


von SvenP (Gast)


Lesenswert?

Hallo

Habe vor ein kleines GPS Programm zu schreiben es gibt schon welche die
sowas gemacht haben.

Aber ich will mal das Rad neu erfinden so das ich ich auch durchblicke
bin neuling in C.

Habe eine Interrupt Routine die beim Empfang eines Zeichen auslöst.

Ich überprüfe das Zeichen ob es mit einen "$" beginnt wenn ja
schreibe ich die nachfolgenden Zechen in einen Buffer char buffer[77].

wenn eines der Zeichen eine 13 ist soll eine Unterroutine aufgerufen
werden und der UART empfang gestoppt werden solange bis die
unterroutine abgearbeitet wurde.
derzeitig bricht meine Unteroutine ab weil der Interrupot ausgelöst
wurde.

wie kann man das erreichen ohne die Globalen Interrupts auser kraft zu
setzten.


vielen Dank

von Rolf Magnus (Gast)


Lesenswert?

Du hast ihn doch auch eingeschaltet. Da müßtet du eigentlich auch
wissen, wie du ihn wieder ausschaltest.

von SvenP (Gast)


Lesenswert?

na da denke ich schalte ich ihn so wieder aus

UCSR0A |= (1 << RXC1);


oder ???


Warum gibt es die funktion strtok nicht

er sagt es fehlt eine reference drauf

#include <string.h> habe ich

will die  nmea daten die per komma getrennt sind aufteilen.

von SvenP (Gast)


Lesenswert?

Also das mit den Interrupt verstehe ich nicht mehr


Ist es so das die Interrupt Routine abgebrochen wird und von vorn
anfängt wenn ein neues zeichen eintrifft ???

was passiert mit dem Rest???

Iwe kann man das lösen das die unterroutinen weiterlaufen Multitasking
ist wahrscheinlich nur mit emensen aufwand möglich.

es muß doch was geben wo man sagen kann interrupt für UART Empfang
deaktivieren und bei bedarf wieder aktivieren.

von SvenP (Gast)


Lesenswert?

Hbe mich mal schlau gemacht und wenn ic´h das richtig verstehe

wird der Interrupt auser betrieb genommen wenn der Interrupt aktiv ist
und es werden alle unterroutinen abgearbeitet.
Ist das richtig???

Habe ich meine UART richtig initialisiert???

hier meine Initialisierung meines 128 iger.
meine UARTS sollen mit 4800 Baud 8,n,1 initialsiert werden.

baudrate=4800
baud=cpuclock/((baudrate*16L)-1);
baud1=baud
baud0=baud

void init_rs232(unsigned int baud0,unsigned int baud1)
{
  UBRR0H= (unsigned char)(baud0>>8);
  UBRR0L = (unsigned char) baud0;
  UBRR1H= (unsigned char)(baud1>>8);
  UBRR1L = (unsigned char) baud1;
  cli();
  UCSR0A = (1 << RXC1);
  UCSR0B=(1<<RXEN)| (1<<RXCIE) ;
  UCSR0C = (1 << UCSZ10) | (1 << UCSZ11);
  UCSR1A = (1 << RXC1) | (1<<TXC1);
  UCSR1B=(1<<RXEN) | (1<<TXEN);
  UCSR1C = (1 << UCSZ10) | (1 << UCSZ11);
  sei();
  }

von johnny.m (Gast)


Lesenswert?

> es muß doch was geben wo man sagen kann interrupt für UART
> Empfang deaktivieren und bei bedarf wieder aktivieren.

Da Du den Interrupt am Anfang zweifelsohne aktivierst, damit er
überhaupt ausgelöst werden kann (klitzekleiner Hinweis:
UCSR0B=(1<<RXEN)| (1<<RXCIE) ;...), solltest Du eigentlich auch keine
größeren Probleme damit haben, ihn wieder zu de- aktivieren, oder?
Ansonsten solltest Du Dich generell mit der Interrupt-Bearbeitung
auseinandersetzen. Es gibt da ein paar nette Threads hier im Forum, die
durchaus zum generellen >Grundlagen-Verständnis beitragen könnten.

von Peter D. (peda)


Lesenswert?

Die UART zu deaktivieren ist Mumpitz.
Es löst keine Probleme, sondern schafft nur welche. Wenn Du nämlich die
UART wieder einschaltest, bist Du asynchron, d.h. irgendwo inmitten
eines Bytes inmitten eines Datenpaketes. Du empfängst also zuerst immer
nur Müll.


Es gibt 3 Möglichkeiten:

1.
Du weißt, daß die Gegenstelle für eine Mindestzeit nichts sendet. Dann
brauchst Du nichts weiter zu machen, als die Daten innerhalb dieser
Mindestzeit auszuwerten.

2.
Du benutzt Hardware-Handshake, um der Gegenstelle zu sagen, wann du
nicht empfangsbereit bist.

3.
Du richtest einen Puffer ein, der dann die weiteren Daten empfängt,
wärend Du die letzten auswertest. Der Interrupthandler schreibt einfach
alle Bytes erstmal in einen Puffer. Für Textdaten empfielt sich ein
Linearpuffer, für Binärdaten ein Ringpuffer.
Diese Möglichkeit wird mit Abstand am häufigsten verwendet, da sie
keinerlei Kompromisse für die Gegenstelle bedeutet.


Peter

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

> Warum gibt es die funktion strtok nicht

Versuch's mal mit dem Studium der Doku, dann wirst du sehen, dass
es stattdessen strtok_r() gibt (das ist die reentrante Variante
von strtok()).

von SvenP (Gast)


Lesenswert?

strtok gibt es nicht habe ich jetzt gelesen und das strtok_r genutzt
geht.

Ich mache jetzt alles in den Interrupt routinen da der GPS Empfänger
sehr schnell die Daten liefert geht bis jetzt wunderbar.


Danke

von Axel R. (Gast)


Lesenswert?

1
void    RX_SWITCH(unsigned char onoff)
2
/*******************************************************************************
3
* ABSTRACT:  This function disabled or enabled the Reciever of the
4
USART0
5
*
6
*/
7
{
8
  
9
  if (onoff==1)
10
  // Enable Receiver Interrupt, Receiver 
11
  UCSR0B |= (1<<RXCIE0)|(1<<RXEN0);
12
  else
13
  UCSR0B &= ~((1<<RXCIE0)|(1<<RXEN0));
14
  return;
15
16
}    // End RX_SWITCH(unsigned char onoff)

Wenns garnicht anders geht - bitte.

Mega48 WinAVR

AxelR.

von Axel R. (Gast)


Lesenswert?

beim erneuten einschalten evtl. das intflag löschen/setzen
Habe ich nicht gemacht - sehe ich gerade :-(( auweia

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.