Forum: PC-Programmierung ATMEGA32 (Daten verarbeiten und senden)


von Rafael B. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Leute,
Ich arbeite zum ersten Mal mit Mikrocontroller und wollte Tipps holen.

Ich habe soweit versucht ein Programm in C zuschreiben, damit der 
Mikrocontroller 2 AD Werte einliest und die an den PC weitergibt (siehe 
Anhang). Damit ich 2 AD kriege habe ich versucht diese nacheinander 
abzufragen mit einer case-Abfrage.
Kann man dies so tun?

von The D. (thedaz)


Lesenswert?

Nein, denn mit adcval und adcval1 machst du im Anschluß nichts.

von Rafael B. (Gast)


Lesenswert?

klar, es wird noch an den beiden Ports (Channel 1 und 5) eine ASM 
angehangen, um Drehmoment und Drehzahl einzulesen.
Wollte mal Informationen sammeln, ob eine case Abfrage sinvoll wäre.

von The D. (thedaz)


Lesenswert?

Wenn ReadChannel den gelesenen Wert returnen würde wäre es eine 
sinnvolle Funktion. Aber das switch statement ist dort überflüssig. Die 
Unterscheidung der ADC channel sollte außerhalb dieser Funktion 
stattfinden. Dort wäre ein switch evtl sinnvoll.

von Rafael B. (Gast)


Lesenswert?

z.b. am ende wo ich while (readchannel... geschreiben habe?

was meinst du mit returnen ? meinst du jetzt den Befehl return?

von Rafael B. (Gast)


Lesenswert?

sieht der code sonst vernünftig aus?

von The D. (thedaz)


Lesenswert?

Rafael B. schrieb:
> z.b. am ende wo ich while (readchannel... geschreiben habe?
>
> was meinst du mit returnen ? meinst du jetzt den Befehl return?

Der return Befehl gehört dazu, ja. Aber auch der Wert bzw. der Inhalt 
einer Variablen.

von The D. (thedaz)


Lesenswert?

Rafael B. schrieb:
> sieht der code sonst vernünftig aus?

Nein. Ohne return value von ReadChannel funktionieren deine while loops 
nicht. Mit return value wird der ADC channel 5 nie ausgelesen, es sei 
denn, channel 4 liefert einmal den Wert 0. Danach holst du nie wieder 
vom channel 4 Daten.

: Bearbeitet durch User
von Rafael B. (Gast)


Angehängte Dateien:

Lesenswert?

hab nun den code was abgeändert.

von The D. (thedaz)


Lesenswert?

Schon besser. uart_putc und uart_putc1 sind identisch, du brauchst nur 
eine davon. Diese Funktion braucht auch kein return statement, von einer 
put Routine erwartet man nur, dass sie was schreibt. Außerdem solltest 
du nicht bei jedem ReadChannel Aufruf den ADC enablen bzw. die 
Referenzspannung wählen, sowas gehört in eine setup routine, die 
einmalig am Programmanfang aufgerufen wird. Dort sollte dann auch der 
UART setup passieren.

Derzeit schickst du die ADC Werte als 8-bit integer Binärwert zur UART. 
Dein ADC hat aber 10 bit, du verlierst beim senden die oberen 2 bits und 
auf der Empfängerseite kommt nur unbrauchbarer Zahlenmüll an. Besser ist 
es vermutlich über die UART lesbare Textnachrichten zu verschicken, die 
dann auch die zum jeweiligen ADC Wert zugehörige ADC Kanalnummer 
enthalten. z.B. sowas : "CH4:128,CH5:572,..."

Desweiteren kannst du die adcval und adcval1 Variablen einsparen und 
besser sowas hinschreiben :
1
uart_putc(ReadChannel(4));
2
uart_putc(ReadChannel(5));

: Bearbeitet durch User
von Rafael B. (Gast)


Lesenswert?

Vieln Dank für deine tollen Tipps!!!
die variabeln habe ich gelassen für mich als Übersicht sowie putc und 
putc1, aber klar man könnte die weg tun bzw. zusammenfassen... 
vielleicht tue ich es noch ^^
sonst nochmal danke für die Tipps :)

von Rafael B. (Gast)


Angehängte Dateien:

Lesenswert?

So sieht mein Code. habe auch die Bit zahl geändert (soweit ich glaub 
XD). adcval und adcval1 habe ich trotzdem gelassen.

von The D. (thedaz)


Lesenswert?

Mit der Zeile
1
UDR = adcval;
schneidest du immernoch die oberen 2 bit des ADC Werts ab und 
produzierst Datenmüll.

Besser wäre
1
UDR = adcval >> 2;

Damit schneidest du die unteren 2 Bit ab aber behältst nutzbare Daten.

Der return type von uart_putc sollte void sein sonst gibt's Compiler 
Warnungen.

: Bearbeitet durch User
von Rafael B. (Gast)


Lesenswert?

und so kann ich diese in 8 bit anzeigen lassen. ah verstehe!
also soll auch anstatt das: UBRRH = (uint16_t) (UBRR_VAL >> 10)
das stehen: UBRRH = (uint8_t) (UBRR_VAL >> 8)

von The D. (thedaz)


Lesenswert?

Rafael B. schrieb:
> und so kann ich diese in 8 bit anzeigen lassen. ah verstehe!
> also soll auch anstatt das: UBRRH = (uint16_t) (UBRR_VAL >> 10)
> das stehen: UBRRH = (uint8_t) (UBRR_VAL >> 8)

Ja, genau. Der Kommentar in der Zeile ist natürlich Unsinn.

: Bearbeitet durch User
von Rafael B. (Gast)


Lesenswert?

ich lerne immer mehr dazu!

von The D. (thedaz)


Lesenswert?

Gut :)
Die Zeile
1
ADMUX &= ~mux;
ist überflüssig.

von Rafael B. (Gast)


Lesenswert?

habe mir gedacht, dass nachdem ein wert in einem der channel gspeichert 
wird, müsste dieser dann wieder gelöscht werden damit ein neuer wert 
gelesen wird

von The D. (thedaz)


Lesenswert?

Rafael B. schrieb:
> habe mir gedacht, dass nachdem ein wert in einem der channel gspeichert
> wird, müsste dieser dann wieder gelöscht werden damit ein neuer wert
> gelesen wird

Wenn du den alten Wert löschen wolltest, müsstest du den Wert des alten 
Kanals kennen. In deiner Routine kennst du aber nur den neuen. Und mit 
der Zuweisung des neuen Kanals überschreibst du eh den vorherigen Wert.

Ich habe gerade mal das Datenblatt angeschaut. Leider habe ich dir wegen 
des ADC setups was falsches gesagt. Die Zeile
1
ADMUX |= (1<<REFS1) | (1<<REFS0);

in der ADC_setup Routine muss tatsächlich in die ReadChannel Funktion. 
Statt
1
ADMUX = mux;
muss es dort heißen
1
ADMUX = (1<<REFS1) | (1<<REFS0) | mux;

: Bearbeitet durch User
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.