mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Frage zum UART (ISR Vector)


Autor: Ein freundlicher türkischer Mitbürger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Abend zusammen.

Ich möchte mich mal kurz auf diesen Code Ausschnitt beziehen, den ich 
mal irgendwann irgendwo gefunden habe, um zu erfahren, ob ich das 
richtig verstanden habe.

Die Funktion (?) ISR(UART_RX_vect) wird jedesmal aufgerufen, wenn von 
dem computer zum (MAX232->) Atmega8 Daten fließen. In UDR sind 
warscheinlich die empfangenen Daten drin. Sind es eizelne 
Chars(=Zeichen) die gesendet werden ?

Diese einzelnen Chars werden in die Variable temp_str rein gepackt, 
welche maximal 10 Zeichen enthalten kann.
NextChar dient dann hier wie eine Art "laufvariable", welches die 
einzelnen Indizies für temp_str darstellt.

rx_flag ist dann sowas wie eine Status Variable, also wenn sie auf 1 
gesetzt wird, heißt es das alle Daten erfollgreich in temp_Str 
reingespeichert wurden. Was ich nicht so ganz verstehe ist die Bedingung 
==0x0D bzw. 13. d.h. das die If Bedingung abbricht wenn irgendein ein 
Element von temp_Str[] den Wert 13 erreicht. Steht die 13 in Relation 
mit der maximalen Anzahl der Zeichen die temp_Str aufnehmen kann oder 
ist das "zufall"?

Bedanke mich im Voraus !


char temp_str[10];
int NextChar;
int rx_flag;
ISR(UART_RX_vect) { 

 temp_str[NextChar] = UDR; 
 
 if (temp_str[NextChar] == 0x0D) 
 { 
   rx_flag=1; 
   NextChar=0; 
 } 
 else 
 { 
 NextChar++; 
 } 
} 

Autor: Ein freundlicher türkischer Mitbürger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aha.. die Hexdezimal stehen für die ASCII Zeichen.. mein gott... 
manchmal sieht man den Wald voller Bäume nicht.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Ein freundlicher türkischer Mitbürger (Gast)

>warscheinlich die empfangenen Daten drin. Sind es eizelne
>Chars(=Zeichen) die gesendet werden ?

Ja.

>Diese einzelnen Chars werden in die Variable temp_str rein gepackt,
>welche maximal 10 Zeichen enthalten kann.

Ja, aber . . .

>NextChar dient dann hier wie eine Art "laufvariable", welches die
>einzelnen Indizies für temp_str darstellt.

Ja, das ist der Index. Allerdings fehl ein Schutz gegen Überlauf. Wenn 
dauernd Zeichen ankommen und kein 0x0D dabei ist, wirst du dir ganz fix 
deinen Speicher überschrieben und der uC stürzt ab.

>rx_flag ist dann sowas wie eine Status Variable, also wenn sie auf 1
>gesetzt wird, heißt es das alle Daten erfollgreich in temp_Str
>reingespeichert wurden.

ja.

>mit der maximalen Anzahl der Zeichen die temp_Str aufnehmen kann oder
>ist das "zufall"?

nöö, das ist der ASCII-Code für RETURN bzw. Enter. Klassische 
Schnittstelle zum PC auf einfacher Terminalbasis.

Machs besser so.

char temp_str[10];
int NextChar;
int rx_flag;

ISR(UART_RX_vect) { 

 temp_str[NextChar] = UDR; 
 
 if (temp_str[NextChar] == 0x0D) 
 { 
   rx_flag=1; 
   NextChar=0; 
 } 
 else 
 { 
   if (NextChar < (size_of(temp_str)-1) ) NextChar++; 
 } 
} 


MfG
Falk

Autor: Ein freundlicher türkischer Mitbürger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Falk Brunner.

Vielen Dank für die schnelle Antwort und für deinen Tipp.

Ist in deiner Version diese Zeile:

if (NextChar < (size_of(temp_str)-1) ) NextChar++;

für den Schutz vor einem Überlauf ?

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja.

Autor: Ein freundlicher türkischer Mitbürger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich bekomme jetzt folgende Fehlermeldungen:

main.c:54: warning: 'UART_RX_vect' appears to be a misspelled signal 
handler
main.c: In function 'UART_RX_vect':
main.c:64: warning: implicit declaration of function 'size_of'

interrupt.h Header habe ich includiert...

Autor: Ein freundlicher türkischer Mitbürger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
aha.. es heißt sizeof nicht size_of...

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Ein freundlicher türkischer Mitbürger (Gast)

>main.c:54: warning: 'UART_RX_vect' appears to be a misspelled signal
>handler

