Forum: Mikrocontroller und Digitale Elektronik UART -> PC


von chris (Gast)


Lesenswert?

hallo,
um debugg Infos zu bekommen will ich die serielle Schnittstelle des uC
an den PC anschließen.
hier mein Code

#include <avr/io.h>
    2
    3
    4 void usart_init()
    5 {
    6    UBRR0L=103;               // 9600 bps
    7    UBRR0H=0;
    8    UCSR0B = (1<<TXEN);       // Receiver enable
    9                             // Set frame format
   10 }
   11
   12
   13
   14 int main ()
   15 {
   16    usart_init();
   17     while (!(UCSR0A & (1<<UDRE))); /* warten bis Senden moeglich
                 */
   18         UDR0 = 'x';                    /* schreibt das Zeichen
x
                                            auf die Schnittstelle
   19
   20 }

ich arbeite mit ATMega128, stk500,501
Linux vielleicht liegts auch daran ?
ich strate die bash
dann in wechsel ich in Ordner /dev
dann mach ich einfach cat ttyS0
dann strate ich meinen uC neu ... nichts passiert ..
liegts an meinem Programm oder wie ich die serielle Schnittstelle unter
Linux abfrage.
 Danke Sehr
   Chris

PS: Ich find das Forum hier echt gut.
    Danke an alle ;-)

von Sebastian (Gast)


Lesenswert?

gab es nicht ein terminal programm??
kable richtig gesteckt??

von chris (Gast)


Lesenswert?

also ich habe von PORTE0 auf RXD und PORTE1 auf TXD gesteckt (RXD und
TXD von RS232 Spare , dann vorne die Serielle Schnittstelle RS232 Spare
mit meinem PC verbuunden (alles bei stk500)
 chris

von chris (Gast)


Lesenswert?

sorry fehler in zeile 8  ... // Transmiter enable
daran lag aber nicht ;-)

von Sebastian (Gast)


Lesenswert?

teste mal andere baudraten...
ich nehme an du benutzt den internen oszi
das ist immer so ne sache für sich

hab putty für linux/unix noch nicht getestet
aber die windows version ist gut
http://the.earth.li/~sgtatham/putty/latest/putty-0.58.tar.gz

von max.p (Gast)


Lesenswert?

Hallo, in zeile 17 muss es
while (!(UCSR0A & (1<<UDRE0))) {}
heisen.

max

von chris (Gast)


Lesenswert?

hallo,
ich weis ehrlcih gesagt net was ich für nen Takt benutze, hab in der
stk nirgendwo was darüber gefunden :-( ....
max.p deins hab ich probiert ohen Erfolg
  chris

von max.p (Gast)


Lesenswert?

Hallo
Es muss aber uaf jeden fall UDRE0 heisen, steht im Datenblatt des
Mega128 drin. Kenne leider das 501 nicht,aber bist du sicher das es der
UART0 ist? könnte es vieleicht 1 sein?

von Osterhase (Gast)


Lesenswert?

> ich weis ehrlcih gesagt net was ich für nen Takt benutze,
> hab in der stk nirgendwo was darüber gefunden :-( ....

Das ist aber doch schon von elementarer Bedeutung. Du solltest
vielleicht wirklich mal herausfinden, wie hoch deine Taktfrequenz ist.

von chris (Gast)


Lesenswert?

kennst du das stk500 ?
das stk501 ist nur ne erweiterung für den ATMega128, bei dem ATMega128
ist doch PORTE0 ist doch RXD0
     und PORTE1 ist doch TXD0
als hab ich so ein zwei kleine leitungen genommen und PORTE0 mit RXD
und PORTE1 mit TXD ( RS232 Spare , gleich neben Port E verbunden, alles
auf stk500 )
jetzt nehme ich an die RS232 Spare Serielle Buchse vorne neben der
anderen seriellen Schnittstelle ( zum Programmieren ) zu den beiden
Pins neben PortE gehört ? da habe ich dann meine Leitung zum PC
angeschlossen ..... chris

von Osterhase (Gast)


Lesenswert?

Hast du ein Oszilloskop, mit dem du überprüfen kannst, ob aus dem ATmega
überhaupt was rauskommt?

von Rahul (Gast)


Lesenswert?

Wie wäre es, wenn du UBRR0L und UBRR0H in der Reihenfolge anordnest, wie
sie im Datenblatt beschrieben ist?
Zumindest bei den beiden Megas (32 und 162), die ich bisher per UART
angesprochen habe, war es so, dass UBRRH vor UBRRL beschrieben werden
musste.

von Sssssss (Gast)


Lesenswert?

installier mal minicom...
dann starten STRG A O und dort bei serial port setup
Baudraten einstellen etc.
Dann in minicom bleiben oder kannst auch rausgehen und per cat ttyS0
gucken.
Wichtig ist nur das die Baudrate einmal richtig gesetzt wird ;)

von chris (Gast)


Lesenswert?

hi,
die Baudrate ist richtig, bzw die gleiche die ich in meinem uC Prog
benutz haben 9600 bps .......
ich hab das mit dem Befehl stty überprüft ...da war die PC
Schnittstelle auch auf 9600 Baud eingestellt ....
ja, mal ehrlcih .. ich muss mal rausfinden welche Taktfrequenz ich
benutze .....
  chris

von chris (Gast)


Lesenswert?

guten morgem,
ich schon wieder , also hab rausgefunden wie mein Takt ist 1Mhz (
default)
hier mein aktuelles Progamm

 10 int main ()
   11 {
   12    int i,j;
   13    char x='x';
   14    DDRB=255;
   15    //usart_init();
   16    UBRR0H=0;
   17    UBRR0L=12;                 // 9600 bps
   18
   19    UCSR0B = (1<<TXEN);       // Trans enable
   20
   21     while ((UCSR0A & (1<<UDRE0)))  /* warten bis Senden moeglich
                 */
   22      {
   23          for(i=0;i<1000;i++)
   24           {
   25            for (j=0;j<100;j++)
   26              {
   27               PORTB=255;
   28              }
   29           }
   30         UDR0 = x;                     /* schreibt das Zeichen
auf die Schnittstelle */
   31         for(i=0;i<1000;i++)
   32           {
   33            for (j=0;j<100;j++)
   34              {
   35                PORTB=0;
   36              }
   37           }
   38      }
   39}


