www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik RS232 unter C auf Atmega8 konfiguriren


Autor: Viktor Tschetwerik (viktort)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,

habe folgendes problem, ich habe die baud rate auf dem PC und µc 
angepast (9600 8N1) und den externen quartz eingestelt 3,6MHz auch die 
dafür notwendigen fuse bits gesetzt, meine konfiguration in C (siehe 
unten).

Ich bekomme aber laute unsinige Zeichen angezeigt.

ich komme einfach nicht weiter.

#define   F_CPU   3686400
#include   <avr\io.h>
#define   BAUD   9600
//----------------------------------------------------------------------
// Titel   : C-Funktion Zeichen zu UART senden.
// IN       : char data
//----------------------------------------------------------------------
void uartPutChar(char data)
{
  //warte bis UDR leer ist UCSRA / USR bei z.B.: 2313
  while (!(UCSRA&32));
  //sende
  UDR=data;
}
void uartPutBin(char data)
{
  //warte bis UDR leer ist UCSRA / USR bei z.B.: 2313
  while (!(UCSRA&32));
  //sende
if (data&1)   uartPutChar('1'); else uartPutChar('0');
if (data&2)   uartPutChar('1'); else uartPutChar('0');
if (data&4)   uartPutChar('1'); else uartPutChar('0');
if (data&8)   uartPutChar('1'); else uartPutChar('0');
if (data&16)  uartPutChar('1'); else uartPutChar('0');
if (data&32)  uartPutChar('1'); else uartPutChar('0');
if (data&64)  uartPutChar('1'); else uartPutChar('0');
if (data&128) uartPutChar('1'); else uartPutChar('0');
}
//----------------------------------------------------------------------
// Titel   : C-Funktion wartet auf Zeichen von UART.
// OUT      : data
//----------------------------------------------------------------------
char uartGetChar()
{
  char data=0;
  //warte bis RX-complete RXC UCSRA / USR bei z.B.: AT090S2313
  while (!(UCSRA&128));
  //empfangen
  data=UDR;
  return data;
}
//----------------------------------------------------------------------
// Titel   : C-Funktion wartet auf Zeichen von UART.
// OUT      : data, error = keine Daten
//----------------------------------------------------------------------
bool error;
char uartIsChar()
{
  char data=0;
  error=true;
  //chek RX-complete RXC UCSRA
  if (!(UCSRA&128)) return 0;
  //zeihen abholen
  data=UDR;
  error=false;
  return data;
}
//----------------------------------------------------------------------
// Titel   : C-Funktion Zeichenkette zu UART senden.
// IN       : char *buffer, Zeichenkette mit NUll abgeschlossen
//----------------------------------------------------------------------
void uartPutString(char *buffer)
{
  for (int i=0; buffer[i] !=0;i++)
    uartPutChar (buffer[i]);
}
//---------------------------------------------------------------------- 
--
// Initialisierungen
//---------------------------------------------------------------------- 
--
void init()
{
  // UART initialisieren
  sbi(UCSRB,3);   // TX aktiv
  sbi(UCSRB,4);   // RX aktivieren
  UBRRL=(uint8_t)(F_CPU/(BAUD*16L))-1;   // Baudrate festlegen
  UBRRH=(uint8_t)((F_CPU/(BAUD*16L))-1)>>8;   // Baudrate festlegen
  //alles Ausgang
  DDRB=0b00111111;
  DDRC=0b11111111;
  DDRD=0b11111110;
}

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Deine Init stimmt nicht.
void init_uart( uint16_t bauddivider )
{
  UBRRH = bauddivider >> 8;
  UBRRL = bauddivider;                  // set baud rate
  UCSRA = 0;                            // no U2X, MPCM
  UCSRC = 1<<UCSZ1^1<<UCSZ0             // 8 Bit
#ifdef URSEL
           ^1<<URSEL                    // if UCSR0C shared with UBRR0H
#endif
           ;
  UCSRB = 1<<RXEN^1<<TXEN;              // enable RX, TX
}


Peter

