为什么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信号