PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Problem mit Pegel beim I2C



snabernick
13.04.2005, 10:21
Hallo,
ich habe ein ähnliches Projekt wie in diesem Forum bereits gepostet wurde. Ein PIC (16F788) soll über I2C einen I/O-Expander (pcf8574a) auslesen und die Zustände der Eingänge am Port ausgeben.

Die I2C Schnittstelle funktioniert soweit ich es erkennen kann, die Impulse sind am Oszilloskop genau so zu erkennen wie sie sein sollen bei der Adresse (01110001). Als Antwort vom Expander erhalte ich aber kein ACK --> Die Daten welche ich nachher von ihm erhalte sind alle High.
Ich vermute, dass der Pegel welche ich am I2C habe zu niedrig ist (2,5V). Gefordert wären laut Datenblatt 0,7*V++=3,5V. Die Pullup Widerstände betragen 4k7 und sind alle korrekt angeschlossen.

Hat jemand eine Ahnung warum die Spannung so klein ist???

mfg mike

stegr
13.04.2005, 13:30
Wie hast du die Spannung gemessen - Oszi oder Multimeter?
mit welcher Spannung laufen PIC und IO-Extender?

Die Pullups dürften passen...

Da du kein Ack bekommen hast, dürfte der Expander schon falsch angesprochen worden sein...

Beantworte mal die Fragen, dann sollte man dir weiterhelfen können...

MfG
Stefan

snabernick
14.04.2005, 12:40
Die Spannung habe ich mit den Oszilloskop und Multimeter gemessen, die Spannung beträgt 2,8V.

Beide Bausteine werden mit einer Betriebsspannung von 5V betrieben, wobei die Frequenz am Bus vom Expander nicht höher als 100kHz sein sollte. Bei mir ca. 90kHz

Das Problem ist, dass mir die Spannung irgendwie "einbricht" auf 2,8V. Muss im Pic irgendein Bit gesetzt werden, damit der Ausgang auf Low gezogen wird bei einer 0 und auf Tristate schaltet bei einer 1 ??

PicNick
14.04.2005, 12:51
Wir hatten mal den Fall, da war am Mega eins der I2C Ports hinüber. Sind wir erst durch normal-Output-Pin definition und gezieltes setzen draufgekommen. (da hat er dann NICHT 0/5 V zusammengebracht)
Mußten wir den Mega austauschen.

snabernick
14.04.2005, 13:34
Kann ich einfach die Pin des Busses wie einen normalen Ausgang auf High setzen?? oder muss zuvor der Bus abgschaltet werden...?

PicNick
14.04.2005, 13:56
Ja schon, keinen init /define auf den I2C (auskommentieren)

snabernick
15.04.2005, 21:21
Hallo,

danke für den Tipp, ich habe nun die Schnittstelle initialisiert und die Pins gesetzt. Messe ich die Spannung ohne Pullup Widerstände, so hab ich 0V (Tristate). Schließe ich nun die Pullup- Widerstände an, so erhalte ich 5V wie es sein soll.
Daraus schließe ich, dass der I2C Bus in Ordnung ist.
Wenn ich nun die Pins wieder rücksetzte so erhalte ich wieder die Spannung von 3,4V an SDA und 2,5V an SCL, mit dem Messgerät gemessen.

Ich hab hier mal den Quellcode eingefügt, vieleicht befindet sich ja hier ein Programmierfehler:


[php:1:1dcf790aa2]
list p=16f877

#include <p16f877.inc>

__Config _WDT_OFF & _HS_OSC & _LVP_OFF & _BODEN_OFF

;################################################# ###############
;Port belegung

#define RunningLed PORTC,0

;----------------------------------------------------------------
;Variablendeklaration

DELAY_H EQU 0x20
DELAY_L EQU 0x21

;----------------------------------------------------------------
;Konstanten
#define ADR0_R b'01110001'
#define ADR0_W b'01110000'
#define ADR1_R b'01110011'
#define ADR1_W b'01110010'

