Problem mit ADC mit PIC12F675
Freitag, 18. Mai 2012
 
 

PIC Mikrocontroller Forum  |  PIC Mikrocontroller  |  Programmiersprache Assembler  |  AD-Wandler (Assembler)  |  Problem mit ADC mit PIC12F675 « vorheriges nächstes »
Seiten: [1] Nach unten Drucken
Autor Thema: Problem mit ADC mit PIC12F675  (Gelesen 5456 mal)
 
bionicdragon

Offline Offline

Beiträge: 0


Profil anzeigen
« am: August 16, 2005, 06:59:15 »

Hallo zusammen,

folgendes Problem.
Habe eine Schaltung aufgebaut, in dem ich einen Lüfter in Abhängigkeit der Temperatur steuern will. Die Steuerung brauch nicht genau zu sein und da ich noch relativ ein Anfänger bin, habe ich das ganz einfach aufgebaut.

Code:
list p=12f675
#include <P12f675.INC>

ERRORLEVEL -302

__CONFIG _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT


wait1 Equ 0x20
wait2 Equ 0x21
check Equ 0x22

org 0x00
goto Init

org 0x04

Init

clrf GPIO
bsf STATUS, RP0
movlw B'00010000'
movwf TRISIO
bcf STATUS, RP0

bsf ADCON0,0 ;ADC einschalten

bsf ADCON0,2 ;ADC Eingang auf
bsf ADCON0,3 ;AN3 einstellen

bsf STATUS, RP0
bsf ANSEL,6 ;ADC Geschwindigkeit
bcf ANSEL,5
bcf ANSEL,4 ;1,25-5 MHz einstellen
bcf STATUS, RP0

bcf ADCON0,7 ;ADC Ergebnis linksbündig einstellen



main
call wait

bsf ADCON0,1 ;ADC starten
loop
btfsc ADCON0,1
goto loop

bsf GPIO,5
...
end
[/list][/code]

zum Test habe ich mal

bsf   GPIO,5 vor der Schleife eingesetzt, und der Lüfter läuft.
wenn ich aber so wie im Code laufen lasse, dann funktioniert er nicht, d.h. er müsste in der Schleife hängen.

Erkennt jemand von euch den Fehler? Ich glaube es müsste an der ADC Einstellung liegen, finde aber keinen Fehler.

Vielen Dank schonmal.
Gespeichert
Bernd
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 3815



Profil anzeigen
« Antworten #1 am: August 16, 2005, 18:42:46 »

In Deinem Programm kann ich im Moment keinen Fehler entdecken. Sobald der A/D-Wandler eingeschaltet wird, funktioniert das GO/DONE Bit, unabhängig von der restlichen Konfiguration (dann ist höchstens das Ergebnis der Wandlung falsch).

Du kannst noch mal versuchen, anstelle des GO/DONE Bits das ADIF Bit abzufragen (PIR1,6).

Den Komparator solltest Du ausschalten, wenn Du ihn nicht benötigst (Register CMCON). Außerdem sollten als digitale Ein-/Ausgänge benutzte Pins im ANSEL-Register entsprechend eingestellt werden. Das hat aber mit dem eigentlichen Problem nichts zu tun.

Noch ein Hinweis: Du machst es anderen (und auch Dir) einfacher, wenn Du statt der Bitnummer die Bezeichnung des Bits aus der .inc-Datei verwendest, also z.B.
Code:
bcf ADCON0, ADFM

statt
Code:
bcf ADCON0, 7



Viele Grüße

Bernd
Gespeichert

bionicdragon

Offline Offline

Beiträge: 0


Profil anzeigen
« Antworten #2 am: August 17, 2005, 14:00:00 »

Danke Bernd,

das mit der Bitbezeichnung werde ich zukünftig berücksichtigen, mir wäre das persönlich eigentlich egal, hatte mich da immer nach Sprut gerichtet.

Mit meinem Problem bin ich schon ein bisschen weiter gekommen. Es lag wahrscheinlich am PIC selbst. (Oder am brennen).

Was noch nicht funktioniert und was ich nicht verstehe ist

Code:
step1
movfw ADRESH ;oberes Bit auslesen
movwf check
movlw D'131'
subwf check,1
decfsz check
goto step2
bsf GPIO,0
bcf GPIO,2
bcf GPIO,1
bcf GPIO,5
goto main


ich habe mal die Spannung an AN3 gemessen, die liegt, je nach Temperatur zwischen 2,6 und 2,0 (je höher die Temperatur desto niedriger)

