Forum: Mikrocontroller und Digitale Elektronik Fehlerhafte Werte bei AD-Wandlung PIC18F2420


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Mike R. (uhrenbastler)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo an Alle und ein "Gesundes Neues Jahr" ,

eigentlich funktioniert die AD-Wandlung ganz gut, nur die Auswertung ist 
nicht so, wie sie sein soll. Während der Messung (0-5V) werden nur Werte 
bis 256 geschrieben und dann geht es wieder von vorn los.

ca.5V = 256, dann bei ca. 3,75V = 0
kleiner 3,75V = 256, dann bei ca. 2,5V = 0
kleiner 2,5V = 256, dann bei ca. 1,25V = 0
kleiner 1,25V = 256, dann bei 0V = 0

Im C-File ist die Pinbelegung und Alles weitere ersichtlich.
Woran kann das liegen? Danke für Eure Tips, ich habe so viel probiert, 
jetzt brauche ich mal Hilfe.

MfG, Uhrenbastler

von Dominic A. (neo123)


Bewertung
0 lesenswert
nicht lesenswert
Ich habe nur kurz über den Code geschaut. In der Main verwendest du bei 
den If Abfragen den & Operator. Ich denke aber du wolltest den && also 
das logische UND benutzen. Gibt da der Compiler keine Warnungen?

von Mike R. (uhrenbastler)


Bewertung
0 lesenswert
nicht lesenswert
Hallo Dominic,

Danke für die schnelle Antwort, keine Fehlermeldung, benutze MPLAB V8.92 
und C18 V3.40. Ich werde mal mit logisch UND (&&) testen. Melde mich 
dann wieder.

MfG

von Mike R. (uhrenbastler)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,

das Ergebnis immer noch gleich. Ich habe auch mal VRef- auf VSS und 
VRef+ auf VDD geschalten, auch keine Änderung.

MfG

von Mike R. (uhrenbastler)


Bewertung
0 lesenswert
nicht lesenswert
Bin dann mal bis morgen offline. MfG

von Mike R. (uhrenbastler)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Problem hat sich geklärt, Lösung ist im Anhang. Danke Dominic, das Du 
wenigstens mal kurz Zeit hattest.

MfG Uhrenbastler.

von Dominic A. (neo123)


Bewertung
0 lesenswert
nicht lesenswert
Ach ich habe den Thread gar nicht mehr gesehen.
Wo war den das Problem?

von Horst (Gast)


Bewertung
0 lesenswert
nicht lesenswert
So einen Quelltext kann doch keiner lesen. Freut mich, dass es nun 
klappt, aber für die Zukunft besser anders formatieren, dann guckt man 
es sich auch an.

Gute N8, Horst

von Mike R. (uhrenbastler)


Bewertung
0 lesenswert
nicht lesenswert
Hallo Dominic, das Problem lag in dieser Zeile:

Ergebnis = (ADRESH<<8) + ADRESL ;

Während der Messung (0-5V) werden nur Werte in Ergebnis
bis 255 geschrieben und dann geht es wieder von vorn los.

ca.5V = 255, dann bei ca. 3,75V = 0
kleiner 3,75V = 255, dann bei ca. 2,5V = 0
kleiner 2,5V = 255, dann bei ca. 1,25V = 0
kleiner 1,25V = 255, dann bei 0V = 0

Das ist jetzt die funktionierende Lösung:

for(i=0;i<16;i++) // Schleife wird 16x durchlaufen

{
ConvertADC();  // Startet eine Analog Digital Umsetzung
while(BusyADC());// Ueberprueft ob gerade eine AD Umsetzung statt findet
Ergebnis += (unsigned int) ReadADC(); // Messung in ERGEBNIS addieren
}
Ergebnis /= 16;    // ERGEBNIS/16 dividieren


Hallo Horst,
wie sieht denn ein gut geschriebener Quelltext aus? Während der 
Umschulung haben wir in Assembler geschrieben und diese tabellarische 
Struktur habe ich so beibehalten. In "C" schreiben habe ich mir mit 
Hilfe eines Buches und "Google" selber beigebracht. Oder ist es manchmal 
auch nur Geschmackssache?

Danke der Nachfrage und auch der Kritik, wenn es etwas zu verbessern 
gibt, bin ich dabei.

Mfg Mike

