Hallo,
also es geht um folgendes. Ich habe 2 Spannungen zu messen. Die eine
steht für eine Leistung (entsprechend vorbereitet) und die andere steht
für die Richtigkeit der ersten Spannung (wegen der Linearität des IC der
die erste Spannung erzeugt).
Nun wandle ich die beiden Spannungen und entscheide dann was zu tun ist.
Hier is der Code dazu:
1
#include<avr/io.h>
2
#include<stdint.h>
3
#include<lcd.h>
4
5
//Funktionsdeklaration (Prototypen)
6
7
//ADC Init.
8
voidvinitADU_8Bit(unsignedshortint);
9
10
intigetADU_8Bit(unsignedshortint);
11
12
13
voidmain(void)
14
{//Variablen Definition
15
charcPuffer[100];
16
intiPuffer=0,iWait=0;
17
18
//Deklaration der PORTS --> "Richtung"
19
DDRD=0xff;//0xff --> Ausgang
20
DDRC=0x00;//0x00 --> Eingang
21
DDRB=0xff;
22
PORTB=0xff;
23
24
25
//Initialisierung des ADCs
26
vinitADU_8Bit(0);
27
28
29
/* Initialisiere Display, Cursor aus*/
30
lcd_init(LCD_DISP_ON);
31
32
/* loesche das LCD Display und Cursor auf 1 Zeile, 1 Spalte */
ADCSRA|=(1<<ADSC);// eine Wandlung "single conversion"
2
while(ADCSRA&(1<<ADSC))
3
{
4
// auf Abschluss der Konvertierung warten
5
iresult=ADCH;// Wandlungsergebnisse abholen
6
}
Ähm. Welche Vorstellung hast du vom Begriff 'Warten'? Was wird man
sinnvollerweise tun, während man wartet? Den ADC auslesen? Eher nicht.
Denn ADC wird man auslesen, nachdem das Warten vorbei ist. Denn das war
ja der Sinn des Wartens: den ADC in Ruhe seine Arbeit machen lassen. Ist
er fertig, meldet er sich. Die Warterei hat ein Ende und man kann sich
den Wert holen.
Weiter gehts
1
ADCSRA&=~(1<<ADEN);// ADC deaktivieren (2)
Aha. Wer schaltet eigentlich im nächsten Schleifendurchlauf, beim
nächsten Aufruf der get Funktion, den ADC wieder ein?
bist du sicher, dass du hier in jedem Durchlauf durch die Schleife den
ADC-Kanal 2 tatsächlich 2 mal neu abfragen willst?
Im schlimmsten (zugegeben konstruierten) Fall liefert der erste Aufruf
den Wert 51 und der zweite Aufruf den Wert 4. Und trotzdem wird dann
keiner der Werte korrekt ausgewertet.
JTR schrieb:
> Was übersehe ich? Das Problem ist nämlich das ich nie in den zweiten> Zweig komme :(.
Noch ein Hinweis:
Du hast ein LCD zur Verfügung.
Niemand hindert dich daran, es in der Entwicklungsphase auch dazu zu
benutzen, sich Werte anzeigen zu lassen, wie zb die Werte, die der ADC
liefert (ohne Umrechnung, so wie der ADC den Wert auswirft).
Solche Hilfsausgaben, die natürlich wieder entfernt werden wenn alles
ferig ist, sind oft sehr hilfreich um zu verstehen, was in einem
Programm abgeht und um Problemen auf die Spur kommen zu können.
Karl heinz Buchegger schrieb:
> int igetADU_8Bit(unsigned short int usimux)
1
{intiresult;
2
ADMUX=usimux;// Kanal waehlen
>>> Tja. Damit ist dann die Einstellung der Referenzspannung hinfällig> geworden.
Also was du damit meinst ist mir nicht klar?!
1
ADCSRA|=0x80;//ADC aktivieren (1)
Damit wird der ADU in jedem Durschlauf wieder aktiviert!
Karl heinz Buchegger schrieb:
> bist du sicher, dass du hier in jedem Durchlauf durch die Schleife den> ADC-Kanal 2 tatsächlich 2 mal neu abfragen willst?> Im schlimmsten (zugegeben konstruierten) Fall liefert der erste Aufruf> den Wert 51 und der zweite Aufruf den Wert 4. Und trotzdem wird dann> keiner der Werte korrekt ausgewertet.
Naja, die Spannung die gewandelt wird, wird über ein Poti eingestellt
(zur Zeit noch). Das stell ich ein mal ein und dann greif ich es nicht
mehr an. Mit Voltmeter gemessen: am Kanal 2 liegen zB 2,5V an
Trotzdem geht er nicht in den 2. Zweig, obwohl 2,5V etwa 127 ergeben
sollte.
Ich verwende das LCD sehr wohl! :D
So, mal ein riesen Danke an dich Karl Heinz, dass du mir so genau Tipps
gegeben hast. Ich komme leider erst morgen dazu deine Tipps aus zu
probieren.
JTR schrieb:
> Karl heinz Buchegger schrieb:>> int igetADU_8Bit(unsigned short int usimux)>
1
{intiresult;
2
>ADMUX=usimux;// Kanal waehlen
>>>>>> Tja. Damit ist dann die Einstellung der Referenzspannung hinfällig>> geworden.>> Also was du damit meinst ist mir nicht klar?!
i = 5;
i = 8;
welchen Wert hat i, nachdem diese beiden Anweisungen durchgelaufen sind?
Überlebt irgendein Bit von i = 5 die Zuweisung von 8? Wohl eher nicht.
Nach
ADMUX = usimux; // Kanal waehlen[/c]
sind alle anderen Bits die du vorher so mühsam in der init Funktion in
ADMUX gesetzt hast, wieder auf 0. Und damit ist die Einstellung für die
Referenzspannung, die ebenfalls über ADMUX gemacht wird, futsch bzw.
eine andere als du bei einem Blick auf die init Funktion denkst.
>
1
ADCSRA|=0x80;//ADC aktivieren (1)
>> Damit wird der ADU in jedem Durschlauf wieder aktiviert!
mein Fehler.
Hab den Code nur nach ADEN abgesucht und nicht gefunden.
SChreib das doch bitte als
ADCSRA |= ( 1 << ADEN );
so wie du das beim Ausschalten auch machst. Dann übersieht man das nicht
so leicht.
> Trotzdem geht er nicht in den 2. Zweig, obwohl 2,5V etwa 127 ergeben> sollte.
Sollte!
Hast du das kontrolliert?
Wechen Wert liefert der ADC?
> Ich verwende das LCD sehr wohl! :D
Das war auch mehr als Hinweis gedacht, was du tun kannst, wenn du nicht
verstehst, warum ein if nicht funktioniert oder eine Berechnung nicht ds
erwartete Ergebnis liefert.
Viele Programmierer haben aus irgendeinem nicht verständlichen Grund
Angst davor, sich Zwischenergebnisse ausgeben zu lassen. Dabei würde ein
Blick auf ein paar Variablen sofort Licht ins Dunkel bringen. Aber aus
irgendeinem Grund schrecken sie davor zurück kurzzeitig ein paar printf
(bei dir eben Ausgaben aufs LCD) einzubauen, die danach wieder entfernt
werden. Es scheint fast so, dass sie lieber im Nebel stochern als die 15
Sekunden Zusatzarbeit zu machen.
JTR schrieb:
> Karl heinz Buchegger schrieb:>> int igetADU_8Bit(unsigned short int usimux)>
1
{intiresult;
2
>ADMUX=usimux;// Kanal waehlen
>>>>>> Tja. Damit ist dann die Einstellung der Referenzspannung hinfällig>> geworden.>> Also was du damit meinst ist mir nicht klar?!
schau dir doch in deinem Code mal an, wie du die Ref auswählst...
> Damit wird der ADU in jedem Durschlauf wieder aktiviert!
und das ist einer der Gründe, warum man sowas
> ADCSRA |= 0x80;
nicht macht!
JTR schrieb:
> Für was Initialisier ich den ADU denn überhaupt?> Ich muss doch nicht jedes mal meine ref. Spannung einstellen.
Genau darum geht es im Grunde ja :-)
Mittels
ADMUX = usimux
stellst du eine neue Referenzspannung ein!
Unabsichtlich! Ich bin sicher du woltest das gar nicht. Aber du tust es!
Du setzt alle Bits, die die Referenzspannung einstellen auf 0!
>>>und das ist einer der Gründe, warum man sowas>> ADCSRA |= 0x80;>>nicht macht!>> Was nicht macht?> Du redest ihn Rätseln....
vergleiche
1
ADSCRA|=0x80;
2
3
...
4
5
ADCSRA&=~(1<<ADEN);
mit
1
ADCSRA|=(1<<ADEN);
2
3
...
4
5
ADCSRA&=~(1<<ADEN);
bei welcher Version sieht auch ein Blinder, dass die eine Operation die
Umkehrung der anderen ist?