Habe mir auch eine Tabelle erstellt, wo ich die Werte enziffere. Bei Raumtemperatur funktioniert der Wert '131' doch andere Zahlen z.B. '130' oder '132' funktionieren nicht. Wobei doch die Spannungsdifferenz bei 0,014V pro 1 wäre???
Naja, ich glaube bei diesem Problem bin ich auf mich alleine gestellt.

Aber Danke nochmal.[/code]
Gespeichert
Bernd
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 3815



Profil anzeigen
« Antworten #3 am: August 17, 2005, 17:31:06 »

Code:
     bsf      GPIO,0
      bcf      GPIO,2
      bcf      GPIO,1      
      bcf      GPIO,5

Unbenutzte Eingänge des A/D-Wandlers und das Komparator Modul hast Du jetzt wohl ausgeschaltet, ansonsten wäre nach Abarbeitung des obigen Codes GPIO0 "0" ("analog" konfigurierte Pins werden immer als "0" ausgelesen, bcf/bsf liest den gesamten Port, verändert ein Bit und schreibt dann den kompletten Port zurück).

Zitat
Bei Raumtemperatur funktioniert der Wert '131' doch andere Zahlen z.B. '130' oder '132' funktionieren nicht. Wobei doch die Spannungsdifferenz bei 0,014V pro 1 wäre???

Da Du mit 8 Bit Auflösung arbeitest, hättest Du bei 5V eine Auflösung von 5V/256 = 19,53mV. Ob das eine große oder kleine Spannungsdifferenz in Bezug auf den Meßwert ist, kann man erst einschätzen, wenn man die Spannungsänderung des Temperatursensors pro Kelvin (oder auch °C) kennt (d.h. wie groß ist die nötige Temperaturänderung für 19,53mV Spannungsänderung).

Der A/D-Wandler besitzt ja eine Auflösung von 10 Bit, d.h. jeder gemessene Wert im Bereich von 524 bis 527 entspricht einem Ergebnis von 131 im Register ADRESH. Bei relativ "sauberen" Umgebungsbedingungen wird bei der Messung einer Gleichspannung eine Reproduzierbarkeit von +/- 2 LSB leicht erreicht.


Viele Grüße

Bernd
Gespeichert

bionicdragon

Offline Offline

Beiträge: 0


Profil anzeigen
« Antworten #4 am: August 18, 2005, 07:06:19 »

Danke nochmal Bernd für deinen Beitrag.

Also ich will eigentlich nur eine einfachste Temperatursteuerung mit 6 Stufen. Die Genauigkeit spielt bei mir keine Rolle. Er sollte die 6 Stufen in einem Temperaturbereich von ca.35-60°C schalten. (Schalte 2 zusammen, deshalb 6 Stufen, sind ja nur 4 restliche Ausgänge)

An GPIO 4 (AN3) habe ich einen Temperatursensor. Die anderen Ausgänge will ich als Ausgänge benutzen, die je einen Transistor durchschalten. Diese schalten jeweils einen Widerstand zum Lüfter.

Bei der Auflösung hattest Du natürlich recht. sind nicht 0,014V sondern 0,019V, aber trotzdem müsste dann doch bei einer gemessenen Spannungsdifferenz von ca. 0,6 V ca. 40x sich der Wert ändern.

Was ist +/-2 LSB?

Zitat
Unbenutzte Eingänge des A/D-Wandlers und das Komparator Modul hast Du jetzt wohl ausgeschaltet, ansonsten wäre nach Abarbeitung des obigen Codes GPIO0 "0" ("analog" konfigurierte Pins werden immer als "0" ausgelesen, bcf/bsf liest den gesamten Port, verändert ein Bit und schreibt dann den kompletten Port zurück).

Tut mir leid, aber diese Aussage verstehe ich nicht. Ich habe auf alle Fälle jeden Ausgang einzeln ausprobiert, und Sie funktionieren. Hab es mal geschafft, dass er sich ein- und wieder ausschaltet, aber halt nich die 6 Stufen durch. Und auch nur 1x.

Ich weiß jetzt auch wo das "alte" Problem lag. Bitte nicht lachen, aber ich habe bei meinem Testsockel fürs Bennen den MCLR-Pin nicht angelötet. Es hatte ja immerhin schon bei ca. 10 Programmierungen funktioniert, aber halt dieses mal nicht. (Habe bisher nur einfache Sachen gemacht)  ](*,)

Ich will jetzt versuchen mir ein kleines 8-Bit Lesegerät zu basteln, wo ich dann die Werte auslesen will. Ich Probier halt mal rum, vielleicht bekomme ich es ja hin.
Ich melde mich wieder, bevor ich mich in die Luft gehe. :-)
Gespeichert
Bernd
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 3815



