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
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?
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
Hallo, das Ergebnis immer noch gleich. Ich habe auch mal VRef- auf VSS und VRef+ auf VDD geschalten, auch keine Änderung. MfG
Hallo, Problem hat sich geklärt, Lösung ist im Anhang. Danke Dominic, das Du wenigstens mal kurz Zeit hattest. MfG Uhrenbastler.
Ach ich habe den Thread gar nicht mehr gesehen. Wo war den das Problem?
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
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
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.
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.
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?
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
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.
Es gibt da schon einen kleinen Unterschied: der Datentyp für ADRES ist unsigned short, was ein 16 Bit unsigned ist.
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
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.