是在一个S3C4510B的板子上调试一块24c02的IIC eeprom,这么一个小芯片调了一周了,总
是不对,真是郁闷,还请各位支个招,3Q
程序的问题是写入的数据和读出的数据对不上,而且每次读取,读出的第一个数据总是0xa1,而这个值正好是设备地址和读/写指令位的值,不知道原因究竟是什么,程序运行结果及源代码如下:
1、运行结果(程序会读写几乎整个芯片):
请注意,我首先对几乎整个芯片我写入同一个数据,然后再每次采用随机序列读,读取17字
节数据,而每次都是从16的整数倍地址开始读取,也就是说其实我每次第一个读取的数据都
应该是上一次读取的最后一个数据,这样做的目的是因为我第一个读取的数据总是设备地址
,不是我真正想要的数据,所以我就每次多读一个数据,不知程序是读的错误还是写的错误
Write data in Hex:
Addr 0x00 :0x 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37
Addr 0x10 :0x 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37
Addr 0x20 :0x 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37
Addr 0x30 :0x 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37
Addr 0x40 :0x 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37
Addr 0x50 :0x 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37
Addr 0x60 :0x 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37
Addr 0x70 :0x 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37
Addr 0x80 :0x 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37
Addr 0x90 :0x 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37
Addr 0xa0 :0x 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37
Addr 0xb0 :0x 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37
Addr 0xc0 :0x 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37
Addr 0xd0 :0x 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37
Addr 0xe0 :0x 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37
Readback data in Hex:
Addr 0x00 :0x a1 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37
Addr 0x10 :0x 80 df ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
Addr 0x20 :0x a1 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37
Addr 0x30 :0x 80 df ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
Addr 0x40 :0x a1 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37
Addr 0x50 :0x 80 df ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff--不再重复标识及排版,见凉!
Addr 0x60 :0x a1 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37
Addr 0x70 :0x 80 df ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
Addr 0x80 :0x a1 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37
Addr 0x90 :0x 80 df ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
Addr 0xa0 :0x a1 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37
Addr 0xb0 :0x 80 df ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
Addr 0xc0 :0x a1 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37
Addr 0xd0 :0x 80 df ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
Addr 0xe0 :0x a1 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37 37
Addr 0xf0 :0x a1 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
Test Finished.
2、源代码:
我看了以前的《I2C总线EEPROM应用笔记》,上面关于24c02的说法跟芯片资料有点冲突
,芯片资料说pagesize是8,而应用笔记上说是16,我是按8操作的,程序是由网上一位网友
说已经成功运行的程序改写的,代码如下:
#define IICCON (*(volatile unsigned *)0x3FFF000)
#define IICBUF (*(volatile unsigned *)0x3FFF004)
#define IICPS (*(volatile unsigned *)0x3FFF008)
#define U16 unsigned short
#define U8 unsigned char
#define MHz 1000000
#define KHz 1000
#define fMCLK 50*MHz
#define fSCL 50*KHz
#define PAGE_SIZE 8
#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
#define BF 0x01 // Buffer flag
#define IEN 0x02 // Interrupt enable
#define LRB 0x04 // Last bit received/ACK not received
#define ACK 0x08 // Ack 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 SET_BF 0x01
#define CLR_BF 0x00
#define BUFF_SIZE 0x20
#define WRITE_SIZE 0x10
#include <stdio.h>
U8 IICTestAddr;
U8 buff_w[BUFF_SIZE],buff_r[BUFF_SIZE];
void delay(unsigned int count)
{
unsigned int i,j,k;
for(i=0;i<count;i++)
for(j=0;j<0xff;j++)
for(k=0;k<0xff;k++);
}
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 IICWrite(void)
{
U8 i;
i=0;
// 以下代码段写一个字符串到IIC总线上,写入相应的EEPROM中
IICSetup() ;// Initialize IIC control block,完全和SNDS100中的一样
//Step 1: Setup IICON register for transmit start
while(IICCON & BUSY); // Wait! the iic bus is busy
IICCON = START|ACK|IEN; // Now, Start to transmit
//Send Slave Address and Write command
IICBUF = IIC_DEV_0|S_WRITE;
while (!(IICCON & BF));
// SEND ADDRESS TO WRITE
IICBUF = IICTestAddr;
while (buff_w[i]!= 0)// Buff是一个字符数组,我用来缓存准备输出的字符串
{
// Send test data: TestData
while (!(IICCON & BF));
IICBUF = buff_w[i];
i++;
}
while (!(IICCON & BF));
//STOP IIC Controller
IICCON = STOP;
}
void IICRead(void)
{
U8 i;
//以下代码检验是否正确写入,将前面写的数据读出来
IICSetup() ;// Initialize IIC control block
//Step 1: Setup IICON register for receive start
while(IICCON & BUSY);//Wait! the iic bus is busy
IICCON = START|ACK|IEN;
//Send Slave Address and Write command
IICBUF = IIC_DEV_0|S_WRITE;
while (!(IICCON & BF));
//Send byte address: MSB
IICBUF = IICTestAddr;
while (!(IICCON & BF));
/* Repeat Start */
IICCON = RESTART;
IICCON = START|ACK|IEN;
IICBUF = IIC_DEV_0|S_READ;
for (i=0;i<PAGE_SIZE*2+1;i++)//读取两页
{
while (!(IICCON & BF)); // BUFFER FULL
buff_r[i] = IICBUF;
}
/* STOP IIC Controller */
IICCON = STOP;
}
int main(void)
{
U8 i,j;
IICTestAddr = 0x0;
for( i = 0; i< BUFF_SIZE; i++)//初始化
{
buff_w[i] = 0;
buff_r[i] = 0;
}
//初始化待写的字符
for(i=0;i<PAGE_SIZE;i++)buff_w[i]=55;
printf("Write data in Hex:\n");
for(j=0;j<15;j++)
{//写芯片,共16*8*2字节,留下最后的16字节不写
printf("Addr 0x%02x :0x ",IICTestAddr);
for(i=0;i<PAGE_SIZE;i++)//输出第一页待写数据
{
printf("%02x ",buff_w[i]);
}
IICWrite();//写第一页
delay(30);
IICTestAddr+=PAGE_SIZE;
for(i=0;i<PAGE_SIZE;i++)//输出第二页待写数据
{
printf("%02x ",buff_w[i]);
}
IICWrite();//写第二页
delay(30);
IICTestAddr+=PAGE_SIZE;
printf("\n");
}
IICTestAddr = 0x0;
printf("Readback data in Hex:\n");
for(j=0;j<16;j++)//读芯片,16*8*2字节
{
printf("Addr 0x%02x :0x ",IICTestAddr);
IICRead();
for(i=0;i<PAGE_SIZE*2+1;i++)
delay(3);
}
printf("Test Finished.\n");
return 0;
}
谢谢指教,谢谢 !