Profil anzeigen
« Antworten #5 am: August 18, 2005, 17:35:47 »

Zitat
Was ist +/-2 LSB?

LSB = Least Significant Bit (niedrigstwertiges Bit). Das bedeutet nichts anderes, als daß der vom A/D-Wandler gelieferte Wert um +/-2 vom erwarteten Ergebnis abweicht und in diesem Bereich schwankt (beim Anlegen einer stabilen, konstanten Spannung). Genauigkeitangaben für A/D-Wandler werden immer in der "Einheit" LSB angegeben, da die Größe des LSBs von der verwendeten Referenzspannung abhängig ist.

Zitat
Tut mir leid, aber diese Aussage verstehe ich nicht. Ich habe auf alle Fälle jeden Ausgang einzeln ausprobiert, und Sie funktionieren. Hab es mal geschafft, dass er sich ein- und wieder ausschaltet, aber halt nich die 6 Stufen durch. Und auch nur 1x.

Schau dir mal diesen Thread an. Das read-modify-write Problem habe ich hier beschrieben, wenn auch im Zusammenhang mit einer Belastung von Portpins. Jeder Pin, der für seine analoge Funktion konfiguriert ist (egal ob als Eingang oder als Ausgang), wird als "0" ausgelesen. Jetzt verständlicher?

In Deinem Code muß in jedem Fall folgendes stehen:
Code:
 movlw   0x07  
  movwf   CMCON0       ; Komparator ausschalten

  bsf     STATUS, RP0
  movlw   0x48         ; ADCS<2:0> = 100, ANS<3:0> = 1000, nur AN3 ist "analog"
  movwf   ANSEL      
  bcf     STATUS, RP0

Ansonsten funktioniert zwar eine Änderung des Portpins über bsf/bcf, bei der Änderung eines anderen Portpins wird der zuvor geänderte Pin aber immer "0".


Viele Grüße

Bernd
Gespeichert

bionicdragon

Offline Offline

Beiträge: 0


Profil anzeigen
« Antworten #6 am: August 20, 2005, 14:41:17 »

ich bin vorerst Happy,

meine Lüftersteuerung funktioniert zwar noch nicht, da ich Deine Tipps noch nicht eingepflegt habe, habe aber, wie geschrieben, das Bit-lesegerät gebastelt, und ich habe die selben Werte aus ADRESH ausgelesen, die ich auch über meine Tabelle ermittelt hatte. (Hatte lang genug gedauert, ich hatte diese Woche Urlaub und habe rund um die Uhr daran gesessen. :supz: )

Ich werde nun deine Tipps ins Programm mit aufnehmen und noch etwas rumprobieren. Kann aber noch 1-2 Wochen dauern, bis ich wieder schreibe.

Ich schreib aber auf alle Fälle, wenn ich das geschafft habe, oder ich noch ein paar Probleme habe.
Gespeichert
bionicdragon

Offline Offline

Beiträge: 0


Profil anzeigen
« Antworten #7 am: August 21, 2005, 15:23:32 »

hätte es nicht mehr geglaubt, dass ich es so schnell noch hinbekomme, habe es aber endlich geschafft.

Läuft so, wie ich es mir vorgestellt hatte.

Vielen Dank nochmal.

PS: Das read-modify-write Problem habe ich nun verstanden. Und es so geschrieben, wie Du vorgeschlagen hattest.

Wieso schreibt Ihr eigentlich immer mit Binärcode, ist Hexadezimal oder Dezimal nicht einfacher?

Zitat
 movlw   0x07    
  movwf   CMCON0       ; Komparator ausschalten

  bsf     STATUS, RP0
  movlw   0x48         ; ADCS<2:0> = 100, ANS<3:0> = 1000, nur AN3 ist "analog"
  movwf   ANSEL      
  bcf     STATUS, RP0


Ich habe das mit Hexadezimal geschrieben, tu ich mich leichter.
Gespeichert
Bernd
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 3815



Profil anzeigen
« Antworten #8 am: August 22, 2005, 18:24:50 »

Zitat
Wieso schreibt Ihr eigentlich immer mit Binärcode, ist Hexadezimal oder Dezimal nicht einfacher?

Ich habe doch den Großteil in Hexadezimal-Darstellung geschrieben. Für drei Bits (ADCS), die sich irgendwo im Register befinden, ist die Hex-Darstellung nicht sonderlich hilfreich. In Deinem Zitat ist es ein Zufall, daß ADCS<2:0> und ANS<3:0> gerade den beiden Nibbles (untere und obere vier Bit) des Bytes entsprechen.

