Forum: Analoge Elektronik und Schaltungstechnik PIC18F1330 ADC Auswertung funktioniert nicht


von Dennis K. (anyone)


Lesenswert?

Hallo Community,

es mag eine dumme Frage sein, doch langsam verzweifle ich damit.
Ich habe einen PIC18F1330 und möchte einen Poti über RA0 einlesen. 
Hierzu habe ich ein 10kOhm Poti an +5V und GND angeschlossen. Zwischen 
Abgriff und ADC-Eingang sitzt dann noch ein 1kOhm Widerstand zur 
Strombegrenzung falls man das Poti auf VDD dreht. Das Ergebnis möchte 
ich linksbündig in ADRESH abholen. Der PIC wird mit einem 4MHz Quarz und 
einer Betriebsspannung von +5V betrieben.

Nun habe ich folgendes Problem:
Wenn ich mit MPLAB X und dem PICkit3 debugge um den Wert anzeigen zu 
lassen, dann kommt beim Einschalten 254 und dann fällt und bleibt der 
Wert auf 85 (Poti steht auf VDD -> VDD liegt an ADC an). Ich habe 
bereits verschiedene Einstellungen für Fosc und TAD versucht, aber es 
ändert sich nichts. An der Schaltung sollte es nicht liegen und ich bin 
mir sicher, dass es ein Softwarefehler ist.

Wäre super, wenn ihr mir helfen könntet!

Hier noch der Code:
1
#include <p18f1330.h>
2
#include <delays.h>
3
4
#pragma config OSC = XT
5
#pragma config PWRT = OFF
6
#pragma config WDT = OFF
7
#pragma config MCLRE = ON
8
9
// Variablen
10
unsigned int result;
11
12
void main(void) {
13
14
    TRISB = 0x00;
15
    TRISAbits.TRISA0 = 1;
16
    TRISAbits.TRISA1 = 1;
17
    INTCONbits.GIE = 0;         // Interupts ausgeschaltet
18
    CMCONbits.CMEN0 = 0;        // Comparator 0 off (an RA0)
19
20
    ADCON0 = 0b00000000;        // ADC off; CH0; Special Event Trigger off
21
    ADCON1 = 0b00000001;        // AN0; RA1; RA4; RA6; Referenz ist AVDD
22
    ADCON2 = 0b00101100;        // Fosc/4; 12 TAD; linksbündig
23
24
    while(1)
25
    {
26
        ADCON0bits.ADON = 1;    // Schalte ADC ein
27
            
28
        Delay10TCYx(10);                // Warte 2,5 us
29
30
        ADCON0bits.GO = 1;      // Starte Konvertierung
31
        while(ADCON0bits.DONE == 1);
32
        result = ADRESH;        // Kopiere Ergebnis in result
33
            
34
        if(result > 127)
35
        {
36
            LATBbits.LATB0 = 1;
37
        }
38
        else LATBbits.LATB0 = 0;
39
40
        Delay10TCYx(10);                // Warte 2,5 us
41
42
        ADCON0bits.ADON = 0;    // Schalte ADC aus
43
    }
44
    return;
45
}

Laut Datenblatt soll man wohl den ADC nach der Konvertierung wieder 
ausschalten, was mich allerdings etwas stutzig macht. Auf dem Demo Board 
des PICkit3 habe ich auch schon den ADC programmiert und da lief alles 
wunderbar. Ein Defekt des PIC kann ich ausschließen, da ich noch einen 
anderen 18F1330 getestet habe und dieser den selben Effekt hervorruft.

Vielen Dank für eure Hilfe!

Viele Grüße,
Dennis K.

von Erich (Gast)


Lesenswert?

http://www.microchip.com/forums/m223732.aspx

" ... but in later silicon the ADCON1 register was changed.
  You now need to enable the A/D channels with a 0 or select port 
functions with a 1. "


http://ww1.microchip.com/downloads/en/DeviceDoc/80352b.pdf

Immer die "Errata" lesen zum jeweiligen uC !

Gefunden mit GOOGLE:   "PIC18F1330" ADCON1 ADCON2 ADCON3 ADRESH


Gruss

von Dennis K. (anyone)


Lesenswert?

Hallo Erich,

danke für den Hinweis! Ich habe das sofort geändert, leider brachte es 
keine Besserung.

Gruß
Dennis K.

von Jens M. (Gast)


Lesenswert?

Dennis K. schrieb:
> danke für den Hinweis! Ich habe das sofort geändert, leider brachte es
> keine Besserung.

Hast du den C-Code aus dem Beitrag im Microchip Forum mal ausprobiert?

von Dennis K. (anyone)


Lesenswert?

Jens Martin schrieb:
>
> Hast du den C-Code aus dem Beitrag im Microchip Forum mal ausprobiert?

Guten morgen,

nein das habe ich noch nicht, aber ist eine gute Idee ;-)

von Dennis K. (anyone)


Lesenswert?

Ich habe jetzt auch die Variante des Codes aus dem Microchip Forum 
getestet und es hat sich leider nichts verändert.

Nun werde ich wohl einen anderen Controller kaufen und es damit mal 
probieren.

Vielen Dank für eure Hilfe!

von Dirk W. (Gast)


Lesenswert?

Der ADC legt sein 10-Bit-Ergebnis in zwei Bytes ab, ADRESH und ADRESL. 
In Deinem Programm wertest Du aber nur das High-Byte aus (ADRESH). Um 
das komplette ADC-Ergebnis zu bekommen, musst Du die Bytes z.B. mit

result = ((unsigned int)(ADRESH)<<8)+ADRESL;

zusammenfügen.

Noch ein Hinweis: Die Pins AVDD und AVSS hast Du entsprechend 
beschaltet?

Übrigens: Nach der Konvertierung brauchst Du den ADC nicht auszuschalten 
(es sei denn, Du willst ein paar µA Strom sparen).

von Dennis K. (anyone)


Lesenswert?

Dirk W. schrieb:
> Der ADC legt sein 10-Bit-Ergebnis in zwei Bytes ab, ADRESH und ADRESL.
> In Deinem Programm wertest Du aber nur das High-Byte aus (ADRESH). Um
> das komplette ADC-Ergebnis zu bekommen, musst Du die Bytes z.B. mit
>
> result = ((unsigned int)(ADRESH)<<8)+ADRESL;
>
> zusammenfügen.
>
> Noch ein Hinweis: Die Pins AVDD und AVSS hast Du entsprechend
> beschaltet?
>
> Übrigens: Nach der Konvertierung brauchst Du den ADC nicht auszuschalten
> (es sei denn, Du willst ein paar µA Strom sparen).

Hallo Dirk,

das ich nur das ADRESH auswerte ist absicht, da die unteren beiden Bits 
im ADRESL meist nur ein Rauschen repräsentieren.

Auch AVDD und AVSS sind richtig angeschlossen.

Vor 10 Minuten habe ich es auch zum Laufen gebracht. Der Hinweis mit den 
geänderten Bits im ADCON1 war ein volltreffer, nur hatte ich noch einen 
Fehler in meiner Schaltung. Nachdem ich diesen behoben habe, 
funktioniert der ADC endlich.

Vielen Dank an alle für die schnelle, nette und kompetente Hilfe! :)

Viele Grüße,
Dennis K.

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
Noch kein Account? Hier anmelden.