allkhush
Newbie level 3
- Joined
- Apr 6, 2012
- Messages
- 4
- Helped
- 0
- Reputation
- 0
- Reaction score
- 0
- Trophy points
- 1,281
- Activity points
- 1,321
Hi there,
I have been working on pic16F877A for a while, and I found that there is some problem with its MSSP module when used in slave mode. My experiment is as follows-
I have atmega128 as master and PIC16F877A as slave. I want slave to transmit few bytes to master on request and interpret(switch on/off set of loads) a byte while in WRITE mode. After initializing the I2C in both the devices, I see that master is doing its work perfectly fine, but the slave doesn't seem to receive anything as it's SSPIF flag doesn't get set which then calls ISR. This, I verified by manually setting SSPIF, and printing a character through UARTwriteChar in ISR, works fine.
I am trying to write a character 'c' (actually random byte) via I2C from master to slave continuously as long as it gets the ACK from slave, i.e. when I2C lines are removed master stops writing.
So, either slave is not receiving anything which is not true since its ACK is sent, Or it receives the data and sends the ACK but there is problem with setting the SSPIF flag after receiving data.
Is there a problem with the internal settings of PIC16 related to I2C or am I missing something important?
Following are the codes-
Any kind of help is appreciated.
I have been working on pic16F877A for a while, and I found that there is some problem with its MSSP module when used in slave mode. My experiment is as follows-
I have atmega128 as master and PIC16F877A as slave. I want slave to transmit few bytes to master on request and interpret(switch on/off set of loads) a byte while in WRITE mode. After initializing the I2C in both the devices, I see that master is doing its work perfectly fine, but the slave doesn't seem to receive anything as it's SSPIF flag doesn't get set which then calls ISR. This, I verified by manually setting SSPIF, and printing a character through UARTwriteChar in ISR, works fine.
I am trying to write a character 'c' (actually random byte) via I2C from master to slave continuously as long as it gets the ACK from slave, i.e. when I2C lines are removed master stops writing.
So, either slave is not receiving anything which is not true since its ACK is sent, Or it receives the data and sends the ACK but there is problem with setting the SSPIF flag after receiving data.
Is there a problem with the internal settings of PIC16 related to I2C or am I missing something important?
Following are the codes-
Code C - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 void I2C_INIT(void) { TRISCbits.TRISC3 = 1; /* SDA and SCL as input pin */ TRISCbits.TRISC4 = 1; /* these pins can be configured either i/p or o/p */ SSPCON1bits.SSPM3 = 0; SSPCON1bits.SSPM2 = 1; // SLAVE mode with 7bit address SSPCON1bits.SSPM1 = 1; SSPCON1bits.SSPM0 = 0; SSPSTATbits.SMP = 0; // Slew rate set to NORMAL/STANDARD speed @ 100kHz SSPADD = I2C_ADDR; // SLAVE address is (7bit). Lsb is R/W flag bit SSPSTATbits.CKE = 0; // Disable SMBus SSPCON1bits.SSPEN = 1; // Enable I2C Master port SSPCON1bits.SSPOV = 0; // Clear Buffer Overflow SSPCON1bits.CKP = 1; // Clock Released SSPCON2bits.SEN = 1; // Clock stretching is enabled INTCONbits.PEIE = 1; // Enable peripheral interrupts INTCONbits.GIE = 1; // Enable global interrupts PIR1bits.SSPIF = 0; // reset MSSP interrupt flag bit PIE1bits.SSPIE = 1; // Enable serial port interrupts BCLIF = 0; // Clear the bus collision interrupt flag BCLIE = 1; // Enable bus collision interrupts } void interrupt ISR(void) { if(SSPIF) { USARTWriteChar('a'); if(!SSPSTATbits.R_nW) // read or write can be known from lsb of ADDRESS BYTE { if(SSPSTATbits.D_nA) { CommandByte = SSPBUF; // get data USARTWriteChar('('); OBCcommandresponse(); //USARTWriteChar(CommandByte); USARTWriteChar(')'); } if(!SSPSTATbits.D_nA) { USARTWriteChar('<'); sendHM_data(); USARTWriteChar('>'); } } } if (BCLIF) // Did a bus collision occur? usually in master mode { crap = SSPBUF; // dummy read SSPBUF to clear BF bit BCLIF = 0; // clear bus collision Int Flag bit SSPCONbits.CKP = 1; // Release CLK } SSPIF = 0; } void main() { USARTInit(9600); USARTWriteChar('b'); I2C_INIT(); //SSPIF = 1; while(1) { } }
Any kind of help is appreciated.
Last edited by a moderator: