Forum: Mikrocontroller und Digitale Elektronik PCF8591 ADC-Funktion


von Sebastian (Gast)


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:
1
include reg52.inc
2
 ;------------------------------------------------------ANFANG MAKROS---------------------------------------------------------------
3
SCL equ p3.4
4
SDA equ p3.5
5
epreg equ R0
6
epzaehler equ R1
7
adresse equ R5
8
adresszaehler equ R6
9
isr_zustand equ R7
10
zahl_sichtbar equ R3
11
LCALL init0
12
;---------------------------------------------------------ENDE MAKROS---------------------------------------------------
13
JMP Init
14
ORG 000Bh                  ;ISR-Einsprungadresse für Timer0-überlauf
15
JMP ISR
16
;-------------------------------------------------ANFANG INITIALISIERUNG----------------------------------------------------
17
init0:
18
  MOV P2, #0h
19
  CLR SCL
20
  SETB SDA
21
  MOV adresse, #10010011b        ;1001 = fix, 0 = !autoinkrement, 01= A0 gesetzt 1 = read
22
  MOV ISR_zustand, #0h          ;Zustand 0 von ISR = startdefinition senden
23
  MOV dptr,#seg7code
24
  RET
25
26
Init:  
27
  LCALL interrupt_init          ;interrupt wird eingeschaltet
28
  LCALL Timerinit             ;Timer wird eingeschaltet
29
  JMP Haupt
30
  interrupt_init:  
31
    MOV IE, #10000010b        ;Einschalten der Erlaubnis eines interrupts und von int0 (timer-CF)
32
    RET
33
  Timerinit:       
34
    MOV TMOD, #0001b          ;Modus 1.. nachladefunktion
35
      ;MOV TL0, #000d
36
      ;MOV TH0, #000d            ;nachladewert
37
      SETB TR0                ;negativflanke
38
    RET
39
;--------------------------------------------------ENDE INITIALISIERUNG----------------------------------------------------
40
;--------------------------------------------------ANFANG HAUPTSCHLEIFE----------------------------------------------------
41
Haupt:  LCALL ISR_kontroller
42
      LCALL Anzeige
43
      JMP Haupt
44
;--------------------------------------------------ENDE HAUPTSCHLEIFE------------------------------------------------------
45
;--------------------------------------------------ANFANG INTERRUPTSTRUKTUR------------------------------------------------
46
;Z0 = start/stopdefinition
47
;Z1 = daten senden
48
;Z2 = daten empfangen
49
;Z3 = ack senden
50
;Z4 = ack empfangen
51
52
ISR_kontroller:
53
  CJNE epzaehler, #8h, kontroll1      ;epzaehler = 7? dann habe ich das gesamte byte erhalten und muss en ack senden
54
    MOV epzaehler, #0h
55
    MOV ISR_Zustand, #3h
56
  kontroll1:  CJNE adresszaehler, #8h, kontroll2    ;adressz = 8? adresse wurde an device gesendet und ich muss das ack annehmen
57
          CLR SDA              ;vielleicht muss ich mein sda-output ausschalten.. damit device funzt
58
          MOV adresszaehler, #0h
59
          MOV adresse, #11001001b
60
          MOV ISR_zustand, #4h
61
  kontroll2:  RET
62
  
63
ISR:  
64
  PUSH ACC
65
  CPL SCL
66
  JB SCL, start_empfang              ;ist die clock 0, können wir daten bzw. das ack senden..ansonsten läuft es hier wieter
67
    CJNE ISR_zustand, #1h, Z3        ;zustand = 3? dann springts zu zustand 3
68
      MOV A, adresse              ;zustand 1
69
      RRC A
70
      MOV SDA, C
71
      MOV adresse A
72
      INC adresszaehler
73
      JMP ISR_ende
74
    Z3:CJNE ISR_zustand, #3h, ISR_ende
75
      CLR C                  ;Zustand 3
76
      MOV SDA, C
77
      MOV ISR_zustand, #2h          ;ack wurde gesendet und kann wieder auf empfang gehen (zustand 2)
78
      JMP ISR_ende    
79
      
80
  start_empfang:CJNE ISR_zustand, #0h, Z2  ;zustand = 2? dann springts weiter.. ansonsten gehts einfach weiter
81
      CLR C                    ;Zustand 0
82
      MOV SDA, C
83
      INC ISR_zustand            ;zustand 0 wird zu zustand 1
84
      JMP ISR_ende
85
      
86
    Z2:CJNE ISR_zustand, #2h, Z4
87
      INC epzaehler              ;Zustand 2
88
      MOV A, epreg
89
      MOV C, SDA
90
      MOV P2.0, C
91
      RLC A
92
      MOV epreg, A
93
      JMP ISR_ende
94
    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)
95
      MOV C, SDA                ;will erstmal nur wissen ob es klappt, dass ich ein ack bekomm
96
      MOV P2.1, C;scheint 0 zu sein
97
      JB SDA, Z4z
98
        MOV adresszaehler, #0h
99
        MOV adresse, #10010011b
100
        MOV ISR_zustand, #0h
101
      Z4z:  MOV ISR_zustand, #2h    
102
      
103
  ISR_ende:
104
      POP ACC
105
      RETI
106
;---------------------------------------------------ENDE INTERRUPT---------------------------------------------------------
107
;---------------------------------------------------ANFANG ANZEIGE---------------------------------------------------------
108
Anzeige:
109
  ;MOV P2, epreg          ;erstmal nur übergangsweise... binäre anzeige des epregs
110
  RET
111
112
;Anzeige:
113
;  ADD A, epreg
114
;  JNB CY, anzeige_ende
115
;  PUSH ACC
116
;  MOV A, zahl_sichtbar
117
;  MOVC A, @A+dptr
118
;  MOV zahl_sichtbar, A
119
;  MOV P2, A
120
;  POP ACC
121
;  anzeige_ende: RET
122
;---------------------------------------------------ENDE ANZEIGE----------------------------------------------------------
123
seg7code:
124
DB 01111110b, 00010010b,10111100b,10110110b,11010010b,11100110b,11101110b,00110010b,11111110b,11110110b 
125
126
END

von Klaus (Gast)


Angehängte Dateien:

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.

von rossi75 (Gast)


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...

von Sebastian (Gast)


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.

von Klaus (Gast)


Angehängte Dateien:

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.

von rossi75 (Gast)


Angehängte Dateien:

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...

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.