mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik UART - Zeichen empfangen


Autor: tim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi all,

ich fange an, mein atmel mega16 zu programmieren, und versuche dieses 
einfache programm, zu programmieren. aber es klappt bei der 
zeicheneingabe net. weist jemand vielleicht woran es liegt.

------------------------------------------------------------------------ 
---

#define FOSC 3686400 // Clock Speed
#define BAUD 9600
#define MYUBRR FOSC/16/BAUD-1

#include <avr/io.h>

// USART initialisieren
void USART_Init(unsigned int ubrr)
{
  /* Set baud rate */
  UBRRH = (unsigned char) (ubrr >> 8);
  UBRRL = (unsigned char) ubrr;

  /* Enable receiver and transmitter */
  UCSRB = (1 << RXEN) | (1 << TXEN);

  /* Set frame format: 8data, 2stop bit */
  UCSRC = (1 << URSEL) | (1 << USBS) | (3 << UCSZ0);
}

// Zeichen senden
void USART_Transmit (unsigned char data)
{
  /* Wait for empty transmit buffer */
  while (! (UCSRA & (1 << UDRE) ) )
  ;
  /* Put data into buffer, sends the data */
  UDR = data;
}

// Zeichen empfangen
unsigned char USART_Receive (void)
{
  /* Wait for data to be received */
  while (! (UCSRA & (1 << RXC) ) )
  ;

  /* Get and return received data from buffer */
  return UDR;
}

int main (void)
{
  // Parameter definieren
  unsigned char temp;

  // Schnittstelle Initialisierung
  USART_Init (MYUBRR);

  // Hauptprogramm
  USART_Transmit ('>');

  temp = USART_Receive ();

  USART_Transmit (' ');

  USART_Transmit (temp);

  return 0;
}

------------------------------------------------------------------------ 
---

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#define FOSC 3686400L // Clock Speed  // das L ist wichtig
#define BAUD 9600
#define MYUBRR FOSC/16/BAUD-1
..
return 0;                              // wo springt er denn hier hin??

Sind die Einstellungen im Terminal auch korrekt?