Was würdest Du zum Beispiel für CHS<1:0> im Register ADCON0 schreiben?
Code:
10   // binär
0x2  // hex
0x8  // hex unter Berücksichtigung der Wertigkeit der Bits

Die dritte Möglichkeit ist falsch, da zwei Bits nie den Wert 0x08 annehmen können.

Die Umwandlung von binär in hex und umgekehrt kann man problemlos im Kopf erledigen, da man lediglich die Binärdarstellung von 0x0 bis 0xF kennen muß:
Code:

0b01011010

0101 = 0x05     1010=0xA

--> 0b01011010 = 0x5A

Generell ist es doch so, daß man anhand des Datenblatts den nötigen Registerwert in Binärform vorliegen hat. Ob man diesen so übernimmt oder als Hex-Wert darstellt (man muß weniger tippen) ist letztendlich Geschmackssache. Die Dezimaldarstellung ist für die Arbeit mit Registern denkbar ungeeignet.


Viele Grüße

Bernd
Gespeichert

bionicdragon

Offline Offline

Beiträge: 0


Profil anzeigen
« Antworten #9 am: August 22, 2005, 20:46:39 »

sorry Bernd,

ich meinte: Wieso schreibt Ihr eigentlich immer mit Hexadezimal, ist  Binärcodeoder Dezimal nicht einfacher?

Ich schreibe gewöhnlich mit Binärcode.

Zitat
Was würdest Du zum Beispiel für CHS<1:0> im Register ADCON0 schreiben?


Ich würde schreiben B'00001000'

Ja, Dezimal ist ungeeignet. Geb ich Dir recht. Aber mit Hexadezimal tu ich mich auch schwer. Wie Du bestimmt schon gemerkt hast, hatte ich weder beruflich noch schulisch irgendetwas mit Elektronik und Elektrik zu tun. Mache halt noch sehr viele Leichtsinnsfehler. (Wie z.B. oben) Aber es wird schon besser.

Also wünsche Dir noch viel Spaß und nen schönen Abend (Nacht).

PS: Bist Du eigentlich der einzige, der hier hilft? Ist zwar etwas übertrieben, macht aber so den Eindruck.
Gespeichert
Bernd
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 3815



Profil anzeigen
« Antworten #10 am: August 23, 2005, 18:19:07 »

Zitat
Zitat
Was würdest Du zum Beispiel für CHS<1:0> im Register ADCON0 schreiben?

Ich würde schreiben B'00001000'

Die Frage resultierte noch aus dem Mißverständnis, daß Du das hexadezimale Format bevorzugst. Wenn ich schreibe "setze CHS<1:0> auf 10", dann bedeutet das:
Code:
ADCON0 = uuuu10uu

Das "u" steht für gegenüber der Ausgangskonfiguration nicht zu verändernden Bits ("unchanged").

Ein Grund für die Verwendung von Hex ist für mich, daß ich
Code:
0x39

schneller tippen kann als
Code:
B'00111001' ; MPASM

Außerdem ist die Fehlerwahrscheinlichkeit bei nur 2 Ziffern geringer als bei 8. Bei C kommt hinzu, daß "0x" als Kennzeichen von hexadezimalen Konstanten im Standard enthalten ist, d.h. alle C-Compiler (unabhängig vom Hersteller) unterstützen diese Schreibweise. Für die binäre Darstellung von Konstanten gibt es im ANSI-C Standard kein Prefix, d.h. die nötige Darstellung unterscheidet sich von Compiler zu Compiler (und kann auch überhaupt nicht unterstützt werden).

Wenn Du mit der Binär-Darstellung am besten arbeiten kannst, spricht überhaupt nichts dagegen, diese zu verwenden. Wie gesagt, die Wahl des Formats ist größtenteils Geschmackssache.

Zitat
PS: Bist Du eigentlich der einzige, der hier hilft? Ist zwar etwas übertrieben, macht aber so den Eindruck.

Wäre schon ganz schön, wenn noch mehr Nutzer Fragen beantworten würden. Im Moment steigt die Zahl der Forennutzer, die Fragen haben, deutlich stärker an, als die Zahl derer, die auch Antworten geben. Also Leute, antwortet ruhig öfter :yawinkle: .


Viele Grüße

Bernd
Gespeichert

Seiten: [1] Nach oben Drucken 
« vorheriges nächstes »
Gehe zu:  

Powered by MySQL Powered by PHP Made for Mozilla (Firefox) Made for Internet Explorer
Seite erstellt in 0.062 Sekunden mit 19 Zugriffen.
 
Top! Top!