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?
Nein, denn mit adcval und adcval1 machst du im Anschluß nichts.
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.
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.
z.b. am ende wo ich while (readchannel... geschreiben habe? was meinst du mit returnen ? meinst du jetzt den Befehl return?
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.
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
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
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 :)
So sieht mein Code. habe auch die Bit zahl geändert (soweit ich glaub XD). adcval und adcval1 habe ich trotzdem gelassen.
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
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)
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.