这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » 请教:应该是很简单的IIC Eeprom读写问题求助 !

共6条 1/1 1 跳转至

请教:应该是很简单的IIC Eeprom读写问题求助 !

菜鸟
2005-09-21 18:16:36     打赏

是在一个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;
}
谢谢指教,谢谢 !

[align=right][color=#000066][此贴子已经被作者于2005-9-21 10:27:58编辑过][/color][/align]



关键词: 请教     该是     简单     Eeprom     读写     问题     求助         

助工
2005-09-21 18:42:00     打赏
2楼
单个字节能读写正确吗?

菜鸟
2005-09-21 19:35:00     打赏
3楼
不要对整个芯片写入同一个数据吧,这样读的时候根本不知道地址是否弄对了。

菜鸟
2005-09-21 19:37:00     打赏
4楼

也不行,单个字节读取,读出的值始终是0xa1,不知何故 !

每次读取的时候我都输出了读取地址的啊,应该地址不会出错吧 ?

[align=right][color=#000066][此贴子已经被作者于2005-9-21 11:38:40编辑过][/color][/align]

助工
2005-09-21 22:21:00     打赏
5楼

while(IICCON & BUSY);//

while (!(IICCON & BF));
我不知道S3C4510B的软逻辑是怎样的,不过我有个建议:上面这两条语句前如果做清零动作,会更保险.

还有,你可用硬逻辑做啊?


菜鸟
2005-09-22 07:03:00     打赏
6楼

硬逻辑 ? 软逻辑 ?什么意思啊 ? 还请再具体说说,3Q

另外,采纳xiajiashan的意见,修改了读写函数,但是最后结果还是不对(代码大体一致,只是加了bf的清楚和设置操作,代码修改部分已用红色标注),不过第一字节读出来不再是0xa1了,所以应该还是解决了部分问题,但是最终还是有问题 !

while(IICCON & BUSY)--因为我每次使用IIC都是对IIC控制器复位了的,而且IICCON中BUSY位只读,所以不能清零,另外写进去的数据也改为不同的了,详见后面程序运行结果。

void IICWrite(void)
{
U8 i;
// 以下代码段写一个字符串到IIC总线上,写入相应的EEPROM中
IICSetup() ;// Initialize IIC control block,完全和SNDS100中的一样
//Step 1: Setup IICON register for transmit start
while(IICCON & BUSY);
IICCON = START|ACK|IEN; // Now, Start to ransmit
//Send Slave Address and Write command
IICBUF = IIC_DEV_0|S_WRITE;
while (!(IICCON & BF));
IICCON = IICCON & CLR_BF;//清bf位,即清BUF
IICCON = IICCON | SET_BF;//按照芯片资料写BUF前置位bf位
// SEND ADDRESS TO WRITE
IICBUF = IICTestAddr;
i=0;
while (buff_w[i]!= 0)// Buff是一个字符数组,我用来缓存准备输出的字符串
{
// Send test data: TestData
while (!(IICCON & BF));
IICCON = IICCON & CLR_BF;//清bf位,即清BUF
IICCON = IICCON | SET_BF;//按照芯片资料写BUF前置位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));
IICCON = IICCON & CLR_BF;
IICCON = IICCON | SET_BF;
//Send byte address: MSB
IICBUF = IICTestAddr;
while (!(IICCON & BF));
/* Repeat Start */
IICCON = RESTART;
IICCON = START|ACK|IEN;
IICBUF = IIC_DEV_0|S_READ;
while (!(IICCON & BF));
//IICCON = IICCON & CLR_BF;
//IICCON = IICCON | SET_BF;
for (i=0;i<PAGE_SIZE*2+1;i++)//读取两页
{
IICCON = IICCON & CLR_BF;//清bf位,即清BUF
while (!(IICCON & BF));
IICCON = IICCON | SET_BF;//按照芯片资料读BUF前置位bf位
buff_r[i] = IICBUF;
}
/* STOP IIC Controller */
IICCON = STOP;
}

程序运行结果如下:

Write data in Hex:
Addr 0x00 :0x 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08
Addr 0x10 :0x 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08
Addr 0x20 :0x 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08
Addr 0x30 :0x 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08
Addr 0x40 :0x 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08
Addr 0x50 :0x 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08
Addr 0x60 :0x 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08
Addr 0x70 :0x 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08
Addr 0x80 :0x 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08
Addr 0x90 :0x 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08
Addr 0xa0 :0x 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08
Addr 0xb0 :0x 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08
Addr 0xc0 :0x 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08
Addr 0xd0 :0x 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08
Addr 0xe0 :0x 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08
Readback data in Hex:
Addr 0x00 :0x 55 55 55 55 55 55 55 55 01 02 03 04 05 06 07 08 01
Addr 0x10 :0x 17 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
Addr 0x20 :0x 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01
Addr 0x30 :0x 17 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
Addr 0x40 :0x 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01
Addr 0x50 :0x 17 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
Addr 0x60 :0x 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01
Addr 0x70 :0x 17 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
Addr 0x80 :0x 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01
Addr 0x90 :0x 17 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
Addr 0xa0 :0x 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01
Addr 0xb0 :0x 17 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
Addr 0xc0 :0x 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 01
Addr 0xd0 :0x 17 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
Addr 0xe0 :0x 01 02 03 04 05 06 07 08 01 02 03 04 05 06 07 08 ff
Addr 0xf0 :0x ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 55
Test Finished.

[align=right][color=#000066][此贴子已经被作者于2005-9-21 23:07:50编辑过][/color][/align]

共6条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]