Thứ Sáu, 2 tháng 11, 2012

Software I2C for PIC Microcontroller

Nowadays, the most of PIC microcontroller was supported  I2C communication interface. But, if your the microcontroller just has one I2C, and you want two or more I2C interface, I think the software I2C solution will the best selection. It's highly flexible. You can chose any pins of your the microcontroller to use for I2C.

This's my library software I2C, it's very simple to use and modified. I hope it will useful for you.


This's file software_i2c.h:


/**********************************************************
* Software I2C for PIC16F887 in master mode
*
* Complier: HT PIC
* Author: Truong Cong Tri
***********************************************************
* LIST FUNCTIONS
*
* soft_i2c_start() - issue start condition
* soft_i2c_stop() - issue stop condition
* soft_i2c_write() - send byte data
* soft_i2c_read(ack) - read byte data: ack=0 -> NACK, ack=1 -> ACK
*
*---------------------------------------------------------*/
#ifndef _SOFTWARE_I2C_H_
#define _SOFTWARE_I2C_H_
//define IO pin for i2c communicate
#define SCL_PIN RC0
#define SDA_PIN RC1
#define SCL_TRIS TRISC0
#define SDA_TRIS TRISC1
void soft_i2c_start();
void soft_i2c_stop();
unsigned char soft_i2c_read(unsigned char ack);
//ack = 1 -> send not ack signal (NACK)
//ack = 0 -> send ack signal (ACK)
void soft_i2c_write(unsigned char data_send);
#endif



This's file software_i2c.c:

/**********************************************************
* Software I2C for PIC16F887 in master mode
*
* Complier: HT PIC
* Author: Truong Cong Tri
***********************************************************
* LIST FUNCTIONS
*
* soft_i2c_start() - issue start condition
* soft_i2c_stop() - issue stop condition
* soft_i2c_write() - send byte data
* soft_i2c_read(ack) - read byte data: ack=0 -> NACK, ack=1 -> ACK
*
*---------------------------------------------------------*/
#include <pic.h>
#include "software_i2c.h"

//=========================================================
// Soft I2C Start
//=========================================================
void soft_i2c_start()
{
SDA_TRIS=0;
SDA_TRIS=0;
SDA_PIN=1;
SCL_PIN=1;
SDA_PIN=0;
SCL_PIN=0;
}
//---------------------------------------------------------

//=========================================================
// Soft I2C Stop
//=========================================================
void soft_i2c_stop()
{ SDA_TRIS=0;
SCL_TRIS=0;
SDA_PIN=0;
SCL_PIN=1;
SDA_PIN=1;
}
//---------------------------------------------------------

//=========================================================
// I2C write
//=========================================================
void soft_i2c_write(unsigned char data_send)
{
unsigned char i;
SDA_TRIS=0;
SCL_TRIS=0;
for(i=0;i<=8;i++)
{
if(data_send & 0x80) // MSB fist -> LSB last
SDA_PIN=1;
else
SDA_PIN=0;
SCL_PIN=1;
data_send <<=1;
SCL_PIN=0;
}
} //---------------------------------------------------------

//=========================================================
// Soft I2C read
//=========================================================
unsigned char soft_i2c_read(unsigned char ack)
{
unsigned char get_data,i;
SCL_PIN=0; SDA_TRIS=1; //set SDA_PIN as input
for(i=0;i<8;i++)
{
get_data<<=1;
SCL_PIN=1;
if(SDA_PIN)
get_data |=1;
SCL_PIN=0;
}
SDA_TRIS=0; //set SDA_PIN as output
if(ack)
SDA_PIN=1; //ack=1 -> send not ack signal (NACK)
else
SDA_PIN=0; //ack=0 -> send ack signal (ACK)
SCL_PIN=1;
SCL_PIN=0;
return get_data;
}
//--------------------------------------------------------- 

This's example, how to use it:




/**********************************************************
* Example Soft I2C
* Author: Truong Cong Tri
*
* MCU: PIC16F887
* Xtal: 4Mhz
**********************************************************/
#include <htc.h>
#include "software_i2c.h"

__CONFIG(FOSC_HS & WDTE_OFF & PWRTE_ON & MCLRE_ON & LVP_OFF & DEBUG_OFF &
BOREN_OFF & CP_ON & CPD_ON & FCMEN_OFF & IESO_OFF); //1st config. word
__CONFIG(BOR4V_BOR21V); //2nd config. word

#define _XTAL_FREQ 4000000 // XTAL 4MHz
//*********************************************************

void main()
{
unsigned char byte1=0, byte2=0;

ANSEL=0;
ANSELH=0;
TRISB=0;
PORTB=0;


soft_i2c_start(); //send start condition
soft_i2c_write(0xA0); //send address device + W (0)
soft_i2c_write(0x00); //send address registor
soft_i2c_write(0x55); //send 1-byte data
soft_i2c_write(0xAA); //send 1-byte data
soft_i2c_stop(); //send stop condition

__delay_ms(190);

soft_i2c_start(); //send start condition
soft_i2c_write(0xA0); //send address device + W (0)
soft_i2c_write(0x00); //send address registor
soft_i2c_start(); //send Re-start condition
soft_i2c_write(0xA1); //send address device + R (1)

byte1 = soft_i2c_read(0); //read 1-byte
byte2 = soft_i2c_read(1); //read 1-byte
soft_i2c_stop(); //send stop condition


while(1)
{
PORTB=byte1;
__delay_ms(190);

PORTB=byte2;
__delay_ms(190);
};
}

Or, you can download it at here: http://www.mediafire.com/?qvv12ak1nvzzal9
and this is project: http://www.mediafire.com/?7ztj268jlpbcqn5

2 nhận xét:

  1. Be sure to test this with a PIC without I2C master (eg 16F88), or not I2c (eg, 16f628 i2c), with a PIC 16f887, the code that actually does not need this, just replace PIN SDA and SCL as well, I rely on and use this code with CCS but it does not run, including 887 always.

    Trả lờiXóa
    Trả lời
    1. I'm tested it with PIC16f887 (but I do not use hardware I2C of pic). the first, I write data to EEPROM, and then I read it and display in led

      Xóa