Forum: Mikrocontroller und Digitale Elektronik PIC16F873A ADC Setup


von Peter A. (Gast)


Lesenswert?

Moin Moin,

kann mir eventuell jemand sagen wo mein Fehler liegt ich bekomme keinen 
Wert in den ADC (AN1) eingelesen. Verwendet wird ein "PIC16F873A" mit 
externem 4MHz Quarz und als Vref. soll VDD/VSS dienen.
1
void SetupPORT_PINS(void){
2
   /*Definitionen, PORT Register (0 = AUSGANG / 1 = EINGANG) */  
3
    //PIN =   76543210      PORT Einstellungen
4
    TRISA = 0b11111111;     //PORT A
5
    TRISB = 0b00000001;     //PORT B
6
    TRISC = 0b00000000;     //PORT C
7
8
    /*PIN Definitionen*/
9
    #define InterruptPin RB0
10
    #define LED1 RB5
11
    // und so weiter
12
}
13
14
void Setup_ADC(void){
15
16
17
    ADCON0bits.ADCS0 = 1; 
18
    ADCON0bits.ADCS1 = 0;
19
20
    ADCON0bits.CHS0 = 1;
21
    ADCON0bits.CHS1 = 0;
22
    ADCON0bits.CHS2 = 0;
23
24
    ADCON1bits.PCFG = 0b00000000;
25
26
    ADCON0bits.ADON = 1;
27
}
28
29
int ADC_Read(){
30
31
  int l_Ergebniss;
32
33
  while (ADCON0bits.GO_nDONE);
34
  
35
  l_Ergebniss = (ADRESH<<8)+ADRESL;
36
37
  //l_Ergebniss = 500;
38
39
  return l_Ergebniss;
40
}

Die Funktion "SetupPORT_PINS" und "Setup_ADC" werden einmal beim start 
des Controllers aufgerufen. Die Funktion "ADC_Read" Wir in der main 
"While(1)" aufgerufen. Werte Werden auch richtig zurückgegeben aus der 
ADC_read aber im Register "ADRESH" und "ADRESL" ist nichts drin!

Danke für Eure Hilfe =)

von Max H. (hartl192)


Lesenswert?

Das ADCON0bits.GO_nDONE musst du auch mal auf '1' setzen um die Wandlung 
zu starten. Ein guter Zeitpunkt wäre am Anfang der ADC_Read().

von Peter A. (Gast)


Lesenswert?

1
int ADC_Read(){
2
3
  int l_Ergebniss;
4
5
  ADCON0bits.GO_nDONE = 1;
6
7
  while (ADCON0bits.GO_nDONE);
8
  
9
  l_Ergebniss = (ADRESH<<8)+ADRESL;
10
11
  //l_Ergebniss = 500;
12
13
  return l_Ergebniss;
14
}

hat leider nichts bewirkt! :(

Noch irgendwas falsch eingestellt?

Gruß

von Toxic (Gast)


Angehängte Dateien:

Lesenswert?

Peter A. schrieb:
> l_Ergebniss = (ADRESH<<8)+ADRESL;

Schau Dir deine Gleichung nochmal an.

von picalic (Gast)


Lesenswert?

Toxic schrieb:
>> l_Ergebniss = (ADRESH<<8)+ADRESL;
>
> Schau Dir deine Gleichung nochmal an.

Und? Welche Erkenntnisse sollte ihm das bringen?

von Toxic (Gast)


Lesenswert?

picalic schrieb:
> Und? Welche Erkenntnisse sollte ihm das bringen?

Also "+" in C ist gleich "|"  ?
Wusste ich nicht.

von Max H. (hartl192)


Lesenswert?

Toxic schrieb:
> Also "+" in C ist gleich "|"  ?
In diesem Fall ja, a << 8 füllt mit Nullen auf und 0 + b und 0 | b führt 
zum gleichen Ergebnis.

von Little B. (lil-b)


Lesenswert?

erster tipp: caste ADRESH auf ein uint16_t (oder ähnlich)

shiftest du einen uint8_t um 8 nach links, bleibt 0x00 übrig!

von Volker S. (vloki)


Lesenswert?

Peter A. schrieb:
> kann mir eventuell jemand sagen wo mein Fehler liegt ich bekomme keinen
> Wert in den ADC (AN1) eingelesen.

Heißt das jetzt es kommt immer Null oder der Wert stimmt nicht (ist zu 
klein) ?

Wegen dem "<<" Problem:
- Entweder vor dem shiften auf 16bit casten
- Ergebnis = ADRES; (könnte funktionieren wenn im Header angelegt)
- Ergebnis = ADRESH*256 + ADRESL; (sollte funktionieren)
- Ergebnis = *(short*(&ADRESL)); (???)

von Little B. (lil-b)


Lesenswert?

zweiter tipp: du taktest den ADC mit Fosc/8, Fosc darf dann nicht höher 
als 5MHz sein!

von Little B. (lil-b)


Lesenswert?

dritter tipp: warte die "Aquisition Time" ab! diese beträgt in der 
Beispielrechnung des Datenblattes knapp 20µs, die du vor dem 
"GO_nDONE=1" warten musst!

Passe diesen Zeitwert für deine Schaltung an und implementiere eine 
wait-funktion!

(datenblatt pic16f873a kapitel 11.1)

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.