Der heisst bei einigen AVRs USART_RX_vect

>main.c: In function 'UART_RX_vect':
>main.c:64: warning: implicit declaration of function 'size_of'

dafür braucht man stddef.h

MFG
Falk

Autor: Ein freundlicher türkischer Mitbürger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Frank:

hab jetzt #include <stddef.h> und USART... versucht aber Warnung noch 
immer Vorhanden und Warnungen solltem an als Fehler wahrnehmen ;-)

Autor: Ein freundlicher türkischer Mitbürger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eine andere Frage, welche mich interessieren würde ist, ob ich den RXCIE 
Bit setzen muss, wenn ich den ISR benutze ? Laut AVRGCC Tutorial, ja.
Ich wundere mich weil ich den initialisierungs Code des UARTS ohne die 
Bit Setzung von RXCIE im Netz gefunden hatte, wo aber auch ISR benutzt 
wurde.

So war es vorher:
void uart_init(void){ 
UBRRH = (unsigned char) (UBRR_BAUD>>8); 
    UBRRL = (unsigned char) (UBRR_BAUD & 0x0ff); 
    UCSRB = (1<<RXEN) | (1<<TXEN); 
    UCSRC = (1<<UCSZ1)|(1<<UCSZ0); 
} 

So habe ich es geändert, indem ich (1<<RXCIE) hinzugefügt habe.

Ist das notwendig ??

void uart_init(void)
{
  UBRRH = (unsigned char) (UBRR_BAUD>>8);
  UBRRL = (unsigned char) (UBRR_BAUD & 0x0ff);
  UCSRB = (1<<RXEN) | (1<<TXEN) | (1<<RXCIE);
  UCSRC = (1<<UCSZ1) | (1<<UCSZ0);
}

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja.

Wegen des Namens der ISR kannst du im Datenblatt des Controllers 
nachschauen, die sind beim AVR GCC gleich dem Datenblatt.

MFG
Falk

Autor: Ein freundlicher türkischer Mitbürger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Frank:

Fehler gefunden... ich habe ein leerzeichen zwischen ISR und der Klammer 
(USART_RXC_vect) vergessen.

Keine Warnungen/Keine Fehler.

Bedanke mich sehr für deine Unterstützung und wünsche dir noch einen 
schönen Sonntag !

Autor: Ein freundlicher türkischer Mitbürger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Entschuldigung, ich meinte es lag an dem C das hinter RX ran muss.

Für einen Atmega8 gilt daher: ISR (USART_RXC_vect)

Autor: Uwe (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi!
Mal was zu:
>if (temp_str[NextChar] == 0x0D)
Wenn du auf die Entertaste haust senden die meisten Programme 0x0D 0x0A.
Das 0x0A würde den Puffer schon mit dem 1. Zeichen füllen, also wenns 
dumm kommt und der Puffer noch nicht verarbeitet ist, ist das 1. Zeichen 
futsch. Brauchen wirst du es vermutlich eh nicht. Am besten mit 
ausfiltern.
Eventuell solltest du überhaupt testen ob der Puffer schon verarbeitet 
ist.
So in der Art if rx_flag==1 dann Fehlermeldung(Flag).

Viel Erfolg, Uwe

Autor: Ein freundlicher türkischer Mitbürger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Uwe !

Ich habe anstelle von Entertaste(CR) Semikolon(0x3B) benutzt. Ich werde 
die Befehle sowieso per Programm senden, wahrsch. eine kleine C 
Konsolenanwendung.

Derzeit quäle ich mich noch mit dem Senden von Daten an den PC. Es kommt 
zwar etwas an, aber es gefällt mir noch nicht :-).

Autor: Ein freundlicher türkischer Mitbürger (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich bin es nochmal.... egal was ich sende es kommen immer "Rechteck" 
Zeichen bzw. als Hexdezimal 00 an.

Was mache ich da falsch ? Mein Code ist im Anhang mitdabei.

Danke.

Autor: Ein freundlicher türkischer Mitbürger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich weiß, dass ich beim Senden eines Zeichens (uart_IAmAlive(const char 
*s)) einen Parameter übergebe mit diesen jedoch nicht arbeite. Ich 
wollte nur schauen, ob das senden von dem Zeichen 'T' funktioniert.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Ein freundlicher türkischer Mitbürger (Gast)

>Was mache ich da falsch ? Mein Code ist im Anhang mitdabei.

Eine globale Variable mit dem Namen i ist sehr gefährlich. Die gehört 
als static in die ISR, denn nur dort wird sie verwendet.

Wegen Problemen zum UART fragen Sie Ihren Arzt oder Apotheker.

http://www.mikrocontroller.net/articles/AVR_Checkl...

Autor: Ein freundlicher türkischer Mitbürger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da ich kein neuen Thread öffnen möchte, könnte ich kurz eine neben Frage 
hier stellen, wenn das in Ordnung sein sollte, ansonsten tut es mir leid 
:).