;---------------------------------------------------------------
;Programmbeinn

ORG 0x00
clrf STATUS
goto MAIN0

;--------------------------------------------------------------
;Macros

BANK0 MACRO
bcf STATUS,RP0
bcf STATUS,RP1
ENDM
BANK1 MACRO
bsf STATUS,RP0
bcf STATUS,RP1
ENDM
BANK2 MACRO
bcf STATUS,RP0
bsf STATUS,RP1
ENDM
BANK3 MACRO
bsf STATUS,RP0
bsf STATUS,RP1
ENDM
;--------------------------------------------------------------
;Interrupt Routine

ORG 0x04

;--------------------------------------------------------------
;--------------------------------------------------------------

MAIN0 call INIT

MAIN incfsz DELAY_L
goto SendByte
movlw b'00000001'
xorwf PORTC,F

SendByte call I2C_ON ;BUS übernehmen
movlw ADR0_R ;Adresse festlegen
call I2C_TX ;Senden
call I2C_RX ;Empfangen
movwf PORTB ;Empfangene Daten ausgeben
call I2C_OFF ;BUS freigeben
goto MAIN

;--------------------------------------------------------------
;--------------------------------------------------------------
;--------------------------------------------------------------


INIT BANK1
;PORT initialisierug
;PORTA initialisieren
movlw 0x06 ;Alle analogen Eingänge auf digital schalten
movwf ADCON1

movlw b'11111111'
movwf TRISA ;Tristate setzen

;PORTB initialisieren
movlw b'00000000'
movwf TRISB ;Tristate setzen

;PORTC initialisieren
movlw b'11111110'
movwf TRISC

;BANK0
;Schnittstellen initialisieren
;I2C
;BANK1
bcf SSPSTAT,SMP ;Slew rate control disable
bcf SSPSTAT,CKE ;I2C confor levels
movlw .9 ;Busgeschwindigkeit 100kHz
movwf SSPADD
BANK0
bcf SSPCON,CKP ;Clock disable
bsf SSPCON,SSPM3 ;I2C Mode
bcf SSPCON,SSPM2
bcf SSPCON,SSPM1
bcf SSPCON,SSPM0
bsf SSPCON,SSPEN ;Enable Serial Port

;Variablen setzen
clrf DELAY_H
clrf DELAY_L

return

;----------------------------------------------------------------
;I2C Bus Übernahme

I2C_ON bcf PIR1,SSPIF
BANK1
bsf SSPCON2,SEN ;Start condition
BANK0
btfss PIR1,SSPIF
goto $-1
bcf PIR1,SSPIF
return

;----------------------------------------------------------------
;I2C Bus freigeben

I2C_OFF bcf PIR1,SSPIF
BANK1
bsf SSPCON2,PEN ;Stop condition
BANK0
btfss PIR1,SSPIF
goto $-1
bcf PIR1,SSPIF
return

;----------------------------------------------------------------
;I2C Senden

I2C_TX movwf SSPBUF ;Daten ins Senderegister
btfss PIR1,SSPIF ;Byte gesendet?
goto $-1 ;Nein
bcf PIR1,SSPIF ;Ja
return

;----------------------------------------------------------------
;I2C Empfangen

I2C_RX BANK1
bsf SSPCON2,RCEN ;Daten empfang einschalten
BANK0

btfss PIR1,SSPIF ;Byte empfangen?
goto $-1 ;Nein
bcf PIR1,SSPIF ;Ja

movf SSPBUF,W ;Buffer einlesen
return

;----------------------------------------------------------------
;----------------------------------------------------------------
;----------------------------------------------------------------
;----------------------------------------------------------------

END

[/php:1:1dcf790aa2]

PicNick
16.04.2005, 11:24
Tscha, ich kann so nix entdecken
Nur eines: Beim Initialisieren
setze ich TRISC etwas anders
movlw B'00011000' ; PortC I2C Input 3/4
Und cleare
clrf SSPCON2

