I2C driver using bit bang help

lamxe

Senior Member
Code:
2C driver using bit bang. This can be used with any microcontroller which has 2 GPIO lines which can be configured as input/output

typedef struct 
{
  unsigned int PIN0:1;
  unsigned int PIN1:1;
  unsigned int PIN2:1;
  unsigned int PIN3:1;
  unsigned int PIN4:1;
  unsigned int PIN5:1;
  unsigned int PIN6:1;
  unsigned int PIN7:1;
} PORT;

/* TODO: Example address shown, but the proper address */
#define PORT0 *(volatile PORT *)0x1234

/* Define the port used for I2C data and clk as shown above to access them pin wise */
#define I2C_DATA PORT0.PIN0
#define I2C_CLK  PORT0.PIN1

#define HIGH 1
#define LOW  0

/* I2C Start - bit bang */
void I2C_START(void)
{
    /* I2C Start condition, data line goes low when clock is high */
    I2C_DATA = HIGH;
    I2C_CLK = HIGH;
    I2C_DATA = LOW;
    I2C_CLK = LOW;
}

/* I2C Stop - bit bang */
void I2C_STOP (void)
{
    /* I2C Stop condition, clock goes high when data is low */
    I2C_CLK = LOW;
    I2C_DATA = LOW;
    I2C_CLK = HIGH;
    I2C_DATA = HIGH;
}

/* I2C Write - bit bang */
void I2C_WRITE(unsigned char data)
{
	unsigned char outBits;
	unsigned char inBit;
	
 	/* 8 bits */
	for(outBits = 0; outBits < 8; outBits++) 
	{
	    if(data & 0x80)
		    I2C_DATA = 1;
		else
		    I2C_DATA = 0;
      	data  <<= 1;
		/* Generate clock for 8 data bits */
		SCLK = HIGH;
		SCLK = LOW;					
	}
	
	/* Generate clock for ACK */
	I2C_CLK = HIGH;
        /* Wait for clock to go high, clock stretching */
        while(I2C_CLK);
        /* Clock high, valid ACK */
	inBit = I2C_DATA;
	I2C_CLK = LOW;					
}

unsigned char I2C_READ (void)
{
	unsigned char inData, inBits;

	inData = 0x00;
	/* 8 bits */
	for(inBits = 0; inBits < 8; inBits++)
	{
		inData <<= 1;
		I2C_CLK = HIGH;
      	inData |= I2C_DATA;
		I2C_CLK = LOW;					
	}

   return inData;
}

/* Examble for writing to I2C Slave */
void writeI2CSlave (unsigned char data)	
{
    /* Start */
  	I2C_START();
	/* Slave address */
   	I2C_WRITE(0xAA)
	/* Slave control byte */
   	I2C_WRITE(0xBB);
	/* Slave data */
   	I2C_WRITE(data);
	/* Stop */
   	I2C_STOP();
}

/* Examble for reading from I2C Slave */
unsigned char readI2CSlave(unsigned char data)
{
   	unsigned char inData;

	/* Start */
  	I2C_START(); 
	/* Slave address */
   	I2C_WRITE(0xAA);
	/* Slave control byte */
   	I2C_WRITE(data);
	/* Stop */
   	I2C_STOP();
	
	/* Start */
   	I2C_START();
	/* Slave address + read */
   	I2C_WRITE(0xAA | 1);
	/* Read */
	inData = I2C_READ();

   	return inData;                 
}
Dear All..
Please could you help me translate this code to Picaxe .And tell me have a software ( Sale or free and easy to use for newbie as me ) for converter to picaxe code. Many thank you in advance.
lamxe
 

inglewoodpete

Senior Member
Debugging bit-banged i2c code is serious work, even for an experienced programmer. Before someone puts a lot of work into your project, can you explain why you want to do this?

All current PICAXE chips have perfectly good i2c commands that work. Revolution Education has gone to a lot of trouble to develop and test the firmware code for i2c. Why don't you want to use it? Personally, as an experienced programmer, I would not think of writing my own i2c code for a PICAXE.
 

hippy

Ex-Staff (retired)
There are already some bit-banged I2C examples on the forum already -

http://www.picaxeforum.co.uk/showthread.php?16503

That is for an 08M but can be fairly easily rewritten for any PICAXE. I am not however sure if it's original code shown or edited.

That will do things better than simply porting the C code will. That C code forces I2C bus lines low or high where the safer technique is to emulate the open-collector nature of the I2C bus by setting the bus lines output low or input.
 

lamxe

Senior Member
Dear Sir Hippy and Sir Inglewoodpete
Many many thank you for your time support and advice me.
Sincerely Thank you again
 
Top