Forum: Compiler & IDEs Senden von "Zahlen" über UART


von EinSteigÄr (Gast)


Lesenswert?

Hallöle!

Ich möchte Zahlen über meinen UART senden. Wie mache ich das am besten? 
Bisher ist es mir nur gelungen, char's zu senden.:

 UDR = 'x';

Ich möchte also das TCCR0-Register und diverse Überlauf-Variablen 
dezimal an mein VisualBasic-Programm schicken.

Vielen Dank

von Karl H. (kbuchegg)


Lesenswert?

EinSteigÄr wrote:
> Ich möchte Zahlen über meinen UART senden. Wie mache ich das am besten?

Indem du sie in ihrer Textform verschickst.
Wie man eine Zahl in ihre Textform überführt findest du
zb hier.

http://www.mikrocontroller.net/articles/FAQ#Wie_kann_ich_Zahlen_auf_LCD.2FUART_ausgeben.3F


von EinSteigÄr (Gast)


Lesenswert?

Hmm, habe es durchgelesen...

ich möchte wiegesagt eine Variable über den UART schicken, damit der 
wert der variablen als "dezimale" Zahl in meinem Programm erscheint.


Ich würde mich mal für diese sprintf() variante interessieren:
______________________________________________

char Buffer[20];                  //Ist das die Anzahl der Zeichen, die 
gewandelt werden müssen? also 20?

  sprintf( Buffer, "%d", i );    //steht i für die Array-Position?


Das heißt doch, dass ich eine Array mit 20 "Buchstaben" habe, und diese 
Buchstaben in dezimal wandle?!

danke

von Karl H. (kbuchegg)


Lesenswert?

Nein.
Das heist das du eine Zahl hast und sprintf wandelt dir
eine Zahl in einen String, einen Text um.
Aus 5436 wird der String "5436"
Und den kannst du dann als ganz normalen Text verschicken.

Der Vorteil einer Textform ist es, dass diese von jedem
Programm leicht aufgefangen werden kann (und dann eventuell
wieder in eine Zahl verwandelt wird). Aber auch jedes
Terminal, bzw. jedes Terminalprogramm kann so einen Text
unmittelbar anzeigen.

von Karl H. (kbuchegg)


Lesenswert?

> char Buffer[20];           //Ist das die Anzahl der Zeichen, die
> gewandelt werden müssen? also 20?

Die 20 bedeuten, dass dieses Array maximal einen String
der Länge 20 aufnehmen kann. Für eine int Zahl brauchst du
wesentlich weniger. Ein 16-Bit Integer kann ja minimal
-32768 gros sein. Dafür brauchst du daher maximal
eins, zwei, drei, ..... sechs Zeichen (inklusive Vorzeichen).
Dazu noch das obligatorische abschliessende '\0' Zeichen
für Strings und mit einem Array der Länge 7 bist du dabei.
Mehr schadet nicht: Ein String der Länge 7 kann ohne Probleme
in einem Array der Länge 10 oder 20 gespeichert werden.
(Siehe auch im gleichen Artikel etwas weiter unten den
Abschnitt über String-Verarbeitung).


von Karl H. (kbuchegg)


Lesenswert?

>  sprintf( Buffer, "%d", i );    //steht i für die Array-Position?

Nein.
i ist die Zahl die gewandelt werden soll.

   char Buffer[20];
   int i = 5436;

   sprintf( Buffer, "%d", i );

   // Buffer enthält jetzt den String "5436"

Du solltest dir Literatur zum Thema 'C' besorgen.
Ohne sie wirst du nicht weit kommen.


von EinSteigÄr (Gast)


Lesenswert?

hmm könntet ihr mir dann mal so nen kleinen Codeschnipsel zukommen 
lassen?

Etwa wie diesen FALSCHEN von mir?


char Buffer[3] = {1,2,3};
for (i=0;i<3;i++)
{
char Buffer[i];

  sprintf( Buffer, "%d", i );
}



danke

von EinSteigÄr (Gast)


Lesenswert?

ok danke, habs gelesen

von EinSteigÄr (Gast)


Lesenswert?

habe jetzt folgenden Code:

#include <inttypes.h>
#include <avr/io.h>
#include <util/delay.h>


void enableTx(void)
{
while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich 
*/
{
}
}

/////////////////// Im Terminalprogramm wird eine Baudrate von 9600 
eingestellt

