各位朋友:
我在用三星4510时,使用IIC总线,挂DS1307做实时时钟芯片,采用如下的IIC读写程序,经过长时间的收发测试,使用JTEG调试器,一般是几个小时的连续读取操作,程序总会停在这个地方: while (!(IICCON&BF)); //停止
请大伙分析分析是什么原因?如能解决,我请客,^_^。我是北京的朋友。
源程序如下:
//宏 定义
#define SYS_BASE 0x03ff0000
#define IO_BASE 0x03600000
#define SYSCFG *((volatile unsigned*)(SYS_BASE+0x0))
//#define IOPMOD *((volatile unsigned*)(SYS_BASE+0x5000))
//#define IOPCON *((volatile unsigned*)(SYS_BASE+0x5004))
//#define IOPDATA *((volatile unsigned*)(SYS_BASE+0x5008))
/********************/
/* I2C Bus Register */
/********************/
#define IICCON *((volatile unsigned*)(SYS_BASE+0xf000))
#define IICBUF *((volatile unsigned*)(SYS_BASE+0xf004))
#define IICPS *((volatile unsigned*)(SYS_BASE+0xf008))
#define IICCOUNT *((volatile unsigned*)(SYS_BASE+0xf00c))
#define BF 0x01 //Buffer flag
#define IEN 0x02 //Interrupt enable
#define LRB 0x04 //Last bit received
//ACK not received
#define ACK 0x08 //Acknowlege enable
//Generate an ACK signal at 9th SCL
#define NOACK 0x00 //No more received data is required
//from the slave
#define START 0x10
#define STOP 0x20
#define RESTART 0x30
#define BUSY 0x40
#define IICRESET 0x80 //Reset the IIC-BUS controller
#define IIC_DEV_0 0xa0 //IIC device''s slave address
#define S_WRITE 0x00 //Write IIC data for slave
#define S_READ 0x01 //Read IIC data for slave
/* Byte Slave transmitter and receive status flags */
#define iic_slave_addr 0x01 /* slave addr flag */
#define iic_byte_addr_msb 0x02 /* byte msb addr */
#define iic_byte_addr_lsb 0x04 /* byte lsb addr */
#define iic_page_tx_done 0x08 /* Page data transmit done */
#define iic_byte_rx_done 0x10 /* byte data receive done */
#define iic_repeat_start 0x20 /* flag for repeat start */
#define iic_multi_recv 0x40 /* recv multiple data */
#define iic_no_more_recv 0x80 /* no more recv from slave */
/*#define S8 signed char
#define S16 signed short
#define S32 signed long
#define U8 unsigned char
#define U16 unsigned short
#define U32 unsigned long*/
#define REG8 volatile unsigned char
#define REG16 volatile unsigned short
#define REG32 volatile unsigned long
#define BYTE U8
#define MHz 1000000
#define fMCLK 50*MHz
#define MCLK2 (fMCLK/2)
#define fSCL 100000 /* IIC Serial clock frequency */
#define SizeOfPage 8
#define StorageSize ((8*1024)/8)
/* Data structure for multiple byte slave transmitter format */
#define Write_Cycle_ms(x) (x*0.001*fMCLK-1)
#define CACHE 6
typedef struct
{
volatile U32 FLAG;
volatile U32 BuffByteCnt; /* Page buffer byte counter */
volatile U32 WriteDataSize; /* Page buffer byte counter */
volatile U8 SLAVE_ADDR; /* Slave address */
volatile U8 BYTE_ADDR_MSB; /* Byte MSB address */
volatile U8 BYTE_ADDR_LSB; /* Byte LSB address */
volatile U8 PAGE_BUFFER[SizeOfPage+1]; /* IIC Page data buffer */
} IIC_DATA_TX_FORMAT;
/* Data structure for multiple byte slave receiver format */
typedef struct
{
volatile U32 FLAG;
volatile U32 ByteReadCnt;
volatile U32 ReadDataSize;
volatile U8 SLAVE_ADDR;
volatile U8 BYTE_ADDR_MSB;
volatile U8 BYTE_ADDR_LSB;
volatile U8 *RCV_BUFFER;
} IIC_DATA_RX_FORMAT;
int SetPreScaler(int sclk)
{
return((int)(((fMCLK/sclk)-3.0)/16.0)-0.5); //add 0.5 for
}
void IicSetup(void)
{
IICCON = IICRESET ;
IICPS = SetPreScaler((int)fSCL); //support upto 100KHz
}
//读取函数
void IICReadInt(U8 SlaveAddr,U8 ReadAddr,U32 SizeOfData, U8 * ReadPtr)
{
IicSetup();
iic_recv.RCV_BUFFER = ReadPtr;
iic_recv.FLAG = 0x0;
iic_recv.ByteReadCnt = 0x0;
iic_recv.ReadDataSize = SizeOfData;
iic_recv.SLAVE_ADDR = SlaveAddr;
iic_recv.BYTE_ADDR_LSB = (U8)(ReadAddr & 0xff);
/* Step 1: Setup IICON register for receive start */
while (IICCON & BUSY); /* Wait! the iic bus is busy */
IICCON = START|ACK;
/* Send Slave Address and Write command */
IICBUF = iic_recv.SLAVE_ADDR|S_WRITE;
while (!(iic_recv.FLAG & iic_byte_rx_done))
{
while (!(IICCON&BF)); //程序停止的地方
if (!(iic_recv.FLAG & (U32)iic_byte_addr_lsb))
{
/* Send byte address: LSB */
IICBUF = iic_recv.BYTE_ADDR_LSB;
iic_recv.FLAG |= (U32)iic_byte_addr_lsb; /* send lsb byte addr */
}
else if (!(iic_recv.FLAG & (U32)iic_repeat_start))
{
/* Repeat Start */
IICCON = RESTART;
IICCON = START|ACK;
IICBUF = iic_recv.SLAVE_ADDR|S_READ;
iic_recv.FLAG |= (U32)iic_repeat_start;
}
else if (!(iic_recv.FLAG & (U32)iic_multi_recv))
{
/* Receive multiple data */
IICCON = ACK;
iic_recv.FLAG |= (U32)iic_multi_recv;
}
else if (iic_recv.ByteReadCnt < iic_recv.ReadDataSize)
{
*(iic_recv.RCV_BUFFER)++ = IICBUF;
iic_recv.ByteReadCnt++;
}
else if (!(iic_recv.FLAG & (U32)iic_no_more_recv))
{
/* Now,no more received data is required from slave */
IICCON = NOACK;
iic_recv.FLAG |= (U32)iic_no_more_recv;
}
else
{ /* Receive last data and STOP */
*(iic_recv.RCV_BUFFER)++ = IICBUF;
/* STOP IIC Controller */
IICCON = STOP;
/* byte data receive done */
iic_recv.FLAG |= (U32)iic_byte_rx_done;
}
}
}