从网上下载了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 编辑 ]
此帖出自
小平头技术问答
一周热门 更多>