Wenn ich bei der Schrittmotorsteuerung RN STEP 297/298 Kombination die 
Referenzspannung ändern möchte um z.b. den maximalen Motorstrom 
festzulegen muss ich dann die Verbindung der Schrittmotorsteuerplatine 
zur AVR Platine trennen ? Ich frage, weil ich an den Spindeltrimmer (Zum 
eisntelen der Referenzspannung) gedreht habe wie bekloppt und sich 
dieser nicht geändert hat, erstnachdem ich die die Verbindung zwischen 
Steuerplatine und AVR getrennt habe.


Zu UART: Das Tutorial bezüglich UART habe ich mir bereits angeguckt, nur 
sehe ich da kein Unterschied... ich korrigiere es mal die gefährliche 
Variable i ;-).

Danke !

Autor: Ein freundlicher türkischer Mitbürger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also ich habe jetzt folgenden Code gestestet:
#include <avr/io.h>
#include <stdlib.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stddef.h>




#define BAUD 9600UL
#define UBRR_BAUD ((F_CPU/(16UL*BAUD))-1)




int main(void)
{

// Uart initialisieren

  
  UCSRB |= (1<<TXEN);                            // UART TX einschalten
  UCSRC |= (1<<URSEL)|(1 << UCSZ1)|(1 << UCSZ0); // Asynchron 8N1 
  
  UBRRH = (unsigned char) (UBRR_BAUD>>8);
 UBRRL = (unsigned char) (UBRR_BAUD & 0x0ff);
  
// Fertig mit initialisieren


  // Lass uns mal was senden :)
  while(1)
  {
  while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich                   */
    {
    }
  UDR = 'x';    
  }
  
return 0;
}

Und habe dieses Phänomen festgestellt:

Erst treffen nur '/////////////////////... zeichen an.. wenn ich die 
Verbindung neuaufbaue kommen diese Zeichen @ßßßßßßßßßßßß.. und beim 
dritten mal erst die gewünschten xxxxxx.  Was ist da faul ? Icb bin 
jetzt genau nachdem Tutorial gegangen.

Danke :)

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Ein freundlicher türkischer Mitbürger (Gast)

>Erst treffen nur '/////////////////////... zeichen an.. wenn ich die
>Verbindung neuaufbaue kommen diese Zeichen @ßßßßßßßßßßßß.. und beim
>dritten mal erst die gewünschten xxxxxx.

>  Was ist da faul ? Icb bin jetzt genau nachdem Tutorial gegangen.

Hast du auch das gelesen?

http://www.mikrocontroller.net/articles/AVR-Tutori...

"Hinweis

Wenn man das nachfolgende Programm laufen lässt und Hyperterminal 
startet, scheint es problemlos zu funktionieren. Wenn man aber das RS232 
Kabel zwischenzeitlich abzieht und wieder ansteckt wird es oft 
passieren, dass nur noch wirre Zeichen auf dem PC erscheinen. Das liegt 
daran, dass der PC aus einem ununterbrochen Zeichenstrom nicht den 
Anfang eines Zeichens erkennen kann. Darum muss in solchen Fällen 
periodisch eine kleine Pause von der Länge mindestens eines Zeichens 
eingelegt werden, damit der PC sich wieder synchronisieren kann."

MfG
Falk

Autor: Ein freundlicher türkischer Mitbürger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh tut mir leid.. hab den Link total übersehen... nach ein paar Stunden 
vor dem Rechner kann das schonmal passieren. Werde mir genau durchlesen 
und mich ggf. melden :).

Danke !

Autor: Ein freundlicher türkischer Mitbürger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich krieg das nicht hin. Ich kann zwar senden und empfanen. Ich habe 
zwischen dem senden ein _delay_ms(10) rein gekloppt und das scheint gut 
zu funktionieren. Aber mit dem ISR das klappt bei mir nicht.

Autor: Ein freundlicher türkischer Mitbürger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich habe im ISR Code Block gleich, bevor eine If Abfrage kommt oder ä., 
den Befehl reingeschrieben den Motor einfach mal drehen zu lassen, um zu 
sehen ob sich überhaupt was im ISR tut und das scheint nicht so der fall 
zu sein....

Autor: Ein freundlicher türkischer Mitbürger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ha ! Endlich geschaft !!! ;)

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.