Autor: Timmo H. (masterfx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Viktor Tschetwerik schrieb:
> void init()
> {
>   // UART initialisieren
>   sbi(UCSRB,3);   // TX aktiv
>   sbi(UCSRB,4);   // RX aktivieren
Machs doch so wie alle anderen:
  UCSRB = (1<<RXEN) | (1<<TXEN);
  UBRRL=(uint8_t)(F_CPU/(BAUD*16L))-1;   // Baudrate festlegen
  UBRRH=(uint8_t)((F_CPU/(BAUD*16L))-1)>>8;   // Baudrate festlegen
  // Hier was wichtiges:
  UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);  // Asynchron 8N1 
  DDRB=0xff;
  DDRC=0xff;
  DDRD = ~(1<<PD0);

Und was ist denn das für eine Schreibweise
>void uartPutChar(char data)
>{
>  //warte bis UDR leer ist UCSRA / USR bei z.B.: 2313
>  while (!(UCSRA&32));
besser:
void uartPutChar(char data)
{
  //warte bis UDR leer ist UCSRA / USR bei z.B.: 2313
  while (!(UCSRA & (1<<UDRE))) ;
  UDR=data;
}

übrigens kannst du dir das " while (!(UCSRA & (1<<UDRE))) ;" in der 
uartPutBin auch sparen, da du es eh bei jedem Zeichen in der uartPutChar 
prüfst.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Viktor Tschetwerik schrieb:
> void uartPutBin(char data)
> {
>   //warte bis UDR leer ist UCSRA / USR bei z.B.: 2313
>   while (!(UCSRA&32));
>   //sende
> if (data&1)   uartPutChar('1'); else uartPutChar('0');
> if (data&2)   uartPutChar('1'); else uartPutChar('0');
> if (data&4)   uartPutChar('1'); else uartPutChar('0');
> if (data&8)   uartPutChar('1'); else uartPutChar('0');
> if (data&16)  uartPutChar('1'); else uartPutChar('0');
> if (data&32)  uartPutChar('1'); else uartPutChar('0');
> if (data&64)  uartPutChar('1'); else uartPutChar('0');
> if (data&128) uartPutChar('1'); else uartPutChar('0');
> }

Also in unseren Breitengraden steht ja üblicherweise das höchstwertige 
Digit links.
Auch muß man Flash nicht mit Gewalt vergeuden.
void binout( uint8_t val )
{
  for( uint8_t i = 8; i--; val <<= 1 )
    uputchar( '0' + !!(val & 0x80) );
}


Peter

Autor: Timmo H. (masterfx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> !!(val & 0x80)
^^ das ist echt tricky, gefällt mir.
Hab sonst auch immer
if(val & 0x80)
  putchar('1');
else
  putchar('0');
gemacht, vorteil ist natürlich dass es leserlicher ist.

Autor: Viktor Tschetwerik (viktort)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen dank für eure schnelle Antwort, ich habe es ausprobiert und es 
geht immer noch nicht. Dar selbe fehlerbild!:-( er zeigt mir laute 
unleserliche zeichen!

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

Bewertung
0 lesenswert
nicht lesenswert
Viktor Tschetwerik schrieb:
> Vielen dank für eure schnelle Antwort, ich habe es ausprobiert und es
> geht immer noch nicht. Dar selbe fehlerbild!:-( er zeigt mir laute
> unleserliche zeichen!

Dann solltest du erst mal prüfen, ob das hier

#define   F_CPU   3686400


auch tatsächlich stimmt.
Dort ist eine Testprozedur beschrieben:
http://www.mikrocontroller.net/articles/AVR_Checkl...

Solange du die nicht positiv bestätigen kannst, macht es keinen Sinn, 
sich über weitere Dinge zu unterhalten.


Deine Init hast du schon korrigiert?

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Viktor Tschetwerik schrieb:
> Vielen dank für eure schnelle Antwort, ich habe es ausprobiert und es

Welche der beiden Vorschläge hast du ausprobiert?

In deinem Beispiel sehe ich auch keine main() Funktion. Man kann nicht 
entscheiden, ob du die uart* Funktionen überhaupt korrekt aufrufst.

> geht immer noch nicht. Dar selbe fehlerbild!:-( er zeigt mir laute
> unleserliche zeichen!

Und die wären bei welchem gesendeten Zeichen welches empfangene Zeichen?

Hast du schon auf dem PC alle Baudraten (insbes. 1200 BAUD) 
durchprobiert?

Welche Werte stehen in UBRRH und UBRRL letztendlich?

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

Bewertung
0 lesenswert
nicht lesenswert
Wichtig ist zb auch hier im Original
  UBRRL=(uint8_t)(F_CPU/(BAUD*16L))-1;   // Baudrate festlegen
  UBRRH=(uint8_t)((F_CPU/(BAUD*16L))-1)>>8;   // Baudrate festlegen

das die Reihenfolge, in der 16 Bit Pseudoregister beschrieben werden, 
eben nicht egal ist. Diese hier ist falsch rum.
Bei derartigen 16-Bit Registern: Immer zuerst H beschreiben und dann L

Ein Studium des Tutorial-Artikels
http://www.mikrocontroller.net/articles/AVR-GCC-Tu...
ist dringend angeraten!

Autor: Viktor Tschetwerik (viktort)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo, tut mir leid das ich mich lange nicht gemeldet hab, ich habe 
folgendes ausprobiert und es hat mehr oder weniger geklapt, blos halt 
zimmlich ungenu und langsam.

#define F_CPU 3686400
#include <avr\io.h>
//----------------------------------------------------------------------
void uartInit()
{
  UBRRL = 23;           //9600Baud siehe Baudratentabelle
  UCSRB = 8 + 16;         //Sender enable, Empfänger enable
}
//----------------------------------------------------------------------
char uartGetChar()
{
  char data=0;
  //warte bis RX-complete RXC UCSRA / USR bei z.B.: AT090S2313
  while (!(UCSRA&128));
  //empfangen
  data=UDR;
  return data;
}
//----------------------------------------------------------------------
void uartPutChar(char data)
{
  //warte bis UDR leer ist UCSRA / USR bei z.B.: 2313
  while (!(UCSRA&32));
  //sende
  UDR=data;
}
//----------------------------------------------------------------------
main ()
{
  uartInit();
  while (true) // Mainloop
  {
    char zeichen;
    zeichen=uartGetChar();
    uartPutChar(zeichen);
  }
}


hier ist noch die intro funktion was er mir anzeigen soll habe aus eimen 
bsp rausgenomen und wie es in main aufegufen wird.

void intro()
{
  uartPutChar('\n');
  for (int i=0;i<42;i++) uartPutChar('=');
  uartPutString("\n mySmartControl Simple Term 1.2 \n www.myAVR.de");
  uartPutChar('\n');
  for (int i=0;i<42;i++) uartPutChar('-');
  uartPutString("\nKommandos: zwei Byte, Kein Trennzeichen");
  uartPutString("\n PB = PortB alle Bits ON");
  uartPutString("\n pb = PortB alle Bits OFF");
  uartPutString("\n PC = PortC alle Bits ON");
  uartPutString("\n pc = PortC alle Bits OFF");
  uartPutString("\n PD = PortD alle Bits ON");
  uartPutString("\n Bx = PortB Bit X ON  (X = 0..5)");
  uartPutString("\n bx = PortB Bit X OFF (X = 0..5)");
  uartPutString("\n Cx = PortC Bit X ON  (X = 0..5)");
  uartPutString("\n cx = PortC Bit X OFF (X = 0..5)");
  uartPutString("\n Dx = PortD Bit X ON  (X = 2..7)");
  uartPutString("\n dx = PortD Bit X OFF (X = 2..7)");
  uartPutString("\n iX = config Port(C,B,D) IN mit PullUP");
  uartPutString("\n ix = config Port(c,b,d) IN ohne PullUP");
  uartPutString("\n gx = get PIN(b,c,d)");
  uartPutString("\n GX = get Port(B,C,D)");
  uartPutString("\n Gx = get DDR(b,c,d)");
  uartPutString("\n Ox = config Port(B,C,D) = OUT");
  uartPutChar('\n');
  for (int i=0;i<42;i++) uartPutChar('=');
}
//////////////////////////////////////////////////////////////////////// 
/////
// Main-Funktion
//////////////////////////////////////////////////////////////////////// 
/////
main()
{
  unsigned char portBuffer[3]={0}; // B,C,D
  char z1,z2;
  init();   // Initialisierungen
  intro();
  while (true)    // Mainloop-Begin


Großen dank nochmal!

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.