es geht immer nich net :-( ...
  chris

von chris (Gast)


Lesenswert?

vergesst Zeile 17
 17    UBRR0L=12;                 // 9600 bps
war num zum Probieren
hab natürlich
       UBRR0L=6; drinn
  chris

von Daniel B. (khani)


Lesenswert?

Hallo,

ich sehe auf Anhieb zwei Problemas :
1. in UCSR0C ist nicht die richtige Menge an Datenbits eingestellt ! Du
verwendest momentan 5N1, also 5bits Daten keine Parität und 1 Stopbit -
Du solltest aber besser 8N1 verwenden. Also noch mal kurz zurück ans
Reißbrett und im Datenblatt Seite 192 konsultieren.
2. Deine Programmstruktur ist nicht gut. Der GCC meckert doch bestimmt
jedesmal rum, dass Deine non-void function irgendwie ohne return
aufhört .... Die Funktion main() sollte mit einer Endlosschleife enden.
Ungefähr so:

...
// Initialisierung
...

// Hauptschleife
while (1)
{
 // warten, bis ein Zeichen gesendet werden kann
 while (!(UCSR0A & (1 << UDRE))) ; // Es ist Quatsch, dass hier {}
stehen muss ';' reich völlig aus.

 // Ein Zeichen auf den Weg schicken.
 UDR0 = 'x';
}

// Ende von main()

Wenn Du Dein Programm so aufbaust, dann sendet der MC immer ein 'x'
nach dem anderen an den PC. Pass dabei auf, dass Du zuerst auf dem PC
Dein Terminalprogramm oder was auch immer für eine Empfangsmöglichkeit
startest und dann noch mal den Microcontroller anhaust - wir wollen ja
immer schön in sync bleiben ;-).

MfG, Daniel.

P.S.: PC-Programme sollten nach endlicher Zeit enden (es sei denn es
sind Betriebssysteme. Microcontrollerprogramme sollten eigentlich nicht
enden, es sei denn sie laufen auf Betriebssystemen.

von Christian Ege (Gast)


Lesenswert?

Also ein Tipp von mir.
Verwende unter Linux minicom (eventuell als root).
Dann verbinde dein RX und TX am seriellen Port und schreibe wie ein
wilder im Minicom. Jetzt sollten alle Buchstaben als Echos kommen so
kannst du testen ob dein Terminal geht.

cu
chege

--: http://cybertux.org :--

von chris (Gast)


Lesenswert?

hi,
also danke erst mal ....
ich hab erst mal minicom benutzt :-) .... irgendwie kommt nur das an

&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533; 
&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533; 
&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533; 
&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533; 
&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533;&#65533; 
&#65533;&#65533;&#65533;

