PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : PIC16F84A mit PCF8574 über I2C --->Testanzeige über LED's



gstyla85
09.10.2008, 14:33
Hallo!
Ich habe ein kleines Problem mit meiner I2C-Routine.
Ich benutze einen Pic16f84a und einen PCF8574. Am Expander sind Dipschalter mit Pull-Ups dran und dann gehts über I2C zum PIC PortB 6/7. Gleichzeitig habe ich an PortB 8 LEDs angeschlossen. Diese sollen mit den DIP-Schaltern am PCF angesteuert werden.
ICh muss sagen, dass ich auf dem GEbiet ein Anfänger bin und wollte fragen, ob es dabe was zu beachten gibt. Oder ob jemand schon ein ähnliches Projekt hatte. Das ganze soll in ASM geschrieben werden.

Ich werde gleich noch meinen ASM-Code posten.

Vielen Dank im Voraus!

wberger
09.10.2008, 18:35
Stell doch mal den Schaltplan online. Ich frage mich, wie du Ports RB6 und 7 zwischen LED und I2C multiplext. LED gegen plus oder gegen Masse? Welcher LED Vorwiderstand? Welcher I2C Pull-up?

Gruß
Wolfgang

gstyla85
09.10.2008, 21:36
Stell doch mal den Schaltplan online. Ich frage mich, wie du Ports RB6 und 7 zwischen LED und I2C multiplext. LED gegen plus oder gegen Masse? Welcher LED Vorwiderstand? Welcher I2C Pull-up?

Gruß
Wolfgang


Die (low current)LED's sind mit Vorwiderständen 1,5k gegen 5V geschaltet.
Und in diesem AUgenblick wird mir schon mein erster Fehler klar :) Ich deklariere ja die PORT's als Ausgang und bekomme ja einen TTL-Signal am Ausgang. Aber wie sage ich dem PIC, dass er mir je nach DIP-Schalterstellung vom 8574 an dem jeweiligen PIC-Pin, den Massebezug herstellen soll?
Im Datenblatt vom Pic16f84a steht, dass die Pins 6/7 vom PortB für serielle Datenübertragung dienen. Kann ich aber trotzdem meine SDA/SCL-Leitung zum Bsp an PORTA anschliessen?
In meiner Software muss ich eben das ganze "multiplexen", in dem ich die PortB Pins 6 und 7 immer zwischen Input/Output deklariere.

ICh habe jetzt keinen Schaltplan parat aber habe hier einen gekritzelt ;)
http://i33.tinypic.com/i69f8g.jpg




;************************************************* ************************************************** *********************************
; Programm EXPANDER.asm: Demoprogramm SeriellePorterweiterung mit PCF 8574 ,
; Porterweiterung dient als Eingang; eingegebene Daten werden an Port B über 8 LEDs ausgegeben .
; PIC 16F84A, f = 4 MHz
;************************************************* ************************************************** *********************************
#include <P16F84A.INC>
list P=PIC16F84A
__CONFIG _XT_OSC &_WDT_OFF
errorlevel -302 ;Eliminate bank warning



ZAEHL1 equ 21H ;
ZAEHL2 equ 22H ;
ZAEHL3 equ 23H ;


;Definition
#define sda PORTB, 7 ;RB,7 Datenleitung SDA
#define scl PORTB, 6 ; RB,6 Taktleitung SCL
; Konstanten
teiladrs equ 0x41 ; Bauteil-Adresse: 41h fuer Lesen aus PCF 8574

; Ziele der Registeroperationen
w equ 0
f equ 1

org 0x0 ; Programmanfang bei PC = 0

start goto init


;************************************************* ************************************************** *********************************
; Erzeugen der Startbedingung: 1-0-Uebergang von SDA, waehrend SCL = 1 ist
;************************************************* ************************************************** *********************************
bstart bcf scl ;sichergehen, dass scl auch 0 ist
bsf scl ;scl=1
call pause
bsf sda ;sda=1
call pause
bcf sda ;sda=0
call pause
bcf scl ;scl=0
return

