Forum: Mikrocontroller und Digitale Elektronik Ausgabe an UART


von Maria (Gast)


Lesenswert?

Hallo!

Bin neu dabei. Habe jetzt eine Schaltung und ein C-Programm. Hiermit
möchte ich eine Spannung messen und an die UART senden. Das Programm
hat den AD-Wandler initialisiert. Zum testen möchte ich jetzt Werte
zwischen 0 und 1023 an die UART senden. Gibt es in der Library eine
Funktion, mit der ich das machen kann, ohne dass ich jetzt ein
Konvertierungs-programm schreiben muss? Habe im Tutorial eine Funktion
fdevopen(.., ..) gefunden sowie diverse andere (uart_putc()). Verstehe
diese aber auch mit Hilfe der libc-library nicht.

Habe die Zeile fdevopen(uart_putc, NULL, 0); einfach mal in mein
Programm eingefügt. Hierbei sagt der Compiler aber, dass ich der
Funktion zu viele Argumente übergebe. Hat sich etwas an der Library
geändert?

lg, Maria

von Michael (Gast)


Lesenswert?

Alle warten ganz gespannt darauf, welchen µP und welchen Compiler Du
meinst.

Du kannst aber in der Codesammlung nach 'hex nach dezimal' o.ä.
suchen. Das brauchst du sicherlich. Es sei denn, Du verwendet das
schnöde printf().

von Maria (Gast)


Lesenswert?

Hallo!

weiter unten habe ich noch etwas zur Hardware geschrieben

mein main.c Programm sieht so aus: (Möchte zum Testen des AD Wandlers
den Wert aus dem Data Register an das Terminal Programm des Computers
schicken)

#include "main.h"

int main(void)
{

  unsigned int result_adc = 0;
  unsigned int manipul = 0;

  UART_init();
  ADC_init();

  result_adc = ADC_read();

  UDR = result_adc;
  while (!(UCSRA & (1<<UDRE)));

  manipul = result_adc & 768; //Maskierung
  manipul = manipul >> 8; //shift right 8x
  manipul = manipul + 0x30;
  if (manipul > 0x39) manipul = manipul + 0x7;
  UDR = manipul;
  while (!(UCSRA & (1<<UDRE)));

  manipul = result_adc & 240; //Maskierung
  manipul = manipul >> 4; //shift right 4x
  manipul = manipul + 0x30;
  if (manipul > 0x39) manipul = manipul + 0x7;
  UDR = manipul;
  while (!(UCSRA & (1<<UDRE)));

  manipul = result_adc & 15; //Maskierung
  manipul = manipul + 0x30;
  if (manipul > 0x39) manipul = manipul + 0x7;
  UDR = manipul;
  while (!(UCSRA & (1<<UDRE)));

}


ad.c sieht so aus:

#include "main.h"
#include "ad.h"



void ADC_init(void)
{
  // Initialisierung des AD-Wandlers
  // ADLAR im MUCX Register ist nicht gesetzt.

  ADMUX=ADC_VREF_TYPE;

  ADCSRA=(1<<ADEN)|ADC_PRESCALER; //ADEN entspricht ADC Enable bit

  //Zum "Warmlaufen wird einmal die Spannung gemessen

  ADCSRA |= (1<<ADSC); // Start der AD Conversion
  while ( ADCSRA & (1<<ADSC) ); // auf Abschluss der
Konvertierung warten
}


unsigned int ADC_read(void)
{
  // Lesen des ausgeählten Kanals ADC0

  unsigned int result = 0;

  ADCSRA|=1<<ADSC; //Start der AD Conversion

  while ((ADCSRA & (1<<ADIF)) == 0); //auf Abschluss der Konvertierung
warten
  result = ADCW;

  return result;
}

Es kommt jetzt immer auf dem Terminal eine hex Zahl heraus, die aber
nicht dem wirklichen wert im Data Register des AD Wandlers sein kann.
Habe super viel herumgesucht und finde einfach keinen Fehler, woran
kann es liegen? Muss ich den AD Port noch so initialisieren, dass er
auf "Eingang" geschalten sein muss?

Zur Hardware:
Habe AVCC=5V, AREF=AVCC (hierfür 10µH Drossel (Hochfrequenz) von AREF
nach VCC, sowie 100nF (Keramik) von AREF nach GND. Die Messspannung
kommt zum Testen von einer Konstantspannungsquelle (Wahlweise zwischen
0 und 5V) und liegt an ADC0 an. Zwischen ADC0 und GND noch ein
Folienkondensator (10nF)

Bitte helf mir, ist mein erstes c-Programm,

lg Maria

von Michael (Gast)


Lesenswert?

result_adc = ADC_read();

Ändere doch 'mal: result_adc = 0x123;
Was kommt dann am Rechner an ?

von Maria (Gast)


Lesenswert?

@ Michael

Danke, dass du dir das angesehen hast. Es war nur ein kleines Kabel
locker. Jetzt kommt der Wert aus dem Data Register in hex super am
Terminal Programm an.

@ an alle

Jetzt bleibt mir nur noch die Frage, wie ich in c am einfachsten einen
Integer Wert oder vieleicht sogar eine Gleitkommazahl auf einem ASCII
Display oder dem Terminal Programm ausgeben kann. Habe mir schon das
Tutorial und einige Programme in der Codesammlung angesehen, z.B. Das
Programm ADC Test unter dem Link:
http://www.mikrocontroller.net/forum/read-4-260506.html

Hier werden auch einige Funktionen aus der Library verwendet.
Ich verwende WINAVR (neueste Version), dort ist ja auch ein C-Compiler
mit dabei, die Library finde ich als Anfängerin wie schon gesagt sehr
unverständlich.

Wäre super, wenn mir jemand helfen könnte. Verstehe das "schnöde
printf" (@Michael) auch gar nicht in Bezug auf den Mikrocontroller. Da
ich mir schon sehr viel angesehen habe, hoffe ich, dass mir jemand noch
einen konkreten Link oder so geben kann, vieleicht auch ein kleines
Beispiel?

lg, Maria

von Karl H. (kbuchegg)


Lesenswert?

sprintf

Duerfte wohl das einfachste sein.

von Rahul (Gast)


Lesenswert?

oder dir xTOA-Reihe...

von Michael (Gast)


Lesenswert?

Das 'schnöde printf()' sollte als Oberbegriff für alle Xprintf()
stehen und ausdrücken, daß hiermit auf einfachste Weise
Zahlenumwandlungen gemacht werden können. Die Funktion braucht
allerdings einige KB Speicherplatz, was nicht stören muß, der aber bei
kleinen µPs schlicht nicht vorhanden ist. Daher mein Verweis auf die
Codesammlung, wo sich Beispiele finden, kleine Zahlenwerte über
spezielle Funktionen von hex->dez zu wandeln.

Ab Mega16 sollte aber der Speicher für sprintf() reichen, sodaß Du
hiermit die einfachste Wandlung (auf für float) in C schreiben kannst.
Um ein Zeichen über UART auszugeben, mache Dir besser ein Unterprogramm
und frage immer erst ab, ob der Sendepuffer frei ist, bevor ein neues
Zeichen in UDR geschrieben wird (zuerst while() und dann UDR = ).
Andernfalls wird das Programm unnötig ausgebremst.

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.