mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik PIC18F1320 Analogeingang


Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: bingo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> ADCON0bits.ADON=0;    //ADC ist deaktiviert

Autor: ich (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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???

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: ich (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
int test;
...
...
ADCON0bits.GO=1;
test=0;
while(test==0){
  if(ADCON0bits.GO==0)
  {
    PORTBbits.RB5=1;
    ADWERT=ADRESH;
    ADWERT=ADWERT<<8;
    ADWERT=ADWERT+ADRESL;
    test = 1;
  }
}
...

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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.