⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2c.c

📁 Analog 公司 ADE7169 SOC 电表方案DEMO程序
💻 C
字号:
/*
-02/23/2006: Petre M.
  -this file contains all the functions used in I2C communications

*/
#include "ioADE7169F16.h"
#include "extern_declarations.h"
#include "EEPROM_locations.h"

void Tx_byte3(void) {

    //enable I2C
    I2CMOD_bit.I2CEN=1;

    //initialize the control word=1010 00 B0 0=Write operation
    I2CADR = 0xa0 | ((X & 0x100)>>7);

    SPI2CTx = X & 0x0ff; //sends the address

    //send the byte to be written
    SPI2CTx = *I2C_ptr;

  return;
}


void Tx_byte2(void) {

  if (N>1)  {
    //update the pointers
    ++I2C_ptr;
    N=N-1;
    X=X+1;

    //before a new communication is started, Bit6 of SPI2CSTAT must be cleared
    //even if it has not been set!?
    I2CSTAT = I2CSTAT & NBit6;

    Tx_byte3();

  }
  else {
    //before a new communication is started, Bit6 of SPI2CSTAT must be cleared
    //even if it has not been set!?
    I2CSTAT = I2CSTAT & NBit6;

    //clear bit0 of I2C_Status to show no EEPROM operation is under way
    I2C_Status = I2C_Status & NBit0;
  }

  return;
}

//this function writes one byte at a time to EEPROM. This means that if we have to write
//N bytes, it sends N times the control word, the address and a byte
//It waits until the entire communication ends
void Tx_byte(char Nr_Bytes, int EEPROM_address,unsigned char __idata  *Pointer) {
  unsigned char I2C_timeout;

  N=Nr_Bytes;
  X=EEPROM_address;
  I2C_ptr = Pointer;
  //set bit0 of I2C_Status to show an EEPROM operation is under way
  I2C_Status=I2C_Status | Bit0;

  Tx_byte3();

  I2C_timeout=0;

  //stay in this loop as long as I2C communication is executed
  while (I2C_Status & Bit0) {
    while (I2CSTAT_bit.I2CBUSY) {
      if (I2CSTAT_bit.I2CNOACK) {
        //erase NoACK bit by writing over a 0
        I2CSTAT = I2CSTAT & NBit6;

        //set bit7 to empty the Tx FIFO
        I2CSTAT = I2CSTAT | 0x80;

        Tx_byte3();
      }
    }
    Tx_byte2();

    //we must ensure that if I2C communication does not function for some reason,
    //we avoid remaining in an endless loop
    I2C_timeout++;
    if (I2C_timeout>0x80){
      I2C_Status=I2C_Status & NBit0;
      Meter_Errors[0] = Meter_Errors[0] | Bit0;
    }
  }

  return;
}

//This function reads Nr_Bytes from address EEPROM_address in EEPROM and stores
//them at Pointer
//It waits until the entire communication ends
void Tx_CTRL_byte(char Nr_Bytes, int EEPROM_address,unsigned char __idata  *Pointer) {
  unsigned int I2C_timeout;

  N = Nr_Bytes;
  X = EEPROM_address;
  I2C_ptr = Pointer;

  //enable I2C
  I2CMOD_bit.I2CEN=1;

  //initialize the control word=1010 00 B0 0=Write operation
  I2CADR = 0xa0 | ((X & 0x100)>>7);

  SPI2CTx = X & 0x0ff; //sends the address

  //set bit0 of I2C_Status to show an EEPROM operation is under way
  I2C_Status=I2C_Status | Bit0;

  I2C_timeout = 0;

  //stay in this loop as long as I2C communication is executed
  while (I2C_Status & Bit0) {
    if (I2CSTAT_bit.I2CNOACK) {
      //clear NoACK bit by writing over a 0
      I2CSTAT = I2CSTAT & NBit6;

      //set bit7 to empty the Tx FIFO
      I2CSTAT = I2CSTAT | Bit7;

      //enable I2C
      I2CMOD_bit.I2CEN=1;

      //initialize the control word=1010 00 B0 0=Write operation
      I2CADR = 0xa0 | ((X & 0x100)>>7);

      SPI2CTx = X & 0x0ff; //sends the address
    }
    if (I2CSTAT_bit.I2CTxIRQ) {
      //enable I2C, put N-1 bytes to read into the register
      I2CMOD = ((I2CMOD & 0xE0) | 0x80) | (N-1);

      //initialize the control word=1010 00 B0 1=Read operation
      I2CADR = 0xa1 | ((X & 0x100)>>7);
    }

    if (I2CSTAT_bit.I2CRxIRQ) {
      Rx_byte();
    }
    I2C_timeout++;
    if (I2C_timeout>0x400){
      I2C_Status=I2C_Status & NBit0;
      Meter_Errors[0] = Meter_Errors[0] | Bit1;

    }

  }


  return;
}

//this function stores all the bytes that were already received
void Rx_byte(void) {

//read data from RxFIFO until it becomes empty
  while (I2CSTAT & 0x0c) {
//read from Rx buffer
    *I2C_ptr = SPI2CRx;

    //if during this process, a FIFO location has been read and written in the same time,
    //then bit1 of SPI2CSTAT has been set. If this happened, we need to restart the
    //entire reading process, so we set bit1 of I2C_Status to signal this
    if (I2CSTAT & Bit1) {
      I2C_Status = I2C_Status | Bit1;
    }

//increment pointer
    ++I2C_ptr;
    N=N-1;
  }

  //if no bytes are to be received, clear the status bit
  if (N==0) {
      //we erase here bit0 of I2C_Status to show that the communication stopped
      I2C_Status=I2C_Status & NBit0;
  }
  return;
}


void Setup_I2C(void)
//this function initializes the I2C and enables I2C interrupt
{
  CFG_bit.SCPS = 0; //P0.4 and P0.6 are used as SDATA and SCLK for I2C

  //disable the weak pull up resistors on P0.4 and P0.6
  PINMAP0_bit.PINMAP04 = 1;
  PINMAP0_bit.PINMAP06 = 1;

  /*0=I2C disabled
     11=I2C serial frequency=Fcore/128=32KHz
       00000=receive nr bytes=0
  */
  I2CMOD = 0x60;

  IEIP2_bit.ESI = 0; //disable I2C interrupt

  return;
}





⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -