www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik PCF8591 ADC-Funktion


Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schönen Guten Abend.
Ich sitze nun schon seit 3 Wochen an meinem PCF8591. Aber nun habe ich 
den Punkt erreciht, wo ich nicht weiterkomme. Ich hoffe ihr könnt 
helfen.

Ich möchte ein einzelnen Poti auslesen. Dieser Wert soll vorläufig als 
Binärer Wert angezeigt werden (LED'S)

Die Schaltung ist fertig und definitiv funktionstüchtig. Wir haben da 
von der Schule so ne tolle Platine, wo wir verschiedene Device drauf 
ansprechen können.

Nur mit der Software hab ich ein Problem. Ich verstehe leider nicht, wie 
ich über den SDA-Pin sowohl inputs machen kann als auch outputs bekomme. 
Und ich bin mir unsicher, ob ich nun auch das Controlbyte schicken muss, 
oder ob das adressbyte reicht (schließlich will ich ja nur eine 
analog-zu-digital-konversation)
Ich hoffe, dass sich jemand mit dem Chip auskennt und mir helfen kann.

Das Problem ist, dass alle LED's leuchten. Ich also FF zurücbekomme, 
egal wie die Stellung des Poti ist.

Das Datenblatt findet sich hier:
http://www.nxp.com/acrobat_download/datasheets/PCF8591_6.pdf

und mein Code hier. Ich hoffe er ist übersichtlich:
include reg52.inc
 ;------------------------------------------------------ANFANG MAKROS---------------------------------------------------------------
SCL equ p3.4
SDA equ p3.5
epreg equ R0
epzaehler equ R1
adresse equ R5
adresszaehler equ R6
isr_zustand equ R7
zahl_sichtbar equ R3
LCALL init0
;---------------------------------------------------------ENDE MAKROS---------------------------------------------------
JMP Init
ORG 000Bh                  ;ISR-Einsprungadresse für Timer0-überlauf
JMP ISR
;-------------------------------------------------ANFANG INITIALISIERUNG----------------------------------------------------
init0:
  MOV P2, #0h
  CLR SCL
  SETB SDA
  MOV adresse, #10010011b        ;1001 = fix, 0 = !autoinkrement, 01= A0 gesetzt 1 = read
  MOV ISR_zustand, #0h          ;Zustand 0 von ISR = startdefinition senden
  MOV dptr,#seg7code
  RET

Init:  
  LCALL interrupt_init          ;interrupt wird eingeschaltet
  LCALL Timerinit             ;Timer wird eingeschaltet
  JMP Haupt
  interrupt_init:  
    MOV IE, #10000010b        ;Einschalten der Erlaubnis eines interrupts und von int0 (timer-CF)
    RET
  Timerinit:       
    MOV TMOD, #0001b          ;Modus 1.. nachladefunktion
      ;MOV TL0, #000d
      ;MOV TH0, #000d            ;nachladewert
      SETB TR0                ;negativflanke
    RET
;--------------------------------------------------ENDE INITIALISIERUNG----------------------------------------------------
;--------------------------------------------------ANFANG HAUPTSCHLEIFE----------------------------------------------------
Haupt:  LCALL ISR_kontroller
      LCALL Anzeige
      JMP Haupt
;--------------------------------------------------ENDE HAUPTSCHLEIFE------------------------------------------------------
;--------------------------------------------------ANFANG INTERRUPTSTRUKTUR------------------------------------------------
;Z0 = start/stopdefinition
;Z1 = daten senden
;Z2 = daten empfangen
;Z3 = ack senden
;Z4 = ack empfangen

ISR_kontroller:
  CJNE epzaehler, #8h, kontroll1      ;epzaehler = 7? dann habe ich das gesamte byte erhalten und muss en ack senden
    MOV epzaehler, #0h
    MOV ISR_Zustand, #3h
  kontroll1:  CJNE adresszaehler, #8h, kontroll2    ;adressz = 8? adresse wurde an device gesendet und ich muss das ack annehmen
          CLR SDA              ;vielleicht muss ich mein sda-output ausschalten.. damit device funzt
          MOV adresszaehler, #0h
          MOV adresse, #11001001b
          MOV ISR_zustand, #4h
  kontroll2:  RET
  
ISR:  
  PUSH ACC
  CPL SCL
  JB SCL, start_empfang              ;ist die clock 0, können wir daten bzw. das ack senden..ansonsten läuft es hier wieter
    CJNE ISR_zustand, #1h, Z3        ;zustand = 3? dann springts zu zustand 3
      MOV A, adresse              ;zustand 1
      RRC A
      MOV SDA, C
      MOV adresse A
      INC adresszaehler
      JMP ISR_ende
    Z3:CJNE ISR_zustand, #3h, ISR_ende
      CLR C                  ;Zustand 3
      MOV SDA, C
      MOV ISR_zustand, #2h          ;ack wurde gesendet und kann wieder auf empfang gehen (zustand 2)
      JMP ISR_ende    
      
  start_empfang:CJNE ISR_zustand, #0h, Z2  ;zustand = 2? dann springts weiter.. ansonsten gehts einfach weiter
      CLR C                    ;Zustand 0
      MOV SDA, C
      INC ISR_zustand            ;zustand 0 wird zu zustand 1
      JMP ISR_ende
      
    Z2:CJNE ISR_zustand, #2h, Z4
      INC epzaehler              ;Zustand 2
      MOV A, epreg
      MOV C, SDA
      MOV P2.0, C
      RLC A
      MOV epreg, A
      JMP ISR_ende
    Z4:CJNE ISR_zustand, #4h, ISR_ende  ;hier nehme ich das ack vom device an. ist es 1, ist alles ok. ansonsten muss ich die adresse nochmal schicken... also von vorne (zustand 0)
      MOV C, SDA                ;will erstmal nur wissen ob es klappt, dass ich ein ack bekomm
      MOV P2.1, C;scheint 0 zu sein
      JB SDA, Z4z
        MOV adresszaehler, #0h
        MOV adresse, #10010011b
        MOV ISR_zustand, #0h
      Z4z:  MOV ISR_zustand, #2h    
      
  ISR_ende:
      POP ACC
      RETI
;---------------------------------------------------ENDE INTERRUPT---------------------------------------------------------
;---------------------------------------------------ANFANG ANZEIGE---------------------------------------------------------
Anzeige:
  ;MOV P2, epreg          ;erstmal nur übergangsweise... binäre anzeige des epregs
  RET

;Anzeige:
;  ADD A, epreg
;  JNB CY, anzeige_ende
;  PUSH ACC
;  MOV A, zahl_sichtbar
;  MOVC A, @A+dptr
;  MOV zahl_sichtbar, A
;  MOV P2, A
;  POP ACC
;  anzeige_ende: RET
;---------------------------------------------------ENDE ANZEIGE----------------------------------------------------------
seg7code:
DB 01111110b, 00010010b,10111100b,10110110b,11010010b,11100110b,11101110b,00110010b,11111110b,11110110b 

END

Autor: Klaus (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Wäre net wenn Du mal ein Flussdiagramm zeichnen würdest, damit man 
blickt wie das Programm arbeiten soll. Beschreib mal dein Konzept.

Irgendwie drängt sich mir auf, das da was fehlt aber ich komm nicht 
drauf.

Du musst zuerst dem PCF8591 über, das Controll-Byte, mitteilen von 
welchen Kanal Du den Analogenwert empfangen möchtest auswählen.
Im einfachsten Fall solltest Du noch single ended wählen.

Im Anhang siehst Du wie gelesen werden muss um einen Analogen Wert zu
empfangen.

Also musst Du dem PCF8591 mitteilen das Du lesen möchtest und immer ein 
ACK sendest solange wie Du Daten empfangen willst danach auf jedenfall 
nACK und I2C_Stop senden.

Autor: rossi75 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe mit dem 8591 auch schon mal gearbeitet. Wenn ich Freitag 
zuhause bin dann kann ich Dir meinen Code für den 8051 schicken (wenn es 
dann noch nicht zu spät ist...).

cu,
olly...

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für eure Antworten,
ein Flussdiagramm kann ich die kommenden Tage sehr gerne uploaden und 
dann hier reinstellen.


@klaus
eben das Frage ich mich auch...ob ich nun das Controlbyte benötige oder 
nicht. aber wenn man mal auf die Protokolle bei der 
analog-digital-konversation schaut (datenblatt), dann ist da keins 
eingetragen. ur beim digital zu analog. Un dich will ihm ja keine 
digitaen inputs geben, wie du gecshrieben hast.. sondern analoge und es 
sollen digitale rauskommen.

Das mit dem ack hab ich auch gemacht... theoretisch sollte es klappen





@rossi75
nein der source wäre dann absolut nicht zu spät... =) ich würde ihn 
nicht übernehmen.. dafür hab ich schon zu lange an meinem gearbeitet. 
aber dadurch kann ich sehr gut entdecken was ich falsch habe.

Autor: Klaus (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Habe mal herumgestöbert und doch noch was gefunden.

Ich hab hier mal in Komprimierter Form ein Dateianhang.
Ich Habe damals einen Sensor GP2D120 zum Spass mal Angeschlossen.

Soviel ich noch weiss muss man erst einen sog. Dummy einlesen dann erst 
die Werte. Frag mich aber nicht warum das so ist. Steht so irgendwo in 
der Doku.

Ich hoffe es hilft dir ein wenig weiter.

Autor: rossi75 (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
So, als Anhang mein Quelltext zur Unterhaltung auf der 
I2C-Schnittstelle...

#define PCF8591_0      0x48  // 01001000

_Aufruf zum Schreiben:_
Str_Temp[0] = 0x40; // Konfiguration (EP0 lesen, 4 Endpunkte, D/A aktiv)
Str_Temp[1] = Str_Delayer[0]; // Wert der ausgegeben werden soll
i2c_send(PCF8591_0, 0, Str_Temp, 2); // Schreiben des DA-Wertes

_Aufruf zum Lesen:_
i2c_send(PCF8591_0, 1, Str_Temp, 4); // Leseanforderung von 4 Werten
delayer_wrt(twi_message.buf[1]); // Spannungsergebnis in den Delayer 
schreiben

ich hoffe Euch geholfen zu haben...
olly...

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.