&#65533;[9;96H&#65533;[9;96H&#65533;[9;96H&#65533;[9;96H&#65533;[9;96H&# 
65533;[9;96H&#65533;[9;96H&#65533;[9;96H&#65533;[9;96H&#65533;[9;96H&#65 
533;[9;96H&#65533;[9;96H&#65533;[9;96H&#65533;[9;96H&#65533;[9;96H&#6553 
3;[9;96H&#65533;[9;96H&#65533;[9;96H&#65533;[9;96H&#65533;[9;96H&#65533; 
[9;96H&#65533;[9;96H&#65533;[9;96H&#65533;[9;96H&#65533;[9;96H&#65533;[9 
;96H&#65533;[9;96H&#65533;[9;96H&#65533;[9;96H&#65533;[9;96H&#65533;[9;9 
6H&#65533;[9;96H&#65533;[9;96H&#65533;[9;96H&#65533;[9;96H&#65533;[9;96H 
&#65533;[9;96H&#65533;[9;96H&#65533;[9;96H



mein Programm sieht so aus (1Stopbit , 8Datenbits)
 #include <avr/io.h>
    2
    3 int main ()
    4 {
    5    int i,j;
    6    DDRB=255;
    7    UBRR0H=0;
    8    UBRR0L=6;                                             // 9600
bps
    9    UCSR0B = (1<<TXEN)|(0<<UCSZ02);                       //
Transmiter enable
   10    // Set Frame Format QUCSR0C=
(0<<USBS0)|(1<<UCSZ00)|(1<<UCSZ01);          // 1 Stopbit
   11
   12
   13    PORTB=255;
   14    while(1)
   15    {
   16      while (!(UCSR0A & (1<<UDRE0)));  /* warten bis Senden
moeglich dh UDRE0=1                  */
   17      {
   18        UDR0 = 'x';                     /* schreibt das Zeichen
auf die Schnittstelle */
   19      }
   20    for (i=0;i<1000;i++)
   21     {
   22     for(j=0;j<100;j++)
   23      {
   24       PORTB=~1;
   25      }
   26     }
   27    }
   28  return 0;
   29 }
   30
   31

ja mein Compiler emkert
"no new line at end of file" ..
kann mir jemadn saen warum ich kein x sehe ?
  chris

von Christian Ege (Gast)


Lesenswert?

Hast du mal den Test mit RX TX gemacht?

Ansonsten könnte der Müll an einer falschen Baudrate bzw Konfiguration
der Schnittstelle liegen wie ist minicom konfiguriert?

cu
chege

--: http://www.cybertux.org :--

von chris (Gast)


Lesenswert?

minicom setup habe ich so gemacht :
serial Port setup :
dann hab ich
A : serial device in  : /dev/ttyS0
und
E : bps              : 9600 8N1
gemacht
ich nehem an 8N1 sthet für 8 datenbits, 1 stopbit ?
 chris

von Christian Ege (Gast)


Lesenswert?

Hm es könnte sein das du den initstring noch raushauen musst aber ich
denke das dürfte den avr nicht stören. Hab jetzt das Datenblatt nicht
da aber stimmt deine odd Parity? N=> Odd parity L => None.

Versuch mal die hardwareflusskontrolle auszuschalten.

cu
chege

--: http://www.cybertux.org :--

von Daniel B. (khani)


Lesenswert?

Hallo ?

N -> odd parity ?!

Wo auch immer das so gehandhabt wird, ist es ein großer Unfug !
Normalerweise steht 8N1 für 8 bits Daten - parity _N_one - 1 stop-bit.

Mir persönlich ist die Bezeichnung (N) für eine odd-parity noch nie
untergekommen. Bitte überprüfen.

MfG, Daniel

von Daniel B. (khani)


Lesenswert?

Hallo

nochmal hier eine Referenz zur Bezeichnungslogik und anderen Daten zu
RS232 : http://de.wikipedia.org/wiki/RS232

MfG, Daniel

von Christian Ege (Gast)


Lesenswert?

Sorry mein Fehler ;-)

Im minicom ist die Taste L für none und O für ODD ;-)

N => None Parity stimmt natürlich. Bin Heute etwas verpeilt :-)


Tasten Einstellung Minicom
L: None  : =>  8N1
M: Even  : =>  8E1
N: Odd   : =>  8O1
O: Mark  : =>  8M1
P: Space : =>  8S1

Bin dann lieber still ;-)

cu
chege

von chris (Gast)


Lesenswert?

