Hi zusammen,
Zur Zeit versuche ich eine Kommunikation zwischen zwei uC hin zubekommen. Da es mein erstes I2C Projekt ist, habe ich den Code aus dem Internet kopiert und an meine PIC's angepasst. Original sind die Code's für den 16F876A.
Hier der Mastercode. [16F887]
Code:
// 16F887
const Slave_Addy = 0x69;
void send(unsigned short send_data){
I2C1_Init(100000);
I2C1_Start();
I2C1_Wr(Slave_Addy);
I2C1_Wr(send_data);
I2C1_Stop();
}
unsigned short read(){
unsigned short read_data;
I2C1_Init(100000);
I2C1_Start();
I2C1_Wr(Slave_Addy + 1);
read_data = I2C1_Rd(0);
delay_ms(100);
I2C1_Stop();
return read_data;
}
void main(){
ANSEL = 0;
ANSELH = 0;
TRISA = 0;
PORTA = 0b00001111;
TRISB = 0;
PORTB = 0;
PORTC = 255;
while (1) {
send(166);
PORTA != PORTA;
delay_ms(2000);
}
// Main program code place here.
// Use sub-routine "send" to send data to slave.
// Use "read" to read data from slave.
Hier der Slavecode [16F883]
Code:
// 16F883
//------------------------------------------------------------------------------
const Addy = 0x69; // set I2C device address
const Delay_Time = 250; // port check delay
//------------------------------------------------------------------------------
// Global Processing Variables
//------------------------------------------------------------------------------
unsigned short j; // just dummy for buffer read
unsigned short rxbuffer; //
unsigned short tx_data; //
//------------------------------------------------------------------------------
void Init(){
ANSEL = 0; // All ports set to digital
ANSELH = 0;
TRISA = 0; // Set PORTA as output
PORTA = 0;
TRISB = 0; // Set PORTB as output
PORTB = 0;
TRISC = 0b00011000; // Set PORTC as input
PORTC = 0;
SSPADD = Addy; // Get address (7bit). Lsb is read/write flag
SSPCON = 0x36; // Set to I2C slave with 7-bit address
PIE1.SSPIE = 1; // enable SSP interrupts
PIR1.SSPIF = 0;
SSPSTAT.R_W = 0;
SSPSTAT.BF = 1;
SSPSTAT.D_A = 0;
INTCON = 0xC0; // enable INTCON.GIE
}
//------------------------------------------------------------------------------
void interrupt(){ // I2C slave interrupt handler
if (PIR1.SSPIF == 1){ // I2C Interrupt
PIR1.SSPIF = 0; // reset SSP interrupt flag
RB7_bit = 1; // Nur zum Debugen
//transmit data to master
if (SSPSTAT.R_W == 1){ // Read request from master
SSPBUF = tx_data; // Get data to send
SSPCON.CKP = 1; // Release SCL line
j = SSPBUF;
RB6_bit = 1; // Nur zum Debugen
return;
}
if (SSPSTAT.BF == 0){ // all done,
j = SSPBUF; // Nothing in buffer so exit
RB5_bit = 1; // Nur zum Debugen
return;
}
//recieve data from master
if (SSPSTAT.D_A == 1){ // Data [not address]
rxbuffer = SSPBUF; // get data
j = SSPBUF; // read buffer to clear flag [address]
RB4_bit = 1; // Nur zum Debugen
return;
}
}
RB3_bit = 1; // Nur zum Debugen
j = SSPBUF; // read buffer to clear flag [address]
}
//------------------------------------------------------------------------------
void main(){
Init();
while(1){
PORTC = rxbuffer;
tx_data = 170;
Delay_ms(Delay_Time);
RB2_bit = 1;
}
}
Nun das Problem:
Der Master sendet den Wert "166" welche beim Slave nie wirklich ankommen. SDA bleibt nach diesem Versuch auf low.
Beim Slave setze ich die Ausgänge vom PORTB, um zu debugen So habe ich erkannt das ein Interrupt stattfinden, jedoch scheint mir das SSPSTAT.R_W bit fehlerhaft. Dieses Bit wird als "1" gelesen, als ob der Master vom Slave lesen will...will er aber nicht.
Habt ihr eine Idee warum es nicht funktioniert? Etwas Hilfe könnte ich gut gebrauchen
Ps. Ich programmiere in MikroC mit dem EasyPic7 Board. Die Kommunikation zwischen Master und Eeprom funktioniert. Pull-Ups sind auch drin und Verdrahtung habe ich geprüft. Ach ja, der Slave ist mit etwa 30cm Litzen zum Board verdrahtet (Problem?)
Lesezeichen