von Dominic A. (neo123)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,
Es könnte sein das der Fehler daher kommt das die ADRESH und ADRESL 
1Byte grosse Register sind. Wenn du nun ADRESH um 8 nach rechts 
schiebst, schiebst du alle Werte aus dem Register raus.
Eventuelle könnte es so funktionieren:
Ergebnis = ((int)ADRESH<<8) + ADRESL);
Im Moment ermittelst du ja einfach den Mittelwert von 16 Werten.

von Mike R. (uhrenbastler)


Bewertung
0 lesenswert
nicht lesenswert
Hallo Dominic,

habe es so getestet: Ergebnis = (((int)ADRESH<<8) + ADRESL);
und es funktioniert prima. Danke für den Tip.

Könnte ich, theoretisch, den Wert einer Variablen (von 0xC8 = 200 bis 
3E8 = 1000) gleich in eine Angabe in Volt umrechnen lassen?
z.B.: 0x1C2(450) = 2,81V ---> Ergebnis = `D281`

Gruß Mike.

von Dominic A. (neo123)


Bewertung
0 lesenswert
nicht lesenswert
Ja stimmt da hatte ich eine Klammer vergessen.
Ich verstehe nicht ganz was du meinst? Die Formel für die Umrechnung 
hast du ja schon im letzten von dir geposteten Code auskommentiert drin.
Oder geht es darum den Bereich für die 0-5V anzupassen?

von Michael H. (morph1)


Bewertung
0 lesenswert
nicht lesenswert
das ginge auch deutlich einfacher:
1
Ergebnis = ADRES;

dann braucht man da nicht soviel nachdenken ;) auch wenn das eventuell 
ganz gut war fürs zukünftige verständnis

von Dominic A. (neo123)


Bewertung
0 lesenswert
nicht lesenswert
Hmm sicher das das geht? Ein kurzer Ausschnitt aus dem Header eines 
PIC16F1825:
1
// Register: ADRES
2
extern volatile unsigned short          ADRES               @ 0x09B;
3
#ifndef _LIB_BUILD
4
asm("ADRES equ 09Bh");
5
#endif
6
7
// Register: ADRESL
8
extern volatile unsigned char           ADRESL              @ 0x09B;
9
#ifndef _LIB_BUILD
10
asm("ADRESL equ 09Bh");
11
#endif
12
13
// Register: ADRESH
14
extern volatile unsigned char           ADRESH              @ 0x09C;
15
#ifndef _LIB_BUILD
16
asm("ADRESH equ 09Ch");
17
#endif

Da sieht es so aus als ob ADRES nur ADRESL ist. Somit hat man dann nur 
das L Byte und steht wieder am Anfang des Problems.

von Ulrich (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Es gibt da schon einen kleinen Unterschied: der Datentyp für ADRES ist 
unsigned short, was ein 16 Bit unsigned ist.

von Mike R. (uhrenbastler)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Dominic A. schrieb:
> Die Formel für die Umrechnung
> hast du ja schon im letzten von dir geposteten Code auskommentiert drin.
> Oder geht es darum den Bereich für die 0-5V anzupassen?

Genau das ist es. Das Auskommentierte ist aber für die Anzeige auf einem 
LCD-Display, wird mir so bestimmt nichts nützen. Ich brauche 
umgerechnete Werte aus "ADRES" um sie auf den 7-Segmentanzeigen anzeigen 
zu können.

0000 = 0,00V --> Ergebnis = 000 (Seg1 - Seg2 - Seg3)
.
.
0200 = 0,69V --> Ergebnis = 069 (Seg1 - Seg2 - Seg3)
.
.
0595 = 2,50V --> Ergebnis = 250 (Seg1 - Seg2 - Seg3)
.
.
1023 = 5,00V --> Ergebnis = 500 (Seg1 - Seg2 - Seg3)

(Die Werte sind Beispiele, wie ich sich sie auf meiner Leiterplatte 
nachgeprüft habe)

Momentan habe ich mehrere Bitmuster vorgegeben (<--das soll weg) und 
frage in der Endlosschleife ab, ob es eine Übereinstimmung gibt und 
lasse sie mir anzeigen (siehe Anhang).

Wenn da was möglich ist, wäre ganz gut, sonst muss ich es halt so 
lassen. Für meine erste AD-Wandlung bin ich schon mal ganz zufrieden, 
die Feinheiten kommen dann eben später.

Gruß Mike

: Bearbeitet durch User

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.