also, es is immer das gleiche se geht net :-( ....
hab inzwischen meine Parity eingestllt, dann uit mirg aufgefallen das
ich nicht angeb ob synchron oder asynchron ...
bei meinem Takt bin ich mir net sicher ob 1Mhz oder 3.68 Mhz
mein derzeitges Prog

   1 #include <avr/io.h>
    2
    3 int main ()
    4 {
    5
    6    int i,j;
    7    DDRB=255;
    8
    9    UBRR0H=0;
   10    UBRR0L=23;                 //9600 bps
   11    UCSR0B = (1<<TXEN)|(0<<UCSZ02);  // Transmiter enable
   12    // Set Frame Format
   13    UCSR0C=
(0<<UMSEL0)|(0<<USBS0)|(1<<UCSZ00)|(1<<UCSZ01)|(0<<UPM01)|(0<<UPM00);
       // 1 Stopbit, 8 Daten , No Parity
   14
   15
   16    PORTB=255;
   17    while(1)
   18    {
   19      while (!(UCSR0A & (1<<UDRE0)));  /* warten bis Senden
moeglich dh UDRE0=1                  */
   20      {
   21        UDR0 = 65;                     /* schreibt das Zeichen
auf die Schnittstelle */
   22      }
   23    for (i=0;i<1000;i++)
   24     {
   25     for(j=0;j<100;j++)
   26      {
   27       PORTB=~1;
   28      }
   29     }
   30    }
   31  return 0;
   32 }
   33
   34
....und es kommt nur Müll bei minicom an ...
hab die HardwareFlußkontrolle ain bzw ausgeshclatet .. also beides
probiert ..... es kommen nur punkte ..... obwohl 65 = a ...
muss ich in minicom angeben das in ascii zeichen augegebne werden soll
? ......
noch was .. ich hab mal die äußere while - schleife weggelassen
als bei jedem Reset wurde ein zeichen gesendet ....
minicom hat aber erst nach 2 maligm drücken der Reset taste was
ausgegeben ..... wie kann das sein ? ...
  chris
PS bei meinem minocom steht unten immer offline aber wenn ich resette
kommt schon was an ... ??

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

.

  Tasten Einstellung Minicom
  L: None  : =>  8N1
  M: Even  : =>  8E1
  N: Odd   : =>  8O1
  O: Mark  : =>  8M1
  P: Space : =>  8S1

Könnte es sein, daß das Benutzerinterface von "Minicom" kaputt ist?

von chris (Gast)


Lesenswert?

ein bischen Erfolg ....
als ich sende jetzt '6' .. aber im minicom kommt
666v6v6vvvvv6vvv6v66v6v6v dh 6 und v in ungeregelter reihenfolge
ich hab schon Umsel =1 oder =0 probiert ...
muss ich  noch was umstellen bei synchron ??
  chris

von Jens (Gast)


Lesenswert?

> Könnte es sein, daß das Benutzerinterface von "Minicom" kaputt ist?

Du meinst damit sicher das Betriebssystem, natürlich ist das kaputt :)
Er sollte einfach mal Windows benutzen, da kann nichts kaputt gehen.

von chris (Gast)


Lesenswert?

;-) ..... tja wie man's nimmt .....
naja komische beobachtung ... sende ich 6 kommt dazwischen nen v
sende ich 7 kommt dazwischen nen w ....

von chris (Gast)


Lesenswert?

hallo,
wenn ich das Programm starte :
    1 #include <avr/io.h>
    2
    3 void sende(char x)
    4 {
    5     while (!(UCSR0A & (1<<UDRE0)));  /* warten bis Senden
moeglich dh UDRE0=1                  */
    6     UDR0 = x;                     /* schreibt das Zeichen  auf
die Schnittstelle */
    7     return;
    8 }
    9
   10
   11 int main ()
   12 {
   13
   14    int i,j;
   15    DDRB=255;
   16
   17    UBRR0H=0;
   18    UBRR0L=6;                                            // 9600
bps
   19    UCSR0B = (1<<TXEN)|(0<<UCSZ02);                       //
Transmiter enable
   20    // Set Frame Format
   21    UCSR0C=
(0<<UCPOL0)|(0<<UMSEL0)|(0<<USBS0)|(1<<UCSZ00)|(1<<UCSZ01)|(0<<UPM01)|(0 
<<UPM00);
         // 1 Stopbit, 8 Daten bist
   22    UCSR0A= (0<<U2X0);    // normal  mode
   23    PORTB=255;
   24    while(1)
   25    {
   26   /* sende('a');
   27    sende('b');
   28    sende('1');
   29    sende('5');
   30    sende('6');
   31    sende('7');*/
   32    sende('8');
   33    sende('9');
   34   /*
   35    for (i=0;i<1000;i++)
   36     {
   37     for(j=0;j<100;j++)
   38      {
   39       PORTB=~1;
   40      }
   41     }*/
   42    }
   43  return 0;
   44 }

wird immer nur 8 bzw x ausgegebn ..... warum wird die funktion senden
nie mit '9' aufgerufen ??
  chris

