Forum: Mikrocontroller und Digitale Elektronik PIC18F1320 Analogeingang


von Peter (Gast)


Lesenswert?

Hallo zusammen,
ich habe eine Programm, womit ich einfach einen analogen Wert einlesen 
möchte. Folgendes habe ich programmiert:

#include "p18f1320.h"
#include "delays.h"

#pragma config OSC=HS
#pragma config PWRT=ON
#pragma config BOR=OFF
#pragma config WDT=OFF
#pragma config LVP=OFF

#pragma code
void main(void)
{
int ADWERT;
ADWERT=0;
ADRESH=0;
ADRESL=0;
PORTA=0x00;
PORTB=0x00;

ADCON0bits.ADON=0;    //ADC ist deaktiviert
TRISAbits.TRISA0=1;    //AN0 ist als Eingang definiert
ADCON2=0x3C;      //Frequenz und Zeitverzögerung
ADCON2bits.ADFM=1;    //Rechtsbündig
ADCON0bits.VCFG0=0;    //Referenzspannung
ADCON0bits.VCFG1=0;    //Referenzspannung
ADCON0bits.CHS0=0;    //Kanalauswahl
ADCON0bits.CHS1=0;    //Kanalauswahl
ADCON0bits.CHS2=0;    //Kanalauswahl

ADCON0bits.ADON=1;    //ADC ist aktiviert

ADCON1bits.PCFG0=0;    //AN0 ist aktiviert

while(PORTAbits.RA4==1);

TRISBbits.TRISB5=0;

ADCON0bits.GO=1;
if(ADCON0bits.NOT_DONE==0)
{
PORTBbits.RB5=1;
ADWERT=ADRESH;
ADWERT=ADWERT<<8;
ADWERT=ADWERT+ADRESL;
}
}

Es funktioniert leider nur genau mit diesem Code. In die if-Schleife 
kommt er gar nicht erst rein.
Wenn ich eine Anweisung hinter die if-Abfrage stelle, ist das Register 
ADRESH und ADRESL leer. Genau das gleiche passiert, wenn ich das 
ADCON2-Register verändere.

Woran könnte das Problem liegen? Ich bitte um Hilfe.

Gruß
Peter

von bingo (Gast)


Lesenswert?

> ADCON0bits.ADON=0;    //ADC ist deaktiviert

von ich (Gast)


Lesenswert?

Peter schrieb:
> Es funktioniert leider nur genau mit diesem Code.

Verstehe ich das falsch?? Ich dachte der Code funktioniert eben nicht^^

Mal dumm gefragt. Hast du AVdd und AVss beschlatet?? Und du setzt PORTA 
als Ausgang und dann A0 als Eingang (für den AD-Wandler). Du prüfst in 
der While-Schleife aber A4 auf 1. Dieser ist doch aber noch Ausgang (der 
dazu beim Ausgang noch als Open-Drain fungiert). Also mach mal die While 
raus und probier nochmal. Wenn du da per Taster bestimmen willst, ob er 
Wandeln soll oder nicht, kannst du den ja noch als Eingang beschalten 
und prüfen.

von Peter (Gast)


Lesenswert?

AVdd und AVss sind direkt an der Versorgungsspannung angeschlossen.

PORTA setze ich nirgends als Ausgang. Die Zeile, wo A4 als Eingang 
deklariert wird habe ich tatsächlich vergessen.
Was ich nicht verstehe ist Folgendes:
Ich lese die Register im Debug-Betrieb im Watch-Fenster.
Wenn ich die if-Abfrage lösche, bleibt das Register ADRESL bzw. ADRESH 
leer. Genau das gleiche passiert, wenn ich hinter die if-Abfrage einen 
neuen Befehl setze. Wenn ich die if-Abfrage aber im Code habe, ohne 
folgende Befehle, funktioniert alles einwandfrei.
Da ist doch irgendetwas komisch, oder???

von Peter (Gast)


Lesenswert?

Nochmal einen Nachtrag:

Der Code springt nicht in die if-Schleife herein. D.h. das Bit NOT_DONE 
müsste noch auf High stehen. Nach vollendeter DA-Konvertierung müsste 
der DA-Wandler das Bit auf Low setzen.

von ich (Gast)


Lesenswert?

Was ist das denn für ein Compiler? Denn evtl. hat er NOT_DONE gleich 
Nicht-GO gesetzt. Also dass du evtl. NOT_DONE auf 1 prüfen müsstest. Zum 
testen könntest du ja fragen if(ADCON0bits.GO==0), denn es ist ja das 
gleiche Bit im gleichen Register.

Zudem wirst du, selbst wenn er wandelt, nicht ins if gehen. Denn du 
startest mit ADCON0bits.GO=1; den Wandelvorgang. Dann wandelt er, aber 
das dauert ja eine gewisse Zeit. Im nächsten Takt prüft er das bit aber 
schon, das aber immernoch auf 1 ist. Ansich, wenn du nur einmal wandeln 
willst und danach was anderes machen willst, müsste es so aussehen:
1
int test;
2
...
3
...
4
ADCON0bits.GO=1;
5
test=0;
6
while(test==0){
7
  if(ADCON0bits.GO==0)
8
  {
9
    PORTBbits.RB5=1;
10
    ADWERT=ADRESH;
11
    ADWERT=ADWERT<<8;
12
    ADWERT=ADWERT+ADRESL;
13
    test = 1;
14
  }
15
}
16
...

Steht auch im Datenblatt auf Seite 159 auf der Rechten Seite:
5. Wait for A/D conversion to complete, by either:
• Polling for the GO/DONE bit to be cleared
OR
• Waiting for the A/D interrupt

Polling ist halt eine While/For-Schleife, in der ein Bit/Byte die ganze 
Zeit geprüft wird.

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.