int main (void)
{

char s[7];


int y=4;
char string1[10] = {'J'};

UCSRB |= (1<<TXEN);              //Senden aktivieren
UCSRC |= (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);  //

UBRRH = 00;                      //Baudrate einstellen 9600 bei 8 MHz
UBRRL = 51;




char Buffer[20];
   int i = 5436;

   sprintf( Buffer, "%d", i );

UDR = Buffer;

   // Buffer enthält jetzt den String "5436"

}



Am VB-Programm kommt jedoch ein "L" an.

von EinSteigÄr (Gast)


Lesenswert?

PS: ich habe schon ein Buch in amazon letzten Samstag bestellt :-)

von Karl H. (kbuchegg)


Lesenswert?

EinSteigÄr wrote:
> char Buffer[20];
>    int i = 5436;
>
>    sprintf( Buffer, "%d", i );
>
> UDR = Buffer;

Wie soll das gehen.
Buffer ist ein String, also eine Abfolge von einzelnen Zeichen.
UDR hingegen kann nur ein einzelnes Zeichen fassen.

Du musst dir schon eine Funktion schreiben, die einen
String entgegen nimmt und den Zeichen für Zeichen
über die UART verschickt.

Dazu schreibst du dir als erstes mal eine Funktion die
ein einzelnes Zeichen korrekt verschickt!
Denn einfach so mit Zuweisen an UDR ist es ja nicht getan.
An UDR zuweisen kannst du sinnvollerweise erst dann,
wenn die UART auch bereit ist ein Zeichen entgegen zu nehmen
(Das steht aber eigentlich auch alles im AVR-gcc Tutorial
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Senden_mit_dem_UART 
)
1
int uart_putc(unsigned char c)
2
{
3
  while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
4
  {
5
  }
6
 
7
  UDR = c;                      /* sende Zeichen */
8
  return 0;
9
}
10
 
11
void uart_puts (char *s)
12
{
13
  while (*s)
14
  {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen" */
15
    uart_putc(*s);
16
    s++;
17
  }
18
}

und mit diesen Hilfsfunktionen macht man dann:
1
  char Buffer[20];
2
  int i = 5436;
3
4
  sprintf( Buffer, "%d", i );
5
6
  uart_puts( Buffer );

  

von EinSteigÄr (Gast)


Lesenswert?

ok. vielen Dank. hat geklappt. Habe noch eine Funktion dazu geschrieben, 
die "sendet und wandelt".

Klappt super:)

von EinSteigÄr (Gast)


Lesenswert?

Hilfee es klappt nicht mehr. Was habe ich gemacht dass er nichts mehr 
sendet?? Ich dreh gleich am Rad^^

danke:

#include <inttypes.h>
#include <avr/io.h>



int uart_putc(unsigned char c)
{
  while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
  {
  }

  UDR = c;                      /* sende Zeichen */
  return 0;
}




void uart_puts (char *s)
{
  while (*s)
  {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen" */
    uart_putc(*s);
    s++;
  }
}

int wandle(int y)
{
char Buffer[20];
  int i = y;

  sprintf( Buffer, "%d", i );

  uart_puts( Buffer );

}


/////////////////// Im Terminalprogramm wird eine Baudrate von 9600 
eingestellt

int main (void)
{



int testvar=0xFF;
int y=4;
char string1[10] = {'J'};

UCSRB |= (1<<TXEN);              //Senden aktivieren
UCSRC |= (1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);  //

UBRRH = 00;                      //Baudrate einstellen 9600 bei 8 MHz
UBRRL = 51;


wandle(testvar);            //soll "0xFF" über UART schicken



}

Es kommt nichts mehr in meinem Terminal an

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


Lesenswert?

Habe in die UART-Registernamen ein paar 1 eingefügt und das Ganze auf
einem ATmega1281 laufen lassen.  Es kommen fotlaufend 255255255255
auf dem Terminal an.

#include <stdio.h> fehlte noch.

Wie schreibt doch Cliff Lawson so schön in seiner signature auf
avrfreaks.net:

FAQ#3: 99.9% of UART errors are AVRs not being clocked right

Bist du dir sicher, dass deine 8 MHz auch stimmen?  (Und du nicht
z. B. noch den Taktteiler auf 1 MHz drin hast oder sowas.)

p.s.: Bitte benutze [ c ] ... [ /c ] Markierungen, damit deine
Programme ordentlich formatiert bleiben und nicht wild umgebrochen
werden.

von EinSteigÄr (Gast)


Lesenswert?

Vielen Dank, habe es aber wieder hingekriegt. Ganz komisch....Habe das 
<stdio.h> weiterhin NICHT eingefügt, und es funktioniert so wie vorher, 
wo es auch nicht dabeistand.

danke:)

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.