Soll nicht heißen, daß das deswegen gehen muß , aber ich weiß, daß die Dinger manchmal auf details happig sind.


Blöde Frage: Die I2C - Adresse stimmt ?

snabernick
16.04.2005, 13:53
Hallo,
ich habe jetzt beim Initialisieren SSPCON2 gelöscht und den Port anders initialisiert. Bei den Pegeln ändert sich trotzdem nichts.

Die Adresse ist korrekt eingestellt 0111 für den Hardware- Teil und 000 für den Teil welchen ich auf GND gelegt habe. Die 1 steht fürs lesen.

Bei der Schaltung kann kein Fehler sein, ich habe SDA am PIC mit SDA am Expander verbunden und SCL mit SCL. Weiters liegen beide Leitungen über Pullup an VCC.

Die Port-Pins am Expander hengen in der Luft, kann das ein Problem sein??

PicNick
16.04.2005, 14:19
Kann schon sein, denn man sieht's den FF nicht an, ob sie vom I2C Bus oder vom PCF kommen. häng mal einen auf Ground (aber nur, wenn du auch immer vom PCF liest)
Pegel: Mach doch mal NACH dem Initialisieren der I2C einen forever-Loop und sonst nix. In dieser Situation (keinerlei open) müssen die Pegel auf Gleichstrom-High sein, sonst könnte er den Bus auch selbst garnicht übernehmen. Bevor das nicht ist, brauchst du den PCF eigentlich garnicht erst anquatschen.
Nimm ev. den PCF mal raus und miß' den I2C-Bus pur.

snabernick
17.04.2005, 12:34
Hallo Robert,

danke für den Tipp, ich habe den PIC initialisiert und dann eine Enlosschleife gestartet. Ich habe die Spannung einmal mit PCF gemessen und einmal ohne.
Die Spannung am Bus beträgt beidemale 5V --> die Schnittstelle muss so weit ich es beurteilen kann in Ordnung sein.

Einen Pin auf GND zu legen hilft auch nicht. Alle PIN's am PORTB bleiben auf HIGH. Das Problem muss also irgendwie mit dem "Bus übernehmen" oder "Adresse senden" zusammenhängen. Vermute ich...

PicNick
17.04.2005, 18:50
PCF rausnehmen und I2C-Pegel dann (nach normalem init) checken hast du gemacht ?
Wenn die Pegel nicht passen, ist der Bus ja scheinbar belegt, da muß er doch beim Bus-Übernehmen schon irgendwelche Fehler zeigen.
PIC mal tauschen geht wohl nicht ?

snabernick
18.04.2005, 15:43
Ja, den PCF hab ich herausgenommen beim Messen und habe nach normaler Initialisierung 5V gemessen. Den PIC und PCF hab ich auch schon getauscht.
Mir ist es rätselhaft wieso die Spannung 5V beträgt nach dem initialisieren und nachher so weit absinkt...

PicNick
18.04.2005, 16:01
Nochmal:
OHNE PCF mit initialisiertem I2C hast du 5V ?
MIT PCF mit initialisiertem I2C hast du 2.5 V ?
wenn so ist, dann hat's was mit dem PCF

snabernick
18.04.2005, 17:10
Hallo Robert,

Ich habe mit PCF und ohne PCF 5V am Bus anliegen

PicNick
18.04.2005, 17:47
D.h, du hast den I2C initialisiert (und SDA u. SDL Ports auf Input) und mißt 5V (durch die Pullup) ? wär ja o.k.
Wenn du dann sendest, sind die Signale aber nur 0-2.5 V ?
Deshalb kein Ack, aber nach dem Senden (nach I2CStop) hast du wieder 5V ?
Wenn es so ist, ist der PIC hinüber, was die HW-I2C betrifft.
Da hätt ich keine andere Erklärung

snabernick
18.04.2005, 19:19
Ja, so sieht es aus!

Danke für dein bemühen. Ich versuche es mal mit dem 16f88 vieleicht sind die 3 Samples welche ich habe vom 16f877 wirklich alle hinüber...