Hallo µC.net Leser,
ich habe vor mit einem Mega8 3 Verschiedene Spannungen (Eingang 12-20V,
Ausgang 5V und 9V) zu messen für eines meiner Projekte[1]. Unter anderem
eben die Versorgungsspannung des Mega8, welcher am 5V Ausgangszweig des
unter [1] verlinken Projektes hängt.
Nun sind mir da ein paar Fragen aufgekommen, die ich gerne vor der
Hardwarebestellung geklärt hätte. Ich werde, wie im Datenblatt
vorgeschlagen, ein LC Netzwerk an den AVcc Pin packen und auch eine
Analoge Ground Plate nutzen.
Um die Vcc zu messen werde ich einen hier im Forum gefunden Tip[2]
nutzen, und über die interne Bandgab-Referenz auf Vcc schliessen.
Nun bleiben noch die beiden Spannungen Input und 9V, die muß ich ja dann
auf die Referenzspannung skalieren.
Und genau da wäre jetzt meine Frage, wenn mich bei der Eingangsspannung
der Bereich von 12-20Volt interessieren würde, dann müßte ich doch den
Spannungsteiler für den Input am Mega8 so bauen, dass bei 12V Eingang,
am Mega8 ~0V ankommen und bei 20V eben AVcc (5Volt oder intern 2,56V ist
hier noch eine Frage)? Richtig soweit? Das gleiche dann bei den 9Volt
(Bereich 7,5V-10,5V).
Also wäre die Rechnung für die Eingangsspannung bei folgendem ST
1
o-----------+
2
Input |
3
Uin +-+
4
| | R1
5
+-+
6
|
7
+---------o AVR (Uref)
8
|
9
+-+
10
| | R2
11
+-+
12
|
13
o-----------+
in etwa:
mit den Werten
Uin = 20V, Uref = 5V und R2 = 1kOhm
macht das also für R1 = 3,2kOhm und das müßte dann passen, oder?
Dann wäre noch die Frage ob es sinnvoll wäre Vcc als AVcc zu nehmen oder
besser die interne. Und kann das prinzipiell so funktionieren?
Theoretisch hätte ich ja die genaue Vcc ermittelt über den
Bandgab-Referenz Trick und könnte für die anderen Messungen mit diesem
Wert rechnen.
Vielleicht merkt man dass das mein erstes ADC Projekt ist, ich teste das
hier mit meinem Evaluationsboard auch soweit das geht, aber so eine
Bestätigung dass man nicht auf dem Holzweg ist, wäre schön. Zumindest
wüßte ich dann ob ich die Theorie verstanden habe und das auch so
klappen könnte ...
Gruß
Jens
[1] Beitrag "2 Spannungen, rel. hohe Leistung"
[2] Beitrag "AVR: Vcc gegen interne Referenz messen möglich?"
Hi
>Dann wäre noch die Frage ob es sinnvoll wäre Vcc als AVcc zu nehmen oder>besser die interne.
Ich glaube du meinst etwas anderes.
>Und genau da wäre jetzt meine Frage, wenn mich bei der Eingangsspannung>der Bereich von 12-20Volt interessieren würde, dann müßte ich doch den>Spannungsteiler für den Input am Mega8 so bauen, dass bei 12V Eingang,>am Mega8 ~0V ankommen und bei 20V eben AVcc (5Volt oder intern 2,56V ist>hier noch eine Frage)?
Das geht mit einem Spannungsteiler so nicht. 20V nach Vref ja. 8V nach
0V nein (oder 20V auch 0V) .
>Theoretisch hätte ich ja die genaue Vcc ermittelt über den>Bandgab-Referenz Trick und könnte für die anderen Messungen mit diesem>Wert rechnen.
Theoretisch. Kannst du sicher sein, das VCC noch gleich dem Wert ist,
den du zuvor mit der Messung gegen die Referenz ermittelt hast?.
VCC als Referenzspannung ist nur dann sinnvoll wenn sich die zu messende
Spannung im gleichen Maße wie VCC ändert. Z.B. du willst du die Stellung
eines Potentiometers einlesen, das auch an VCC hängt.
VCC-unabhängige Messwerte erreichst du nur durch Benutzung der internen,
oder bei höheren Anforderungen einer externen Referenz.
MfG Spess
Mhm, also heißt das ich kann nicht nur einen Bereich "raussuchen" mit
dem Spannungsteiler, und habe, wenn meine maximal Eingangsspannung 20V
ist, beim 10-Bit ADC des Mega8, eine Auflösung von
? Naja, damit könnte ich auch leben.
Ich möchte die drei Spannungen ja nur anzeigen, also nix wildes. Werd
das einfach mal ausprobieren so.
Vielen Dank schonmal
Jens
Jens Krause schrieb:
> Mhm, also heißt das ich kann nicht nur einen Bereich "raussuchen" mit> dem Spannungsteiler,
Drum heißt das Ding ja auch Spannungs/teiler/ und nicht
Spannungs/subtrahierer/
> und habe, wenn meine maximal Eingangsspannung 20V> ist, beim 10-Bit ADC des Mega8, eine Auflösung von> 20V/1024 = 0,01953V?
Ganz genau
So, heut morgen kamen die 1% Widerstände für die Spannungsteiler. Also
die anliegende Spannung am ADC kann ich ziemlich genau auf mein LCD
bringen, habs noch nicht auf die Eingangsspannung umgerechnet. Danke
nochmal für die Zaunpfahlwinkerei g ...
Gruß
Jens
So, ich habs geschafft alle drei Spannungen anzuzeigen (siehe Anhang).
Ich hab jetzt aber mal ne C-Frage, vielleicht ist das ne ganz dumme
Anfängerfrage (kannte bis jetzt nur Java), aber ich hab etwas nicht so
hinbekommen wie ich wollte.
Hier mal mein kompletter Quellcode:
aufrufen.
Aber das funktionierte nicht. Nun dacht ich mir, da klappt was mit dem
casten auf den unsigned int nicht, hab es aber nicht hinbekommen ...
Lieg ich da richtig? Und wenn ja, wie könnte ich das lösen?
Jens
> aufrufen.> Aber das funktionierte nicht. Nun dacht ich mir, da klappt was mit dem> casten auf den unsigned int nicht,
Du kannst die 9000 long machen so viel du willst. Das ändert nichts
daran, dass hier
maxvoltage ein 16 Bit Datentyp ist, ebenso wie adc. Deine 9000L werden
bei der Übergabe sofort wieder zu 16 Bit eingedampft.
Daher wird hier
1
adc*maxvoltage
16-Bit Arithmetik betrieben. Und 1024 * 9000 ergäbe 9216000, welches
wiederrum viel zu groß für ein 16 Bit Ergebnis ist.
Hier
1
uint16_tconvert9Voltage(uint16_tadc){
2
return(adc*9000L)/1024L;
3
}
liegt die Sache anders. Wenn du nur
1
adc*9000L
betrachtest, dann wird hier ein uint16_t, also ein 16 Bit Datentyp mit
einem long, also einem 32 Bit Datentyp, multipliziert. Und in dem Fall
gewinnt der größere Datentyp -> die Multiplikation wird als 32 Bit
Multiplikation ausgeführt. Und in 32 Bit ist 9216000 ohne Probleme
darstellbar.
-> Bei jeglicher Rechnerei, bei jeder Operation, immer überlegen:
welcher Datentyp steht links von der Operation, welcher rechts davon.
Der größere der beiden gewinnt und in diesem Datentyp kriegst du auch
das Ergebnis der Operation. Das kann dann wieder zb die linke oder
rechte Seite einer anderen Operation sein usw. oder aber auch das
Endergebnis welches dann einer Variablen zugewiesen wird, wobei es dann
vor der Zuweisung wieder auf den Datentyp der Zielvariable umgewandlt
wird.
Das ist ein häufiger Trugschluss:
uint32_t result;
uint16_t a, b;
result = a * b;
und die Frage dazu: Hilfe, warum klappt die Berechnung nicht? Ich weise
ja ohnehin an eine 32 Bit Variable zu!
Schon. Das ist aber für die Berechnung an sich uninteressant. Links vom
* steht ein 16 Bit Wert, rechts davon steht ein 16 Bit Wert. Also wird
die Multiplikation als 16 Bit Multiplikation durchgeführt (welche
überläuft) und erst dann das fehlerhafte Ergebnis auf 32 Bit gebracht.