Forum: Mikrocontroller und Digitale Elektronik PIC18F66 ADC per Hand auslesen


von Stefan S. (humus)


Lesenswert?

Hallo Zusammen,

kann mir jemand sagen was ich beim Auslesen des ADC von meinem 
PIC18F66K80  falsch mache? Ich verwende MicroC Pro als Compiler. Wenn 
ich die integrierte Lib einsetze, funktioniert es einwandfrei, ich 
möchte aber wissen was passiert und deswegen alles per Hand 
programmieren. Hier mein C-Code:
1
for (i=0; i<13; i++)
2
{
3
adc_rd = 0;
4
PORTB =pin_mux[i];
5
6
ADCON0.ADON = 1;        //Wake up ADC
7
    ADCON0.CHS0=0;
8
    ADCON0.CHS1=0;
9
    ADCON0.CHS2=0;
10
    ADCON0.CHS3=0;
11
    ADCON0.CHS4=0;
12
13
    ADCON0.GO = 1;          //start 12b ADC conversion
14
    while(ADCON0.NOT_DONE); //wait until ADC finished
15
16
    adc_rd=ADRESH;              //12b ADC result value
17
    adc_rd=adc_rd<<8;           //bitwweises verschieben nach links
18
    adc_rd=adc_rd+ADRESL;       //12b ADC result value
19
ADCON0.ADON = 0;        //set ADC conversion module off
20
                    
21
    sprintf(lcd_line[0], "AN0 = %u", adc_rd);                                                                                                                        //The pec_error variable is simply set negative if any PEC errors
22
    Lcd_Out(1,1, lcd_line[0]);
23
    
24
ADCON0.ADON = 1;        //Wake up ADC
25
adc_rd = 0;
26
    ADCON0.CHS0=1;
27
    ADCON0.CHS1=0;
28
    ADCON0.CHS2=0;
29
    ADCON0.CHS3=0;
30
    ADCON0.CHS4=0;
31
32
    ADCON0.GO = 1;          //start 12b ADC conversion
33
    while(ADCON0.NOT_DONE); //wait until ADC finished
34
35
    adc_rd=ADRESH;              //12b ADC result value
36
    adc_rd=adc_rd<<8;           //bitwweises verschieben nach links
37
    adc_rd=adc_rd+ADRESL;       //12b ADC result value
38
ADCON0.ADON = 0;        //set ADC conversion module off
39
 
40
    sprintf(lcd_line[1], "AN1 = %u", adc_rd);                                                                                                                        //The pec_error variable is simply set negative if any PEC errors
41
    Lcd_Out(2,1, lcd_line[1]);
42
    
43
    sprintf(lcd_line[2], "MUX = %X", pin_mux[i]);                                                                                                                        //The pec_error variable is simply set negative if any PEC errors
44
    Lcd_Out(3,1, lcd_line[2]);
45
    Delay_ms(1000);
46
}

Anstatt von Werten zwischen 0 und 40954 bekomme ich Werte um die 65000 
auf meine LCD angezeigt.

Vielen Dank

von adc_rd (Gast)


Lesenswert?

adc_rd nicht in String umgewandelt.

von Volker S. (vloki)


Lesenswert?

Stefan S. schrieb:
> Anstatt von Werten zwischen 0 und 40954 bekomme ich Werte um die 65000
> auf meine LCD angezeigt.

Wird irgendwo das Format (Right/Left justified) eingestellt?
Wenn nicht, dann ist die Voreinstellung Left justified!

Den ADC sollte man auch nicht ständig ein und ausschalten.
Den stellt man einmal in der Initialisierung ein und danach schaltet man 
meist nur noch die Kanäle um und startet neue Messungen...

Probier mal ob der Compiler nicht auch das kann:
    ADCON0.CHS = 0; // 1, 2, 3 oder ...
    adc_rd = ADRES; // ohne H/L

von Stefan S. (humus)


Lesenswert?

adc_rd schrieb:
> adc_rd nicht in String umgewandelt.

adc_rd ist als unsigned int definiert. Das Display kann doch nur String, 
oder irre ich mich?

Volker S. schrieb:
> Wird irgendwo das Format (Right/Left justified) eingestellt?
> Wenn nicht, dann ist die Voreinstellung Left justified!
Verstehe nicht was du meinst?

> Den ADC sollte man auch nicht ständig ein und ausschalten.
> Den stellt man einmal in der Initialisierung ein und danach schaltet man
> meist nur noch die Kanäle um und startet neue Messungen...
Bringt keine Veränderung.


> Probier mal ob der Compiler nicht auch das kann:
>     ADCON0.CHS = 0; // 1, 2, 3 oder ...
>     adc_rd = ADRES; // ohne H/L
ADRESH/ADRESL ist im Datenblatt mit jeweils 8 bit angegeben.

von Witkatz :. (wit)


Lesenswert?

Stefan S. schrieb:
>> Wenn nicht, dann ist die Voreinstellung Left justified!
> Verstehe nicht was du meinst?

s. Datenblatt Kap. "23.2.2 A/D RESULT REGISTERS" erklärt die 
Wertedarstellung sehr anschaulich, sogar mit Bild
http://ww1.microchip.com/downloads/en/DeviceDoc/39977f.pdf#G20.1060972

von Torben K. (tokuhila)


Lesenswert?

Um meinen Vorredner zu ergänzen:

a) ist ADRES ein 16bit signed
b) ADCON2.ADFM ist default 0, d.h. left justified
c) Hat der A/D-Wandler im K80 einen Schuss, siehe Errata Item 1

von Volker S. (vloki)


Lesenswert?

Stefan S. schrieb:
>> Probier mal ob der Compiler nicht auch das kann:
>>     ADCON0.CHS = 0; // 1, 2, 3 oder ...
>>     adc_rd = ADRES; // ohne H/L
> ADRESH/ADRESL ist im Datenblatt mit jeweils 8 bit angegeben.

Wenn für den Compiler irgendwo definiert ist, dass ADRES ein 16 unsigned 
ist und die gleiche Adresse hat wie ADRESL, dann passt das automatisch. 
(beim xc8 und C18 Compiler ist das so)

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