setting an i2c register to high

389 views Asked by At

I have this project that my boss asked me to do and the first step is to figure out how to set a given I2C register to high or low using the silicon lab library, if anyone knows any good sources for this type of problem please provide them thank you. The pic that I am using is the pic16f1823, I've already looked at the documentation of the pic but into only states how to read and write to an I2c.

1

There are 1 answers

0
imqqmi On

I use this as a header file and seems to work well for PIC16F1827 which is basically the same as the 1823. It used the peripheral of the PIC. Just include in in any c file you want to use i2c in. Make sure you #define FOSC in order to calculate the correct baud rate. Also double check the port and tris assignments are correct for your device and make adjustments.

It uses polling instead of an interrupt. Uncomment the interrupt setup code and write an interrupt service routine to catch the interrupts.

  #ifndef I2C_H
  #define   I2C_H

  #ifdef    __cplusplus
  extern "C" {
  #endif

  /*
   * Hi-Tech C I2C library for 12F1822
   * Master mode routines for I2C MSSP port to read and write to slave device 
   * Copyright (C)2011 HobbyTronics.co.uk 2011
   * Freely distributable.
  */

  #define I2C_WRITE 0
  #define I2C_READ 1

  // Initialise MSSP port. (12F1822 - other devices may differ)
  void i2c_Init(void){

      // Initialise I2C MSSP
      // Master 100KHz

      TRISB2 = 1;
      TRISB5 = 1;
      SSP1CON1 = 0b00101000; // I2C Master mode
      SSP1CON2 = 0b00000000; 
      SSP1CON3 = 0b00000000; 

      //SSP1MSK  = 0b00000000; 
      SSP1ADD  = I2C_BRG; // clock = FOSC/(4 * (SSPxADD+1))
      //SSP1IE = 1; // enable interrupt
      SSP1STAT = 0b10000000;
  }

  // i2c_Wait - wait for I2C transfer to finish
  void i2c_Wait(void){
      while ( ( SSP1CON2 & 0x1F ) || ( SSPSTAT & 0x04 ) );
  }

  // i2c_Start - Start I2C communication
  void i2c_Start(void)
  {
      i2c_Wait();
      SSP1CON2bits.SEN=1;
  }

  // i2c_Restart - Re-Start I2C communication
  void i2c_Restart(void){
      i2c_Wait();
      SSP1CON2bits.RSEN=1;
  }

  // i2c_Stop - Stop I2C communication
  void i2c_Stop(void)
  {
      i2c_Wait();
      SSP1CON2bits.PEN=1;
  }

  // i2c_Write - Sends one byte of data
  void i2c_Write(unsigned char data)
  {
      i2c_Wait();
      SSPBUF = data;
  }

  // i2c_Address - Sends Slave Address and Read/Write mode
  // mode is either I2C_WRITE or I2C_READ
  void i2c_Address(unsigned char address, unsigned char mode)
  {
      unsigned char l_address;

      l_address=address<<1;
      l_address+=mode;
      i2c_Wait();
      SSPBUF = l_address;
  }

  // i2c_Read - Reads a byte from Slave device
  unsigned char i2c_Read(unsigned char ack)
  {
      // Read data from slave
      // ack should be 1 if there is going to be more data read
      // ack should be 0 if this is the last byte of data read
      unsigned char i2cReadData;

      i2c_Wait();
      SSP1CON2bits.RCEN=1;
      i2c_Wait();
      i2cReadData = SSPBUF;
      i2c_Wait();
      if ( ack ) SSP1CON2bits.ACKDT=0;          // Ack
      else       SSP1CON2bits.ACKDT=1;          // NAck
      SSP1CON2bits.ACKEN=1;                    // send acknowledge sequence

      return( i2cReadData );
  }

  #ifdef    __cplusplus
  }
  #endif

  #endif    /* I2C_H */

Then you can use the higher level functions defined above to control a device, which is described in the datasheet of the slave device.

For example, to read from an eeprom:

  #include <xc.h>
  #define FOSC 16000000
  #include "i2c.h"

  unsigned char i2c_read_eeprom( unsigned char slaveaddress, unsigned char memaddress )
  {
      unsigned char data;

      data = 123;

      i2c_Start();
      i2c_Address( slaveaddress, I2C_WRITE);
      i2c_Write(memaddress);
      if( SSP1CON2bits.ACKSTAT )
           txstring("ACK!\r\n");
      else txstring("nACK!\r\n");

      i2c_Start();
      i2c_Address( slaveaddress, I2C_READ);
      data = i2c_Read(0);

      i2c_Stop();

      return data;
  }