读书人

为什么24C02 读写出错了?解决思路

发布时间: 2012-04-03 12:38:19 作者: rapoo

为什么24C02 读写出错了?

这是我使用51单片机 与24C02 之间进行读写的程序, 把一个已经初始化的数组里值 写入24C02, 然后读取24C02存储的数据,把结果显示在数码管里。


#include<reg52.h>
#include<intrins.h>
typedef unsigned char uchar;
//编码范围:0-9
unsigned char code table[10]={0x3f,0x6,0x5b,0x4f,0x66,0x6d,0x7d,0x7,0x7f,0xef };


sbit SCL=P2^0; //时钟线
sbit SDA=P2^1; //数据线


void Write_I2C_Byte(unsigned char Data) //往24C02里写数据 即传送数据
{//传送数据Data 首先从高字节开始传送
unsigned char i;
for(i=0; i<8; i++)
{
SDA=Data&0x80; //Data和0x80进行逻辑"与"运算 即读取Data数据的高位
Data=Data<<1; //由于已经读取一次高位 因此左移一位 从而可以继续读取下一位
_nop_();

SCL=1; //时钟线为高电平 使SDA数据线传输的数据能有效传送
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
//延时 是为了保证SDA数据线传送的数据能够顺利完成传输过程
SCL=0;
_nop_(); _nop_();

}
}

unsigned char Read_I2C_Byte(void) //从24C02里读数据 即接收数据
{
unsigned char Data=0;
unsigned char i;

for(i=0; i<8; i++)
{
SCL=0;
_nop_(); _nop_(); _nop_(); _nop_(); _nop_();

SCL=1;
_nop_(); _nop_();

Data=Data<<1; //
Data=Data|SDA; //调试的时候,发现: 从24C02芯片里读取一个字节时, SDA一直保持高电平,才导致返回Data的值是0xFF, 而在读取第二个字节的时候,SDA一直保持低电平, 所以导致 在数码管里显示的数字是: 800
请问, 各位, 我这个程序,哪里出问题了?

_nop_(); _nop_();

SCL=0;
}

return Data; //返回读取的数据
}

void Delay(unsigned char n)
{
unsigned char i, j;
for(i=n; i>0; i--)
for(j=110; j>0; j--);
}

void Write(uchar DataStartAdress, uchar *pData, uchar count) // 写操作
{ //DataStartAdress 为数据起始保存地址,
//pData指针为指向数据的指针变量, count 为写入字节的个数

unsigned char i;
I2C_Start();
Write_I2C_Byte(WR24C02); //把器件地址 发送到24C02 里
Check_ACK();
Write_I2C_Byte(DataStartAdress); //数据存储地址 即字地址
Check_ACK();

for(i=0; i<count; i++)
{
Write_I2C_Byte(*pData);
Check_ACK();
pData++;
}

I2C_Stop();

Delay(20);
}

void Read(uchar DataStartAdress, uchar *pData, uchar count) // 读操作: 随机读
{
unsigned char i;
I2C_Start();
Write_I2C_Byte(WR24C02); //把器件地址 发送到24C02 里
Check_ACK();
Write_I2C_Byte(DataStartAdress); //数据地址 即字地址
Check_ACK();

I2C_Start();
Write_I2C_Byte(RD24C02);
Check_ACK();

for(i=0; i<count; i++)
{
*pData=Read_I2C_Byte();
ACK();
pData++;
}

NoACK();
I2C_Stop();
Delay(10);
}

void main(void)
{
unsigned char WriteString[3]={3,6,9};
unsigned char ReadString[3];

unsigned char i;

Write(0x00, WriteString, 3);

Read(0x00, ReadString, 3);


while(1)
{
P1=0xfe; //位选线
i=ReadString[0];
P0=table[i]; //段选线
Delay(10);

P1=0xfd;
i=ReadString[1];
P0=table[i];
Delay(10);



P1=0xfb;
i=ReadString[2];
P0=table[i];
Delay(10);
}
}

希望 各位高手指点下,谢谢了


[解决办法]
看一下24C02的用户手册和时序图
[解决办法]
i=ReadString[0];
P0=table[i]; //段选线
Delay(10);
你是要用LED灯显示吧。。
那么i是一个实数吧。。
应该是P0=i,,,试试看。。

[解决办法]
建议先别急着显示 将写入的值 再读出来 比较是否相等 确保底层没问题
[解决办法]
Check_ACK();这里确定下从设备到底有没有返回ack信号

读书人网 >单片机

热点推荐