PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : I2C Slave im PIC



FancanTeik
09.07.2004, 15:29
Hallo,

hat wer schon mal den I2C slave in einem PIC zum laufen gebracht?

Überall lese ich nur von Problemen. Ich möchte einen PIC16F819 (der hat HW I2C) als Intelligenten Sensor an meiner Roboter Platine betreiben.

Bevor ich das Geld für den PIC + Brenner in den Sand setzte ...

Danke

Fancan

mcs
26.07.2004, 10:12
Was für Sensoren willst du denn dran bauen?

FancanTeik
26.07.2004, 19:41
Mein Roboter "Mainboard" hat einen 400 kHz I2C Bus als Extension Bus.
An den möchte ich meine Erweiterungen anschließen.

Geplant sind bis jetzt eine Lego Mindstorms kompatibles Infrarot Sende und Empfangsmodul, damit mein Robby mit den Mindstorms kommunizieren kann.
Das 2. Module ist für die aktiven Legosensoren, die ich dann auch mit meinen Board nutzen kann. Aktive Legosensoren übertragen die Versorgungsspannung und die Sensordaten über eine 2 Drahtleitung im Zeitmultiplex.

Meine Idee war nun den PIC16F819 einzusetzen, der hat nur 18 Pins aber ein HW I2C Interface, 1x PWM und einen 5 Kanal 10 bit AD Wandler.
Also ideal für kleine Erweiterungen mit ein wenig eigen Intelligenz für die echtzeit.

Fancan

02.08.2005, 23:18
also ich hab meine elekronik jetzt auch nahezu fertig und hab sie auch auf I2C aufgebaut jedoch müssen bei mir 3 PICs miteinander kommunizieren das jedoch nur in einer richtung Master-->beide slaves bin mir aber auch noch nicht sicher wie ich das codetechnisch hinkriege aber ich probier die woche einfach mal rum werds schon irgendwie rauskriegen hoffe ich ich lass euch dann den code (assembler) hier in den thread falls ichs irgendwie hinkrieg ;) wäre jedoch auch um jede hilfe froh!!
für master gibts ja mehr wie genug anleitungen .. aber für slave schauts ja echt mager aus.. naja bin jedenfalls froh dass jemand diese frage gestellt hat sons müsst ich sie jetzt stellen!
mfg
m0

the_Ghost666
03.08.2005, 17:59
schau mal ins datenblatt, da sind die einstellungen eigentlich ganz gut beschrieben, du suchst dir ne adresse aus, indem du sie in das nötige register schreibst, usw. den rest müsste das modul können, ausserdem solltest du über einen interrupt anfragen können, ob was angekommen ist und dann auswerten und reagieren

m0
03.08.2005, 20:37
Hi!
also ich bin übrigens der Gast von 2 threads weiter oben sorry....
hab mich jetzt mal hingesetzt und das versucht sitz jetzt aber schon 4 stunden an dem slave.. will einfach nicht.. es währe echt total genial wenn sich jemand der sich auskennt mal meinen code ansieht! is auch schön kurz nur zum testen vielleicht hab ich ja nur irgend ne kleinigkeit vergessen.. naja den master hab ich aus den schnipseln von www.sprut.de zusammengesetzt aber vielleicht liegts ja auch an dem... ich verzweifel hier auf jedenfall fast.. wäre echt spize wenn sich jemand die mühe macht sich das anzusehen!!
hier mal die codes (für PIC16F877 @ 4mHz):

Master:


#include <P16f877.INC>
__CONFIG _PWRTE_ON & _WDT_OFF & _HS_OSC & _LVP_OFF & _BODEN_OFF

adresse1 EQU 0x26 ; Variablen Declarieren ;)
loops EQU 0x28
loops2 EQU 0x29
temp EQU 0x2A

; reicht vorerst an vars will ja nix übertreibn
org 0
goto init

; init the I2C stuff::::::::::::::::::::::::::::::::::::::::::::: :::::::
init
movlw B'01001000'
movwf adresse1

bsf STATUS, RP0 ; Bank1
movlw B'00011000' ; trisc 2+3 inputs für i2c
movwf TRISC ;
movlw B'00000000' ; trisd outputs für servos
movwf TRISD ;
movlw B'00000000' ; trisb outputs für LEDs und Relais
movwf TRISB ;
movlw d'2' ; clock = 4/(4*(2+1)) = 333kHz
movwf SSPADD ; für I2C
bcf STATUS, RP0 ; Bank 0
movlw B'00001000' ; master mode, clock=Fosc/(4*(SSPADD+1))
movwf SSPCON ;
bsf SSPCON, SSPEN ; MSSP-Modul enable

goto main
; rdy with initing::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::
; General routines:::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::
; delay 1sec::
WAIT
top1 movlw .110 ; timing adjustment variable (1ms)
movwf loops2
top21 nop ; sit and wait
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop

decfsz loops2, F ; inner loops complete?
goto top21 ; no, go again

decfsz loops, F ; outer loops complete?
goto top1 ; no, go again
retlw 0 ; yes, return from subWAIT


