Probleme mit PIC16F876 als Slave

01/04/2015 - 18:43 von Christian Müller | Report spam
Hallo NG,

seit einigen Tagen mache ich nichts anderes, als ein I2C-Slave in einen
PIC16F876 zu implementieren, aber es will mir einfach nicht so recht
gelingen. Ich habe schon bei uC.net gepostet, aber nicht geholfen bekommen,
darum frage ich hier. Die Probleme habe ich schon dort geschildert:
http://www.mikrocontroller.net/topic/362605#new
Es geht im Prinzip darum, eine vorhandene Hardware, in der der PIC vorher
Master war, als Slave zu verwenden. Ich verwende noch 3 weitere Slaves,
alles PCF8574, die funktionieren gut. Wenn es nicht geht, frickle ich dann
einen PCF8574 in den PIC-Sockel.

Es scheint, dass jegliche Aktivitàt auf dem Bus die Daten im SSPBUF
veràndert, auch in den Zwischenvariablen lies1, lies und lesen, jedenfalls
wirkt sich das so aus. Und nur, wenn Aktivitàt auf dem Bus (irgendwo
zwischen Start und Stop) habe ich verànderte Date. Konkret bekomme ich die
ZU SENDENDEN Daten in die EMPFANGENEN. Leider hilft der Zwischenspeicher
nicht dabei, wenn an und von ALLEN PCF kommuniziert wird.

Compiler ist microBASIC von MikroE. Habe nur Beispiele in C gefunden und
adaptiert. unterdessen verstehe ich sogar, was passiert...

Aktueller Code:

dim rdummy, wdummy, I2CAdresse, schreiben, schrei, lesen, lies as byte
dim schrei1, lies1 as byte

sub procedure interrupt
if SSPSTAT.R_W = 0 then 'Read/-Write = Read (Master -> Slave)
if SSPSTAT.D_A = 0 then 'Data/-Address = Address
rdummy = SSPBUF 'Dummy-Read
SSPSTAT.BF = 0 'Flag Buffer-Full loeschen
SSPCON.CKP = 1 'Clockstretching erlauben
PIR1.SSPIF = 0 'SSP-Interrupt-Flag wieder loeschen
'return
else
'Hier werden die empfangenen Daten ausgelesen:
lesen = SSPBUF 'Datenbyte von SSPBUF lesen und in Variable
einlesen
SSPCON.CKP = 1 'Clockstretching erlauben
PIR1.SSPIF = 0 'SSP-Interrupt-Flag wieder loeschen
'return
end if
else 'Read/-Write = Write (Slave -> Master)
if SSPSTAT.D_A = 0 then 'Data/-Address = Address
'Hier werden die zu sendenden Daten ins SSPBUF geschrieben:
SSPBUF = schreiben 'Datenbyte von Variablen lesen und in SSPBUF
schreiben
SSPCON.CKP = 1 'Clockstretching erlauben
PIR1.SSPIF = 0 'SSP-Interrupt-Flag wieder loeschen
'return
else
SSPBUF = wdummy 'Dummy-Write, mit anderer Variable
SSPCON.CKP = 1 'Clockstretching erlauben
PIR1.SSPIF = 0 'SSP-Interrupt-Flag wieder loeschen
'return
end if
end if
end sub

main:
OPTION_REG = %10000000 'Bit7: 1 = PORTB pull-ups are disabled
TMR0 = 0
INTCON = %00000000 'Disable alle Interrupts
TRISC = %01111111 '1 = Input, 0 = Output
'Bit0:
'Bit1:
'Bit2:
'Bit3: SCL
'Bit4: SDA
'Bit5:
'Bit6: TX
'Bit7: (RX) Servo
'PORTC = %00000000
ADCON1 = %00000110 'PortA auf digitale Eingànge schalten
TRISA = %00111111 'Bit0:
'Bit1:
'Bit2:
'Bit3:
'Bit4:
'Bit5:
'Bit6,7: nicht vorhanden
PORTA = 0
TRISB = %11011001 'Bit0:
'Bit1: Pumpe ein
'Bit2: EV ein
'Bit3: Pumpenüberwachung
'Bit4:
'Bit5: Kontroll-LED
'Bit6,7: Programmierstecker
PORTB = 0

schreiben = 0
schrei = 0
schrei1 = 0
lesen = 0
lies = 0
lies1 = 0

'I2C-Hardware-Modul als Slave konfigurieren
SSPCON = %00110110 'Sync Serial Port Control Register 1
SSPCON2 = %00110110 'Sync Serial Port Control Register 2
SSPSTAT = %10000000

'I2C Slave Adresse in SSPADD schreiben
'Hier 0 A5 A4 A3 A2 A1 A0 R/-W
I2CAdresse = %01000110 'hier steht die Slave Adresse
SSPADD = I2CAdresse

'Interrupt freigeben
PIE1 = %00001000 'Peripheral Interrupt Enable Register 1
(Bank 1)
INTCON = %11000000 'Interrupt-Control-Register (Bank 1)

while TRUE
'Lesen
lies1 = lies
lies = lesen 'Variable an die Hilfsvariable übergeben
if lies = lies1 then
'PORTB.5 = lies.3 'Kontroll LED
PORTB.1 = lies.4 'Pumpe ein
PORTB.2 = lies.5 'EV ein
PORTC.7 = lies.6 'Servo ein
end if

if PORTB.1 = 1 then
PORTB.1 = 0
else
PORTB.1 = 1
end if
'Schreiben
'Pegel
schrei = 7 'Fass voll, alle Geber (1-6) ein (Logisch
0)
If PORTC.0 = 0 then
schrei = 5 'Geber 1-5 ein
end if
If PORTA.5 = 0 then
schrei = 4 'Geber 1-4 ein
end if
If PORTA.3 = 0 then
schrei = 3 'Geber 1-3 ein
end if
If PORTA.2 = 0 then
schrei = 2 'Geber 1-2 ein
end if
If PORTA.1 = 0 then
schrei = 1 'Geber 1 ein
end if
If PORTA.0 = 0 then 'Fass leer
schrei = 0 'Geber 1 aus (logisch 1)
end if

schrei.4 = PORTB.3 'Pumpenüberwachung
schreiben = schrei 'Hilfsvariable an die Variable übergeben

Delay_ms(90) 'Warten
wend
end.


Gruss Chregu

@Jörg: Es dürfen auch ICs für >$1 verwendet werden
Michael Eggert in de.sci.electronics
 

Lesen sie die antworten

#1 Hans-Jürgen Schneider
02/04/2015 - 09:11 | Warnen spam
"Christian Müller" schrieb:

seit einigen Tagen mache ich nichts anderes, als ein I2C-Slave in einen
PIC16F876 zu implementieren,

Konkret bekomme ich die
ZU SENDENDEN Daten in die EMPFANGENEN.



Möglicherweise kümmert sich Dein Basic nicht automatisch um TRISC
beim Wechsel zwischen lesen und schreiben.

MfG
hjs

Ähnliche fragen