Pages

Tuesday, December 9, 2014

PIC16F877A I2C code Interfacing Library

Summary Of PIC16F877A:
======================
PIC16F877A is an 8 bit RISC microcontroller developed by Microchip. Only 35 assembly instructions are there for the microcontroller which makes it a better RISC controller with full functionalities.
The specifications are:
  • 20MHz maximum frequency.
  • 14.3KB of program memory.(can hold upto 8192 single word instructions)
  • 368 Bytes SRAM.
  • 256 EEPROM
  • 33 multiplexed I/O pins.
  • Eight 10 bit ADC channels.
  • 2 PWM.
  • 1 SPI & 1 I2C (MSSP works as either one at a time)
  • 1 USART
  • Two 8-bit timers & one 16-bit timer.
  • 2 Comparators 
What to Know before programming :
  • Uses MSSP(Master synchronous serial port) module.
  • Mode Supported
    • Master Mode
    • Multimaster mode
    • Slave mode
  • Addressing Supported
    • 7 - bit
    • 10 - bit
  • Registers used:
    • MSSP Control Register (SSPCON)
    • MSSP Control Register 2 (SSPCON2)
    • MSSP Status Register (SSPSTAT)
    • Serial Receive/Transmit Buffer Register(SSPBUF)
    • MSSP Shift Register (SSPSR) – Not directly accessible
    • MSSP Address Register (SSPADD)
      • slave mode - slave address
      • master mode - lower 7 bits acts as baud rate generator reload value.


Summary to develop code:
======================
You can use MPLAB IDE for the development. Assembly programming can be done using the IDE, but c coding requires additional compilers like MPLAB C and HI-TECH compilers. Now Microchip integrated the above two and made a new compiler named as MPLAB XC Compiler. There the free compiler is having lesser optimization (Only 25% compared to the PRO paid version). Means the level of code compression(which requires lesser ROM space) and accurate delay may have the difference. 


Master mode coding:
===========================
Please add i2c.c file in your c file containing the main function and use the code.

i2c.h
=======


void i2c_init();
void i2c_waitForIdle();
void i2c_start();
void i2c_repStart();
void i2c_stop();
unsigned char i2c_read( unsigned char ack);
unsigned char i2c_write( unsigned char i2cWriteData);

i2c.c
=====
/*
PIC16F877A Code for i2c in master mode.
Developed By Arun Chettoor
Can be used freely in any project under GPL license.
E-mail : arunkrishnanc@gmail.com
*/


#include"i2c.h"

#define clockFreq 10 //in MHz
#define i2cClock 0 // 0 for 100KHz and 1 for 400KHz

void i2c_init(){
char i2cFreq;
TRISC3=1;           // set SCL and SDA pins as inputs
  TRISC4=1;

  SSPCON = 0x38;      // set I2C master mode
  SSPCON2 = 0x00;

  #if i2cClock==0
  i2cFreq=100;
  #else
  i2cFreq=400;
  #endif

  SSPADD = (char)(((clockFreq*1000)/i2cFreq)-1);

  PSPIF=0;      // clear SSPIF interrupt flag
  BCLIF=0;      // clear bus collision flag
}

/*********************************************
To wait until i2c is idle.
*********************************************/

void i2c_waitForIdle()
{
 while (( SSPCON2 & 0x1F ) | STAT_RW ) {}; // wait for idle and not writing
}

/********************************************
To sent the start sequence
**********************************************/

void i2c_start()
{
 i2c_waitForIdle();
 SEN=1;
}

/*********************************************
To sent a repeated start sequence
*********************************************/

void i2c_repStart()
{
 i2c_waitForIdle();
 RSEN=1;
}

/*********************************************
To sent a stop sequence
**********************************************/

void i2c_stop()
{
 i2c_waitForIdle();
 PEN=1;
}

/*********************************************
Read char from i2c buffer register and return the value
*********************************************/

unsigned char i2c_read( unsigned char ack )
{
 unsigned char i2cReadData;

 i2c_waitForIdle();

 RCEN=1;

 i2c_waitForIdle();

 i2cReadData = SSPBUF;

 i2c_waitForIdle();

 if ( ack )
  {
  ACKDT=0;
  }
 else
  {
  ACKDT=1;
  }
  ACKEN=1;               // send acknowledge sequence

 return( i2cReadData );
}

/*********************************************
Write char data to i2c buffer

*********************************************/

unsigned char i2c_write( unsigned char i2cWriteData )
{
 i2c_waitForIdle();
 SSPBUF = i2cWriteData;
 i2c_waitForIdle();
 return ( ! ACKSTAT  ); // function returns '1' if transmission is acknowledged
}

No comments:

Post a Comment