打印

依旧I2C——24C02读写问题

[复制链接]
3217|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
t86964988|  楼主 | 2009-12-29 19:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我刚开始的时候,往24c02中的0地址开始写,写入0--7这8个数,然后读出来,结果显示:0,1,2,3,4,5,6,7
然后重新我往24c02中的0地址开始写,依次写入0,1...,9这10个数,然后再依次读出来用数码管显示。结果显示的是8,9,2,3,4,5,6,7,8,8.
我不知道为什么?
程序如下:其中I2C子程序测试过了 没问题的。
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define TRUE 1
#define FALSE 0
bit acktemp;
uchar ch,tt,cn;
uchar code tab[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,0x7f,0x6f};
sbit WP=P1^0;
sbit scl=P1^1;
sbit sda=P1^2;
void delay(uchar z)
{
uchar x,y;
for(x=z;x>0;x++)
  for(y=100;y>0;y++);
}
void init()
{
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
ET0=1;
TR0=1;
EA=1;
}
void start()
{
sda=1;
_nop_();
scl=1;//起始建立时间大于4.7us
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
sda=0;//起始锁定时间大于4us
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
scl=0;
_nop_();
}
void stop()
{
sda=0;
_nop_();
scl=1;//发送停止条件的时钟信号,停止总线时间大于4us
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
sda=1;//结束总线
_nop_();//保证一个终止信号和起始信号的空闲时间大于4.7us
_nop_();
_nop_();
_nop_();
}
uchar cheak_ack()//主机发送一个字节数据后检查应答位
{
  bit FO=0;
sda=1;//释放数据线等待接收应答信号ACK
_nop_();
_nop_();
scl=1;//应答位时钟拉高
_nop_();
_nop_();
F0=sda;
scl=0;
_nop_();
_nop_();
if(F0==1)
return FALSE;
else
return TRUE;
}
void master_ack()//主机接收一个字节数据应答
{
sda=0;
scl=1;
_nop_();
_nop_();
_nop_();
_nop_();
scl=0;
sda=1;
}
void master_uack()//主机接收一个字节数据非应答
{
sda=1;
scl=1;
_nop_();
_nop_();
_nop_();
_nop_();
scl=0;
sda=0;
}
void write_byte(uchar date)//在EEPROM上写一个字节数据
{
uchar i,temp;
temp=date;
for(i=0;i<8;i++)
{
  temp=temp<<1;
  sda=CY;
  _nop_();
  scl=1;
  _nop_();
  scl=0;
  _nop_();
}
}
uchar read_byte()//从EEPROM上读一个字节数据
{
uchar i,j,k;
sda=1;
_nop_();
for(i=0;i<8;i++)
{
  scl=1;
  _nop_();
  k=sda;
  scl=0;
  _nop_();
  j=(j<<1)|k;
}
return j;
}
void main()
{
init();
WP=0;
P2=1;
start();
write_byte(0xae);  //写24c02的地址
acktemp=cheak_ack();
write_byte(0);   //从24c02内部地址0开始写
acktemp=cheak_ack();
for(ch=0;ch<9;ch++)
{
  write_byte(tab[ch]);//向24c02中依次写入0到9
  acktemp=cheak_ack();
}
stop();
delay(100);
while(cn<9)
{
  start();
  write_byte(0xae);
  acktemp=cheak_ack();
  write_byte(cn);
  acktemp=cheak_ack();
  start();
  write_byte(0xaf);
  master_ack();
  P0=read_byte();
  master_uack();
  stop();
}
while(1);
}
void time0() interrupt 1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
tt++;
if(tt==20)
{
  tt=0;
  cn++;
}
}

相关帖子

沙发
kiyan| | 2010-6-18 19:16 | 只看该作者
正在学习中

使用特权

评论回复
板凳
NE5532| | 2010-6-18 20:16 | 只看该作者
你先别那么贪心啊,写1个数看看,写2个看看,写3个看看,找找规律呢。

使用特权

评论回复
地板
狼行千里wkt| | 2010-10-18 12:36 | 只看该作者
这个程序正好符合我的板子,不错哩!

使用特权

评论回复
5
狼行千里wkt| | 2010-10-18 12:40 | 只看该作者
我改成只显示1234,数码管显示到4后变暗延时了一会就变成8了不动了,这是为什么啊?

使用特权

评论回复
6
NE5532| | 2010-10-18 19:30 | 只看该作者
你有把其他程序屏蔽掉没?

使用特权

评论回复
7
zhaoyu2005| | 2010-10-19 16:58 | 只看该作者
没看程序,不过8 9 2 3 4 5 6 7这8个数符号卷页(我的叫法,不一定准,24C02的一页是8个字节,你送了10个,那第9个数就取代了第一数,第10个数就取代了第二个数,在本例中就是8覆盖了0,9覆盖了1)的现象,这个datasheet里有说明。

使用特权

评论回复
8
zhaoyu2005| | 2010-10-19 17:22 | 只看该作者
后面多两个8有两种情况:
1.你的程序正常,那两个地址的数据就是0x7F
2.你的I2C读程序不对,造成读的数据最高位丢失,那0xFF就变成0x7F了
自己想办法验证下吧,显示不会是P0=read_byte();吧?

使用特权

评论回复
9
tablexp| | 2010-10-20 08:52 | 只看该作者
学习后走人, 电感

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

19

主题

77

帖子

1

粉丝