; I2C routines:::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::
; bus übernehmen::
i2c_takeover bcf PIR1, SSPIF ; SSPIF Bit löschen
bsf STATUS, RP0
bsf SSPCON2, SEN ; Bus Übernahme anweisen
bcf STATUS, RP0

i2c_t1 btfss PIR1, SSPIF ; Testen, ob Bus schon übernommen wurde
goto i2c_t1 ; nein, noch nicht
bcf PIR1, SSPIF ; ja, der Bus ist mein! nun noch SSPIF zurücksetzen
return

; w senden an adresse1::
i2c_sendw1 movwf temp
movfw adresse1
movwf SSPBUF ; -> zum I2C-Slave übertragen

i2c_t2 btfss PIR1, SSPIF ; ACK schon empfangen?
goto i2c_t2 ; nein, noch nicht
bcf PIR1, SSPIF ; ja, Daten sind im Slave, nun noch SSPIF zurücksetzen

movfw temp
movwf SSPBUF ; -> zum I2C-Slave übertragen

i2c_t3 btfss PIR1, SSPIF ; ACK schon empfangen?
goto i2c_t3 ; nein, noch nicht
bcf PIR1, SSPIF ; ja, Daten sind im Slave, nun noch SSPIF zurücksetzen
return


; bus freigeben::
i2c_free bsf STATUS, RP0
bsf SSPCON2, PEN ; Bus Freigabe anweisen
bcf STATUS, RP0

i2c_t6 btfss PIR1, SSPIF ; Bus schon freigegeben?
goto i2c_t6 ; nein, noch nicht
bcf PIR1, SSPIF ; ja, alles fertig, nun noch SSPIF zurücksetzen
return
;:::::::::::::::::::::::main program::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::::::::::::::::::..
;::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::....
main
clrf PORTB
call WAIT
call WAIT
call i2c_takeover
bsf PORTB, 0
movlw b'11111111'
call i2c_sendw1
bsf PORTB, 1
call i2c_free
bsf PORTB, 2
call WAIT
call WAIT
bsf PORTB, 3
call i2c_takeover

movlw b'00000000'
call i2c_sendw1
call i2c_free
goto main

end


Slave:



#include <P16f877.INC>
__CONFIG _PWRTE_ON & _WDT_OFF & _HS_OSC & _LVP_OFF & _BODEN_OFF

adresse1 EQU 0x26 ; Variablen Declarieren ;)
adresse2 EQU 0x27
loops EQU 0x28
loops2 EQU 0x29
s_copy EQU 0x2A
w_copy EQU 0x2B
temp EQU 0x2C


; reicht vorerst an vars will ja nix übertreibn
org 0
goto init


org 4 ; Interruptvector

intvec bcf INTCON, GIE ; disable Interupt
movwf w_copy ; w retten
swapf STATUS, w ; STATUS retten
movwf s_copy ;



; Intrupt servic routine
Int_serv

call receivedata
swapf s_copy, w ; STATUS zurück
movwf STATUS
swapf w_copy, f ; w zurück mit flags
swapf w_copy, w

bcf INTCON, T0IF ; Interupt-Flag löschen
bsf INTCON, GIE ; enable Interupt
retfie


receivedata bsf STATUS, RP0 ; Bank1
btfss SSPSTAT, BF
goto receivedata

movfw SSPBUF
movwf PORTB
bcf STATUS, RP0 ; Bank 0
bcf PIR1, SSPIF

return



; init the I2C stuff::::::::::::::::::::::::::::::::::::::::::::: :::::::
init
bsf STATUS, RP0 ; Bank1
movlw B'00011000' ; trisc 2+3 inputs für i2c
movwf TRISC ;
movlw B'00000000' ; trisd outputs für servos
movwf TRISD ;

movlw B'00000000' ; trisb outputs für LEDs und Relais
movwf TRISB ;

movlw d'01001000' ; adress
movwf SSPADD ; für I2C
bcf STATUS, RP0 ; Bank 0
clrf PORTB
clrf PORTD
movlw B'00001100' ; slave mode
movwf SSPCON ;
bsf SSPCON, SSPEN ; MSSP-Modul enable
bsf INTCON, GIE ; Interupt erlauben
goto main
; rdy with initing::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::



;:::::::::::::::::::::::main program::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::::::::::::::::::..
;::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::....
main
nop

goto main

end


Vielen dank im voraus ich weiss is n haufn arbeit son code durchzugehn aber ich wär euch echt dankbar!
mfg.
m0

m0
05.08.2005, 09:23
Hi!
also hab mal weitergetestet und bin zum ergebnis gekommen dass kein adressmatch occured d.h.: der slave fohlt sich netmal angesprochen und gibt auch kein ACK ... woran könnte das liegen? ist hier keiner der sone I2C sache zum laufen gebracht hat und helfen kann (z.b.: mit codeschnipseln oder so) würde mich echt riesig freuen weil ich weis mir keinen rat mehr... test jetzt schon seit ewigkeiten rum und komm einfach zu keinem ergebnis...

VIelen Dank
m0