;************************************************* ************************************************** *********************************
; Erzeugen der Stoppbedingung: 0 -1- Uebergang von SDA, waehrend SCL = 1
;************************************************* ************************************************** *********************************
bstop bcf sda ;sichergehen, dass sda auch wirklich 0 ist
call pause ;
bsf scl ; Takt auf High
call pause ;
bsf sda ;0-1 -Flanke von sda
return
;************************************************* ************************************************** *********************************
; Lesen eines bit aus dem Expander und Ablegen in ZAEHL3
;************************************************* ************************************************** *********************************
bitein bsf STATUS,RP0 ;auf Bank 1 umschalten
movlw 0xBF ;1011 1111 ins w-reg
movf TRISB ;RB7 = Input / RB6 muss Output bleiben, da der takt vom Pic erzeugt wird
bcf STATUS,RP0 ;
bsf sda ;
bsf scl ;
call pause ;
bcf ZAEHL3,0 ;
btfsc sda ;
bsf ZAEHL3,0 ;
bcf scl ;
return
;************************************************* ************************************************** *********************************
; Bestätigungsbit an das EEPROM augeben
;************************************************* ************************************************** *********************************
bitaus bsf STATUS,RP0 ;sda auf Output setzen
bcf sda ;
bcf STATUS,RP0 ;
btfss ZAEHL3,1 ; teste ob bit1 im zaehl3 =0 dann sda=0
goto I2C_Weiter1 ;
bsf sda ;wenn bit1=1 dann setze sda=1
goto I2C_Weiter2 ;
I2C_Weiter1 bcf sda ;
I2C_Weiter2 bsf scl ;
call pause ;
bcf scl ;
return
;************************************************* ************************************************** *********************************
; Uebertragen eines Datenbytes aus ZWISCH ueber EEPROM,do ins PCF 8574; ZWISCH muss vorher aus DATAUS
; geladen sein. Nach dem 8. bit erfolgt ein 9. Taktpuls und Test des Bestaetigungsbits vom Eeprom auf 0. Ist das
; Bestaetigungsbit = 1, wird als Fehlermeldung RA0 = 1 gesetzt (LED).
;************************************************* ************************************************** *********************************
I2C_Schr movlw 0x08 ;
movwf ZAEHL2 ;
I2C_Schl2 bcf ZAEHL3,1 ;
btfsc ZAEHL1,7 ;
bsf ZAEHL3,1 ;
call bitaus ;
rlf ZAEHL1,f ;
decfsz ZAEHL2,f ;
goto I2C_Schl2 ;
call bitein ;
return
;************************************************* ************************************************** *********************************
; Lesen eines Datenbytes aus PCF 8574 nach DATEIN; danach Bestaetigungsbit =1 ausgeben,
; um Stoppbedingung zu ermöglichen
;************************************************* ************************************************** *********************************
I2C_Lesen clrf ZAEHL1 ;
movlw 0x08 ;
movwf ZAEHL2 ;
bcf STATUS,0 ;
I2C_Schl1 rlf ZAEHL1,f ;
call bitein ;
btfsc ZAEHL3,0 ;
bsf ZAEHL1,0 ;
decfsz ZAEHL2,f ;
goto I2C_Schl1 ;
bsf ZAEHL3,1 ;
call bitaus ;
return
;************************************************* ************************************************** *********************************
; Programmbeginn
;************************************************* ************************************************** ********************************
init bsf STATUS,RP0 ;
clrf PORTB ;
bcf STATUS,RP0 ;

;************************************************* ************************************************** *********************************
; Daten aus PCF 8574 lesen
lies clrf ZAEHL1 ;
clrf ZAEHL2 ; Vorbereiten zum Lesen des PCF 8574
clrf ZAEHL3 ;
call bstart ; Startbedingung uebertragen
movlw teiladrs ;
movwf ZAEHL1 ; Bauteiladresse f. Lesen (41h) uebertragen
call I2C_Schr ;
call I2C_Lesen ; 1 Datenbyte aus PCF 8574 lesen
call bstop ; Stoppbedingung uebertragen


;************************************************* ************************************************** *********************************
; Daten von PCF 8574 in DATEIN
bsf STATUS, RP0 ;
clrf TRISB ;
bcf STATUS, RP0 ;
movf ZAEHL1,w ; ZAEHL1 nach w
movwf PORTB ; und nach Port B
clrw
call pause ; 10 ms Pause zum Anzeigen
goto lies

org 1FF
goto start
;************************************************* ************************************************** *********************************
;Pausenzeit
;************************************************* ************************************************** *********************************
pause nop
return

end

Jojo12
29.10.2008, 15:21
Hallo, was ich bis jetzt geshen hab,als ich mal deinen Code überflogen habe ist, dass du die Addresse des Slaves so deklarierst: teiladrs equ 0x41
Damit benennst du aber die Speicherzelle 0x41 teiladrs. Richtig müsste es dann ja heißen: #define teiladrs 0x41
Ich hoffe das hilft schonmal nen bisschen.