Hi,
Use a PIC16F15324 as an I2C slave in FC10
Current project has some tricky little tasks that need constant attension, this is a sledgehammer approach but I'm thinking about using the feature rich but small PIC16F15324 to do the dedicated work and just read the data out over i2C with the main PIC18F.
Has anyone else tried this approach? I've not done a i2C slave before and any obvious traps or examples would be welcome.
I want to avoid a rabbit hole playing with i2C slaves....but it could become a super flexible codeable periferal for this and other projects.
Thanks, J.
PIC16F as i2C Slave - Begineer
-
- Posts: 215
- http://meble-kuchenne.info.pl
- Joined: Sun Dec 20, 2020 6:06 pm
- Has thanked: 81 times
- Been thanked: 56 times
-
- Valued Contributor
- Posts: 1512
- Joined: Wed Dec 09, 2020 9:37 pm
- Has thanked: 138 times
- Been thanked: 725 times
Re: PIC16F as i2C Slave - Begineer
An i2c slave probably needs to be interrupt driven.
See - https://flowcode.co.uk/forums/viewtopic ... 285#p16285 - although this thread is for ATMega MCUs, I think the general principals will be the same.
Basically to ensure correct timing - it is difficult to busy-wait on a i2c transaction being received.
Martin
See - https://flowcode.co.uk/forums/viewtopic ... 285#p16285 - although this thread is for ATMega MCUs, I think the general principals will be the same.
Basically to ensure correct timing - it is difficult to busy-wait on a i2c transaction being received.
Martin
-
- Valued Contributor
- Posts: 1574
- Joined: Thu Dec 03, 2020 10:57 am
- Has thanked: 356 times
- Been thanked: 560 times
Re: PIC16F as i2C Slave - Begineer
Hi
I have no access to hardware just noe so can't really try anything but a year or so ago I did get slightly involved on a slave project.
The chip I used was a PIC and it had an inbuilt Interrupt on I2C (if I remember correctly) which could be selected.
This made things quite easy - ish.
Won't be able to dig out the project anytime soon, but depending on your chip capabilities it should be quite doable.
Regards
I have no access to hardware just noe so can't really try anything but a year or so ago I did get slightly involved on a slave project.
The chip I used was a PIC and it had an inbuilt Interrupt on I2C (if I remember correctly) which could be selected.
This made things quite easy - ish.
Won't be able to dig out the project anytime soon, but depending on your chip capabilities it should be quite doable.
Regards
Re: PIC16F as i2C Slave - Begineer
Hi,
I've been trawling the datasheets and trying to examine the C from the i2C slave component. I've probably just got confused.
A) The PIC16F15324 used does have a dedicated i2C periferal with slave support, I would love to use the interupt driven features at some point but I am currently just trying to get a basic level of i2C comms.
The channel is set to 1. The Pins are re-mapped correctly. (I'm fairly sure)
B) What seemed odd, when i read the FC Slave 'C' for the Slave Status function, it refers to register "SSPSTAT" for channel 1, the chip only responds to the register name given in the datasheet of SSP1STAT. Indeed most of the FC 'C' register names dont seem to have exacly the same names as the Datasheet. Is this just becuase the 'C' is generic across lots of PICs and a Cal file or similar sorts out the correct naming? to SSP1STAT
C) I dont really know the correct way to apply the existing slave component so its mostly guess work. The attached FC is suppossed to be reciving the address and two bytes of data.
I never seem to be able to read a TRUE BufferFull bit for the i2C_Status byte. But I see the register SSP1STAT toggle its BF bit on/off. D) I was unsure what was set in the registers so I read out everything associated with i2C and send them to a Terminal program and display them as bits, MSB to the left.
I've been trawling the datasheets and trying to examine the C from the i2C slave component. I've probably just got confused.
A) The PIC16F15324 used does have a dedicated i2C periferal with slave support, I would love to use the interupt driven features at some point but I am currently just trying to get a basic level of i2C comms.
The channel is set to 1. The Pins are re-mapped correctly. (I'm fairly sure)
B) What seemed odd, when i read the FC Slave 'C' for the Slave Status function, it refers to register "SSPSTAT" for channel 1, the chip only responds to the register name given in the datasheet of SSP1STAT. Indeed most of the FC 'C' register names dont seem to have exacly the same names as the Datasheet. Is this just becuase the 'C' is generic across lots of PICs and a Cal file or similar sorts out the correct naming? to SSP1STAT
C) I dont really know the correct way to apply the existing slave component so its mostly guess work. The attached FC is suppossed to be reciving the address and two bytes of data.
I never seem to be able to read a TRUE BufferFull bit for the i2C_Status byte. But I see the register SSP1STAT toggle its BF bit on/off. D) I was unsure what was set in the registers so I read out everything associated with i2C and send them to a Terminal program and display them as bits, MSB to the left.
-
- Valued Contributor
- Posts: 1512
- Joined: Wed Dec 09, 2020 9:37 pm
- Has thanked: 138 times
- Been thanked: 725 times
Re: PIC16F as i2C Slave - Begineer
Looks like the chip has a MSSP module.
Use an interrupt (here in C) something like...
As with the AVR it's a bit involved....
Martin
Code: Select all
SSP1STATbits.SMP = 1; // Slew rate control disabled
SSP1CON1bits.SSPM = 0x06; // Set to Slave mode, 7-bit address
SSP1CON1bits.SSPEN = 1; // Enable I2C module
SSP1CON1bits.CKP = 1; // Release SCL clock
SSP1ADD = SLAVE_ADDRESS; // Set the slave address
Code: Select all
if (SSP1IF) { // Check if the interrupt is from the SSP1 module
uint8_t received_data;
// Check if it's a read or write operation
if (SSP1STATbits.D_A) { // If D_A is 1, it's a data address (write)
// Write operation
received_data = SSP1BUF; // Read the received data
i2c_data = received_data; // Store data in buffer
SSP1IF = 0; // Clear interrupt flag
}
else { // It's a read operation
// Read operation, send data back to the master
SSP1BUF = i2c_buffer; // Write data to be sent to master
SSP1IF = 0; // Clear interrupt flag
}
}
Martin
Re: PIC16F as i2C Slave - Begineer
OK, so I have gone back to check the basics. Great info from Martin but I'm not attempting the Interupt approach yet, until I can understand the possible issue with the standard i2C Slave component.
If I use the FC i2C Slave component to retrive the SSP1STAT register and put it in variable i2C_Status, I cant read out values for the (BF) BufferFull bit.
However If I directly read the Register into my own variable.
then
I now read what look like good Values for BF and Last.
So is this a bug or am I doing something I dont understand?
J.
If I use the FC i2C Slave component to retrive the SSP1STAT register and put it in variable i2C_Status, I cant read out values for the (BF) BufferFull bit.
Code: Select all
i2C_BF = i2C_Status AND 0x01
i2C_Last = (i2C_Status AND 0x10) >> 4
Code: Select all
FCV_REG1 = SSP1STAT;
Code: Select all
i2C_BF = Reg1 AND 0x01
i2C_Last = (Reg1 AND 0x10) >> 4
So is this a bug or am I doing something I dont understand?
J.
Re: PIC16F as i2C Slave - Begineer
So looking sat the PIC i2C CAL C, whilst i dont understand it , the Code handles the different naming conventions.
Just cant work out why calling the same register values gives a different outcome... must be something dumb I'm doing.
Code: Select all
//Ensure SSPSTAT register is defined correctly
#ifndef _SSPSTAT_BF_POSN
#ifdef _SSP1STAT_BF_POSN
#define SSPSTAT SSP1STAT
#ifdef _SSP1STAT_R_nW_POSN
#define SSPSTAT_R_NOT_W R_nW
#else
#define SSPSTAT_R_NOT_W R_NOT_W
#endif