Autor: Patrick (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich bin auch Anfänger, aber fehlt da nach "int main (void)" nicht die 
Schleife while(1){ ? Oder hab ich da was falsch verstanden?

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>nach "int main (void)" nicht die Schleife while(1){ ? Oder hab ich da was >falsch 
verstanden?

Naja ja.
Aber die muss nicht (gleich) hinter
int main (void)

deshalb ja meine Frage, wo er (der µC) bei
return 0;
 hinspringt

Autor: Patrick (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Meiner Meinung nach müsste doch der Code so aufgebaut sein:
int main (void){
...
while(1){
//Was zu tun ist
}
return 0;

Der letzte Befehl meldet doch einfach 0 zurück und bricht dann main ab, 
oder?

Autor: Robert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

deine main wird exakt einmal durchlaufen. Also pack die USART Funktion 
in eine while (1) Schleife (oder eine for Endlosschleife), nicht jedoch 
die Initialisierung des USART. Mit return 0 im main springt der uC ins 
Nirvana, deine main darf das return also nie (!) erreichen!

Robert

Autor: Patrick (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Konkret:
int main (void)
{
  // Parameter definieren
  unsigned char temp;

  // Schnittstelle Initialisierung
  USART_Init (MYUBRR);
while(1){
  // Hauptprogramm
  USART_Transmit ('>');

  temp = USART_Receive ();

  USART_Transmit (' ');

  USART_Transmit (temp);
}
  return 0;  //Never reached
}

Oder bin ich damit wirklich auf dem Holzweg?

Autor: tim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo beide.

--- Matthias L.
   wie so is der - UL - wichtig? wofür seht es? und den - return 0; 
anweisung - habe ich einfach eingebaut, da die main-fkt von typ int ist. 
das programm soll erstmal einmal durchlaufen, um die fkt zu testen, ob 
es richtig funktionert. deswegen gibst auch in diesem programm keine 
unendl. scheife.

---  Patrick
   ja. aber erst will ich nur alle fuktionen prüfen. später tue ich  die 
while-schleife ein.

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>wie so is der - UL - wichtig? wofür seht es?

Weil nach C-Standart der Compiler sonst mit 16bit arbeitet. Und wie 
lautet 3686400 in eine 16bit Zahl "gepresst"? Richtig: 16384.
Und du hast ja wohl kaum einen 16kHz Quartz dran, oder?

PS: die Quartzfrequenz von 3,6864MHz hab ich noch nie gehört..
(Muss aber nix heißen)

Autor: tim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
aber das prob ist es, dass nach der ausgabe von > das programm net 
weiter läuft

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Oder bin ich damit wirklich auf dem Holzweg?

Nein. Passt schon. Da aber damit das return 0 NIE ausgeführt wird, kann 
man es auch weglassen, und das main als void deklarieren..

(Es folgt eine Warnung da nicht C-konform, die kann aber (als einzige 
Warnung) ignoriert werden)

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>aber das prob ist es, dass nach der ausgabe von > das programm net
>weiter läuft

Natürlich nciht, denn was macht dieses Programm:?
// Zeichen empfangen
unsigned char USART_Receive (void)
{
  /* Wait for data to be received */
  while (! (UCSRA & (1 << RXC) ) )
  ;

  /* Get and return received data from buffer */
  return UDR;
}

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Robert (Gast)

>die Initialisierung des USART. Mit return 0 im main springt der uC ins
>Nirvana, deine main darf das return also nie (!) erreichen!

Quark. Sowohl der AVR mit GCC als auch z.B. der M16C mit Renesas 
Compiler springen aus Main in eine Endlosschleife. Also nix Nirvana!

MfG
Falk

Autor: tim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hmm verstehe. also diese zahl 3.6864 steht aufn quarzbauteil, die mit 
stk500 mitgeliefert wurde. das bedeutet doch quarzfrequenz von 3.6864 
MHz. hab ich recht?

Autor: tim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
dieses programm soll einfach ein zeichen, das vom tastatur über 
hyperterminal eingegeben wird, nur empfangen zu ins programm 
zurückgeben.

>>>
// Zeichen empfangen
unsigned char USART_Receive (void)
{
  /* Wait for data to be received */
  while (! (UCSRA & (1 << RXC) ) )
  ;

  /* Get and return received data from buffer */
  return UDR;
}

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
tim wrote:
> ...das bedeutet doch quarzfrequenz von 3.6864 MHz. hab ich recht?
Wenn das da drauf steht, dann ja. Allerdings läuft der Controller auch 
nur dann mit dem Quarztakt, wenn die Fusebits entsprechend gesetzt sind.

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>dieses programm soll einfach ein zeichen, das vom tastatur über
>hyperterminal eingegeben wird, nur empfangen zu ins programm
>zurückgeben.

Soweit richtig. Aber ich meinte, das
  /* Wait for data to be received */
  while (! (UCSRA & (1 << RXC) ) );
sorgt dafür, dass du hier SOLANGE wartest, bis ein Zeichen KORREKT 
empfangen wurde..
(Deshalb kann er hier mehr oder weniger lange festhängen)

Autor: tim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja, ich stecke hier noch fest. hab versuch zeichen einzugeben aber es 
passiert nix.

Autor: Patrick (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Welchen Hyperterminal verwendest Du?
Wird denn das gesendete Zeichen ausgegeben?

Autor: tim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hyperterminal von windows xp und die ausgabe vom zeichen > läuft alles 
in ordnung und dann hab ich versucht zeichen einzugeben. aber es ist nix 
passiert, wobei es so nur das gleiches zeichen auf dem terminal 
zurückgeben.

Autor: Patrick (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Probier mal den im Anhang. Der ist viel Konfortabler.

Bei mir hat das mit dem Windows Terminal auch nie funktioniert.

Autor: tim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
vielen dank. es hat geklappt. aber es ist wirklich kömisch dass mit dem 
hyperterminal net fkt.

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.