von Martin #. (martin-)


Lesenswert?

Hallo chris.
Ich habe hier leider kein ATMega128 also kann ich diesen Code nicht
testen, aber laut dem Datenblatt müsste folgender Code Funktionieren,
sofern mit deiner Hardware alles in Ordnung ist:
1
void USART_Init( unsigned int baud )
2
{
3
    /* Set baud rate */
4
    UBRR0H = (unsigned char)(baud>>8);
5
    UBRR0L = (unsigned char)baud;
6
    /* Enable receiver and transmitter */
7
    UCSR0B = (1<<RXEN)|(1<<TXEN);
8
    /* Set frame format: 8data, 1stop bit */
9
    UCSR0C = (0<<USBS)|(1<<UCSZ1)|(1<<UCSZ0);
10
}
11
12
void USART_Transmit( unsigned char data )
13
{
14
    /* Wait for empty transmit buffer */
15
    while ( !( UCSR0A & (1<<UDRE)) ) ;
16
    /* Put data into buffer, sends the data */
17
    UDR0 = data;
18
}
19
  
20
 
21
22
int main ()
23
{
24
  USART_Init(0x000C);//fuer 19200 Baud
25
  while(1)
26
  {
27
    USART_Transmit('x');
28
    USART_Transmit('#');
29
    USART_Transmit('q');  
30
  }
31
  return 0;
32
}

Ein ähnlicher Code für ATMega8 funktioniert bei mir einwandfrei.
Trotzdem was hier ein Troll behauptet, funktioniert Zugriff auf
serielle Schnittstelle unter Linux recht zuverlässig.
Die Schnittstell soll aber noch konfigurieren werden:
stty -F /dev/ttyS0 ispeed 19200 cs8
und dann mit:
cat /dev/ttyS0 zeichen empfangen.

von chris (Gast)


Lesenswert?

hi,
geht leider auhc net :-( ...... wenn ich stty -F /dev/ttyS0 eingebe
kommt das

speed 9600 baud; line = 0;
min = 1; time = 5;
ignbrk -brkint -icrnl ixoff -imaxbel
-opost -onlcr
-isig -icanon -iexten -echo -echoe -echok -echoctl -echoke

kann das sein das ich min , oder time umstellen muss ??
  chris

von Martin #. (martin-)


Lesenswert?

>kann das sein das ich min , oder time umstellen muss ??
nein, es ist ok so.
>wenn ich stty -F /dev/ttyS0 eingebe
Ja das sind alle aktuellen einstellungen, gib einfach mal stty --help
um zu sehen was sie bedeuten.Es ist auch alles in Ordnung so.Aber es
ist auch alles eher unwichtig.

Wozo gibst du eigentlich stty -F /dev/ttyS0 alleine, damit werden doch
keine Einstellungen geändert ?

Wichtig ist Baudrate und Framenformat. Hat du es eingestelllt ? Auf
beiden Seiten muss es richtig eingestellt sein.
Bei dir seht aber dannach nicht aus(speed 9600 baud), der Code was ich
gepostet habe ist für 4MHz Quarz und 19200Baud.

Also:
stty -F /dev/ttyS0 ispeed baudrate cs8

und im Code entsprechenden Wert bei USART_Init(Wert) übergeben. Sonst
kannst du entweder nichts empfangen oder nur sinnlose Zeichen.

von Fritz G. (fritzg)


Lesenswert?

Ich kenn mich beim Board nicht aus, aber ist da kein Quarz drauf? Ohne
Quarz wirst keine saubere Baudrate zusammenbringen.
Wenn einer drauf ist, musst ihn mit den Fusebits erst enablen. Und dann
natürlich die USART Baudrate anpassen.

von Rolf F. (Gast)


Lesenswert?

Am besten fängst Du mit einem Echo an; d. h. die empfangenen Bytes
werden ungeändert zurück geschickt, so wie von einer Drahtbrücke.
In einem Programm wie minicom sieht man dann, ob die Daten ankommen
oder nicht und ob sie auch unverändert ankommen.
Mit Drahtbrücken am seriellen Port und direkt vor dem MC bekommt man
heraus, ob die Hardware funktioniert. Erst nach diesen Test macht es
Sinn die Software auf dem MC zu betrachten.

von Martin #. (martin-)


Lesenswert?

Mir ist noch ein kleiner Fehler unterlaufen:
Die Komandozeile muss lauten:#
1
stty -F /dev/ttyS0 ispeed 19200 cs8 raw -cstopb
Damit alles auf einen Schlag richtig konfiguriert ist, für den Empfang
von dem MCU.

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.