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]
Hier der Slavecode [16F883]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.
Nun das Problem: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; } }
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 debugenSo 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?)







Zitieren


Lesezeichen