Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

some questions regarding i2c slave and master software

Status
Not open for further replies.

large_ghostman

Well-Known Member
Most Helpful Member
hi
i havnt actualy tried the following programs yet as ive been reading through the code to see how i will need to alter it for my needs if i decide to use i2c instead of spi after reading through the code there are some aspects that i dont understand why its done that way etc. before i show the code and explain my questions i will give a rundown of what i am doing


ok hi this is of course for my robot project and i know that if i realy try then i could come up with a way of just using one pic to do all i will need BUT i dont want to do it that way and i will get more points by doing it a different way so the plan is a master pic wich at present is a 18f4685 wich is boss and takes care of the LCD etc then i have planned to use a 18f1330 for motor control (it has good pwm modual) and line sensors and bump sensor (micro switchs) then i plan to use some along the lines of a 18fxxK22 for the metal detecting (circuit still not fully decided) and probaly for the laser addon. theese chips will need to talk to each other and at first i was going to use SPI (i have used it a couple of times) but i am now thinking of going I2C as i dont need realy realy fast speed and i like the 2line coms.also my BOT will have the abillity to have other addon boards plugged into the main board so the bot can do diffferent jobs. please dont tell me its all pointless to do it this way because i have a good reason for this approach the bot is a competition that some must do parts like the line following race and metal detecting and telling gold coloured metal from silver coloured metal and there is a part of the comp that will test how long the bot will run for on one charge/set of bats.
this is all must do parts
then there is other part of comp that your bot gets judged by my school pupils on things like looks and wow factor and abillity to do cool stuff (i goto a technology school) Okehampton. so my plan is to have a busy main board with plenty of bits and led indicators etc so it looks complicated and cool and rather than have all the stuff on one board i plan to have my addon boards laid out next to the bot for the judging with description and write up of each board again i am sure this will get extra points also my bot is the only bot in the competion that is completly home made all the others are now ones that were got from shops or ebay and just altered so the teacher judges will give me megga more points for that so i have decided to have a go at a I2C bus ive read loads of threads on here and seems no one is that keen on I2C slave pics i noticed that a couple of years ago mr nigle didnt think pic slaves were a good idea and I2C bus was best if you had I2C chips. so i am aware of the bad bits that mr nigle pointed out but i still think I2C would be cool
i found some Master and slave I2C code examples from microchip and they are the programs i have been studying but i am a bit unsure of the way they have made it work i am not going to use the code as is but before i mess with it i wanted to ask some questions so here is there code BTW there code is well comented

I2C MASTER PIC CODE

Code:
#define USE_OR_MASKS
#include <p18cxxx.h>
#include "i2c.h"

//-------------------------------Configuration setting ----------------------------------------------
/**
	* Oscillator is configured as HS
	* Fail safe monitor is enabled
	* watch dog timer is disabled
	* Extended instruction mode is disabled
	* oscillator switch over is enabled	
*/
#if defined(__18F4685)		//If the selected device if PIC18F4685, then apply below settings else user will have to set
#pragma config OSC=HS, FCMEN=ON, WDT=OFF, IESO=ON, XINST=OFF, LVP=OFF 
#endif


unsigned char I2C_Send[21] = "MICROCHIP:I2C_MASTER" ;
unsigned char I2C_Recv[21];

