i2c实验

2019-03-25 09:28发布

从网上下载了i2c的ip核,是Richard Herveille上传的,引文没有很好的参考例程,自己写的nios程序一直不通,有没有写好的例程,对照一下,
我写的程序,还请看看哪里有问题,卡在这里两天了,
操作的是PCF8563实时时钟,main函数是我自己写的,其他的下载时别人写好的。谢谢啊

#include "system.h"
#include "oc_i2c_regs.h"
#include "altera_avalon_pio_regs.h"
#include "alt_types.h"
#include "unistd.h"

int a[2]={2,2};
int b[2]={0};
int d[2]={0};
int e[8]={0};
int j,h;
int c[2]={0};
void I2CWaitTIP(alt_u32 base);

/*********************************************************************************************************
** Function name:                        InitI2C
**
** Descriptions:                        Initialize the I2C Open Core. The frequency of SCL is set as freq
**                    Interrupt will be or not be enabled by the IEN  
**
** input parameters:        base: The base address of I2C Core;
**                    freq: The frequency of SCL we want
**                    IEN : When the IEN is 1, interrupt will be enabled;
**                          When the IEN is NOT 1, interrupt will be disabled.                       
**                                               
** Returned value:                None
**         
** Used global variables:        None
** Calling modules:                          None
**
** Created by:                                Jing.Zhang
** Created Date:                        2005/09/30
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void InitI2C(alt_u32 base, alt_u32 freq, alt_u8 IEN)
{
        alt_u32 prescale;
        // Calculate the prescale value
        prescale = ALT_CPU_FREQ/((freq<<2) + freq);
  // Setup prescaler for the freq of SCL with sysclk of ALT_CPU_FREQ
  IOWR_OC_I2C_PRERLO(base, prescale & 0xff);
  IOWR_OC_I2C_PRERHI(base,(prescale & 0xff00)>>8);
  // Enable core
  if(IEN == 1) // Enable interrupt
  {
          IOWR_OC_I2C_CTR(base, 0xC0);
  }
  else // Enable core while disable interrupt
  {
          IOWR_OC_I2C_CTR(base, 0x80);
  }
}

/*********************************************************************************************************
** Function name:     I2CWaitTIP
**
** Descriptions:      Wait for the completion of transfer.
**
** input parameters:  base:    The base address of I2C Core;
**                 
**            
** Returned value:    None
**         
** Used global variables: None
** Calling modules:       None
**
** Created by:        Jing.Zhang
** Created Date:      2005/09/30
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void I2CWaitTIP(alt_u32 base)
{
  while (IORD_OC_I2C_SR(base) & I2C_SR_TIP) {}
}

/*********************************************************************************************************
** Function name:                        I2CWrite
**
** Descriptions:                        Write num bytes data to slave device by I2C bus.
**
** input parameters:        base:    The base address of I2C Core;
**                    address: The address of I2C slave device;
**                    reg:     The register of I2C slave device;
**                    buf:     The pointer to data buffer;
**                    num:     The num bytes of data which will be written                       
**                                               
** Returned value:                None
**         
** Used global variables:        None
** Calling modules:                          None
**
** Created by:                                Jing.Zhang
** Created Date:                        2005/09/30
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void I2CWrite(alt_u32 base, alt_u8 address, alt_u8 reg, alt_u8 *buf, alt_u16 num)
{
        alt_u16 i,tmp;
        // Wait for the completion of transfer
        I2CWaitTIP(base);

  // write address of I2C slave device
  // and generate START & WR command
  IOWR_OC_I2C_TXR(base, address);
  IOWR_OC_I2C_CR(base, I2C_CR_STA | I2C_CR_WR);
  I2CWaitTIP(base);

  // write register address
  IOWR_OC_I2C_TXR(base, reg);
  IOWR_OC_I2C_CR(base, I2C_CR_WR);
  I2CWaitTIP(base);

  // write data
  if(num > 0)
  {
          tmp = num - 1;
          for(i=0; i<tmp; i++)
          {
       IOWR_OC_I2C_TXR(base,*buf++);
       IOWR_OC_I2C_CR(base, I2C_CR_WR);
       I2CWaitTIP(base);
          }
  }

  // write data with STOP signal
  IOWR_OC_I2C_TXR(base, *buf);
  IOWR_OC_I2C_CR(base, I2C_CR_WR | I2C_CR_STO);
  I2CWaitTIP(base);
}

/*********************************************************************************************************
** Function name:                        I2CRead
**
** Descriptions:                        Read num bytes data from slave device by I2C bus.
**
** input parameters:        base:    The base address of I2C Core;
**                    address: The address of I2C slave device;
**                    reg:     The register of I2C slave device;
**                    buf:     The pointer to data buffer;
**                    num:     The num bytes of data which will be written                       
**                                               
** Returned value:                None
**         
** Used global variables:        None
** Calling modules:                          None
**
** Created by:                                Jing.Zhang
** Created Date:                        2005/09/30
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void I2CRead(alt_u32 base, alt_u8 address, alt_u8 reg, alt_u8 *buf, alt_u16 num)
{
        alt_u16 i,tmp;
        // Wait for the completion of transfer
        I2CWaitTIP(base);

  // write address of I2C slave device
  // and generate START & WR command
  IOWR_OC_I2C_TXR(base, address);
  IOWR_OC_I2C_CR(base, I2C_CR_STA | I2C_CR_WR);
  I2CWaitTIP(base);

  // write register address
  IOWR_OC_I2C_TXR(base, reg);
  IOWR_OC_I2C_CR(base, I2C_CR_WR);
  I2CWaitTIP(base);

  // write address of I2C slave device
  // and RD command
  IOWR_OC_I2C_TXR(base, address|1);
  IOWR_OC_I2C_CR(base, I2C_CR_STA | I2C_CR_WR);
  I2CWaitTIP(base);
  // Read data
  if(num > 0)
  {
          tmp = num - 1;
          for(i=0; i<tmp; i++)
          {
                   IOWR_OC_I2C_CR(base,I2C_CR_RD | I2C_CR_ACK);
       I2CWaitTIP(base);
       *buf++ = IORD_OC_I2C_RXR(base);
       j=*buf;
          }
  }

  // Read data with STOP signal
  IOWR_OC_I2C_CR(base,I2C_CR_RD | I2C_CR_ACK | I2C_CR_STO);
  I2CWaitTIP(base);
  *buf++ = IORD_OC_I2C_RXR(base);
  h=*buf;
}


int main(void)
{
    IOWR_ALTERA_AVALON_PIO_DATA(PIO_LED_BASE, 0x1);
    InitI2C(OC_I2C_BASE, 400000, 0);           //控制寄存器,使能i2c

    I2CWrite(OC_I2C_BASE,0xA2,0x00,(void*)e,8);         //8563的控制/状态寄存器
    I2CWrite(OC_I2C_BASE,0xA2,0x01,(void*)e,8);       //8563的控制/状态寄存器

    I2CWrite(OC_I2C_BASE,0xA2,0x04,(void*)a,2);        //      写入 小时寄存器数据
    usleep(100000);
    I2CRead(OC_I2C_BASE,0xA2,0x04,(void*)b,2);         //读出小时寄存器内容
    I2CRead(OC_I2C_BASE,0xA2,0x02,(void*)d,2);
    c[2]=b[2];
    while(1)
    {
        if(a[0]==b[1] || a[0]==b[0])
        {
            IOWR_ALTERA_AVALON_PIO_DATA(PIO_LED_BASE, 0x1);            //写入的和读出的一样则LED灯亮灭
            usleep(500000);
            IOWR_ALTERA_AVALON_PIO_DATA(PIO_LED_BASE, 0x0);
            usleep(500000);
        }
    }
   
}
[ 本帖最后由 tianma123 于 2012-4-4 19:25 编辑 ] 此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。