//************ I2C MASTER ****************************
void main(void)
{

unsigned char sync_mode=0, slew=0, add1,w,data,status,length;

for(w=0;w<20;w++)
I2C_Recv[w]=0;

add1=0xA2;		//address of the device (slave) under communication

	CloseI2C();	//close i2c if was operating earlier

//------------------------INITIALISE THE I2C MODULE FOR MASTER MODE WITH 100KHz ---------------------------
	sync_mode = MASTER;
	slew = SLEW_OFF;
  
	OpenI2C(sync_mode,slew);

SSPADD=0x0A;			 //400kHz Baud clock(9) @8MHz

//check for bus idle condition in multi master communication
	IdleI2C();
//--------------------START I2C---------------
	StartI2C();
	
//**************write the address of the device for communication************
		data = SSPBUF;		//read any previous stored content in buffer to clear buffer full status
	do
	{
	status = WriteI2C( add1 | 0x00 );	//write the address of slave
		if(status == -1)		//check if bus collision happened
		{
			data = SSPBUF;		//upon bus collision detection clear the buffer, 
			SSPCON1bits.WCOL=0;	// clear the bus collision status bit
		}
	}
	while(status!=0);		//write untill successful communication
//R/W BIT IS '0' FOR FURTHER WRITE TO SLAVE	
	
//***********WRITE THE THE DATA TO BE SENT FOR SLAVE****************
while(putsI2C(I2C_Send)!=0);	//write string of data to be transmitted to slave

//-------------TERMINATE COMMUNICATION FROM MASTER SIDE---------------
	IdleI2C();
		
//-----------------RESTART I2C COMMUNICATION---------------------------------------
	RestartI2C();
	IdleI2C();	
//**************write the address of the device for communication************
		data = SSPBUF;		//read any previous stored content in buffer to clear buffer full status

//R/W BIT IS '1' FOR READ FROM SLAVE		
add1 = 0xA2;
	do
	{
	status = WriteI2C( add1 | 0x01 );  //write the address of slave
		if(status == -1)		//check if bus collision happened
		{
			data = SSPBUF;		//upon bus collision detection clear the buffer, 
			SSPCON1bits.WCOL=0;	// clear the bus collision status bit
		}
	}
	while(status!=0);			//write untill successful communication
	
//******************* Recieve data from slave ******************************
	while( getsI2C(I2C_Recv,20) );		//recieve data string of lenght 20 from slave 
	I2C_Recv[20] = '\0' ;
		
		NotAckI2C();					//send the end of transmission signal through nack
		while( SSPCON2bits.ACKEN!=0);		//wait till ack sequence is complete	
		
//********************* close I2C *****************************************		
CloseI2C();								//close I2C module

while(1);						//End of program
}



I2C SLAVE


Code:
#if defined(__18F4685)		//If the selected device if PIC18F4685, then apply below settings else user will have to set
#pragma config OSC=HS, FCMEN=ON, WDT=OFF, IESO=ON, XINST=OFF, LVP=OFF 
#endif



unsigned char I2C_Send[21] = "MICROCHIP:I2C_SLAVE" ;
unsigned char I2C_Recv[21];

//************ I2C SLAVE ****************************************
void main(void)
{

unsigned char sync_mode=0, slew=0, add1,status,temp,w,length=0;

for(w=0;w<20;w++)
I2C_Recv[w]=0;

	CloseI2C();							//close i2c if was operating earlier

//------------------------INITIALISE THE I2C MODULE FOR MASTER MODE WITH 100KHz ---------------------------
	sync_mode = SLAVE_7;
	slew = SLEW_OFF;
  
	OpenI2C(sync_mode,slew);
	
SSPADD = 0xA2;							//initialze slave address
//********************* Read the address sent by master from buffer **************
		while(DataRdyI2C()==0);			//WAIT UNTILL THE DATA IS TRANSMITTED FROM master
		temp = ReadI2C();


//********************* Data reception from master by slave *********************
		
		do
		{
		while(DataRdyI2C()==0);			//WAIT UNTILL THE DATA IS TRANSMITTED FROM master
		I2C_Recv[length++]=getcI2C();       // save byte received
		}
		while(length!=20);
		
//******************** write sequence from slave *******************************
		while(SSPSTATbits.S!=1);		//wait untill STOP CONDITION

//********************* Read the address sent by master from buffer **************
		while(DataRdyI2C()==0);			//WAIT UNTILL THE DATA IS TRANSMITTED FROM master
		temp = ReadI2C();

//********************* Slave transmission ************************************		
	if(SSPSTAT & 0x04)					//check if master is ready for reception	
	while(putsI2C(I2C_Send));			// send the data to master

//-------------TERMINATE COMMUNICATION FROM MASTER SIDE---------------
	CloseI2C();							//close I2C module
	
	while(1);							//End of program
}

ok the questions

on the slave code look at this part

Code:
SSPADD = 0xA2;							//initialze slave address
//********************* Read the address sent by master from buffer **************
		while(DataRdyI2C()==0);			//WAIT UNTILL THE DATA IS TRANSMITTED FROM master
		temp = ReadI2C();


//********************* Data reception from master by slave *********************
		
		do
		{
		while(DataRdyI2C()==0);			//WAIT UNTILL THE DATA IS TRANSMITTED FROM master
		I2C_Recv[length++]=getcI2C();       // save byte received
		}
		while(length!=20);
		
//******************** write sequence from slave *******************************
		while(SSPSTATbits.S!=1);		//wait untill STOP CONDITION

//********************* Read the address sent by master from buffer **************
		while(DataRdyI2C()==0);			//WAIT UNTILL THE DATA IS TRANSMITTED FROM master
		temp = ReadI2C();
ok i see it sets its address at 0xA2 thats fine
it then reads from master and sends some data itself but nowhere can i see where it actualy checks to see if the information is for itself or another slave:confused::confused: surely somewhere after the first read it should chk to see if the address the master sends is for itself???

also why does it read the sent address at the very end instead of the beginning ????


then on the master side

Code:
//***********WRITE THE THE DATA TO BE SENT FOR SLAVE****************
while(putsI2C(I2C_Send)!=0);	//write string of data to be transmitted to slave

//-------------TERMINATE COMMUNICATION FROM MASTER SIDE---------------
	IdleI2C();
		
//-----------------RESTART I2C COMMUNICATION---------------------------------------
	RestartI2C();
	IdleI2C();	
//**************write the address of the device for communication************
		data = SSPBUF;		//read any previous stored content in buffer to clear buffer full status

why does it send data then idle the restart???
i have other questions but that will do for now :D
thank you

forgot to add that on main board is also a 18fxxk22 for doing nothing but flash leds under bot for diff reason and just doing fancy stuff to look cool no real purpose stuff ;)
 
Last edited:
SPI slave select question

hi ive messed with SPI using a master pic spi and a slave pic spi and it worked ok i know normaly you use a slave select line for more than one slave on the bus but i was wondering if you were just using pics as slaves and a master pic could you do away with slave select and just give the slaves adreeses in code so the master when it sends a command on the bus first sends a address then the command all the slaves read the address but only the one that matches the address would respond to the command? is this normaly done or is it ok to do it this way? i did ask questions on I2C as i was going to use that but i havnt had any replies yet so thought of this as a backup :D
lg
 
Bump!!!
 
i am not sure but i dont think addressing would work in SPI i can vaguely remember seeing a kind of circular transfer on the logic analyzer with SPI, from what i remember of it the slave sends data as it recieves it so if you had several they would all read the address and try and send something back to the master before they had processed who the information was for so i guess this would give you a bus collision. As you know tho i havnt done anything yet with I2C so cant help there.
Why not use a shift register on the master to controll the slave select lines? maybe someone else who knows more will have an answer if not i will ask on microchip for you on my day off this week
 
Hi LG... I have read both of your queries, but I haven't done anything with slaves on I2C. The SPI however.... I have helped on a post on this forum (I can't find it at the moment) but it had software programmable addressing, so Yes it is possible to do.

With the I2C question... All I can think of is that the slave reads all the data first... Stores it in a buffer then looks t see if it has to respond..

I write all my own I2C routines... But as I said, I've never done a slave device...

I think this is an advanced topic... Most people only use pre-made devices... I did read somewhere that Microchips Slave code in C18 was difficult to get running.
 
Status
Not open for further replies.

Latest threads

Back
Top