51单片机 24c02读取出来的数据不对 大神救救孩子

sixto47 2018-11-26 07:22:18
每次设定好,结果再复位出现的数值总是大了些,但确定它是能写入的。

应该不是延时固化数据的问题,是WrToROM或者RdFromROM 这两个子程序出问题了吗


#include <reg52.H>
#include <intrins.h>
#include "24c02.h"
#define AddWr 0xa0 //写数据地址
#define AddRd 0xa1 //读数据地址


sbit WP=P1^6;

/*------------------------------------------------
延时程序
------------------------------------------------*/
void mDelay(unsigned char j)
{
unsigned int i;
for(;j>0;j--)
{
for(i=0;i<100;i++)
{;}
}
}

/*--------------------------------------------------
初始化
--------------------------------------------------*/
void init(void)
{
Sda = 1;
mDelay(3);
Scl=1;
mDelay(3);
}

/*------------------------------------------------
启动IIC总线
------------------------------------------------*/
void Start(void)
{
Sda=1;
mDelay(3);
Scl=1;
mDelay(3);
Sda=0;
mDelay(3);
}


/*------------------------------------------------
停止IIC总线
------------------------------------------------*/
void Stop(void)
{
Sda=0;
mDelay(3);
Scl=1;
mDelay(3);
Sda=1;
mDelay(3);
}


/*------------------------------------------------
应答IIC总线
------------------------------------------------*/
void Ack(void)
{
Sda=0;
mDelay(3);
Scl=1;
mDelay(3);
Scl=0;
mDelay(3);
}


/*------------------------------------------------
非应答IIc
------------------------------------------------*/
void NoAck(void)
{
Sda=1;
mDelay(3);
Scl=1;
mDelay(3);
Scl=0;
mDelay(3);
}


/*------------------------------------------------
发送一个字节
------------------------------------------------*/
void Send(unsigned char Data)
{
unsigned char BitCounter=8;
unsigned char temp;
do
{
temp=Data;
Scl=0;
_nop_();_nop_();_nop_();_nop_();_nop_();
if((temp&0x80)==0x80)
Sda=1;
else
Sda=0;
Scl=1;
temp=Data<<1;
Data=temp;
BitCounter--;
}
while(BitCounter);
Scl=0;
}


/*------------------------------------------------
读入一个字节
------------------------------------------------*/
unsigned char Read(void)
{
unsigned char temp=0;
unsigned char temp1=0;
unsigned char BitCounter=8;
WP = 0;
Sda=1;
do
{
Scl=0;
_nop_();_nop_();_nop_();_nop_();_nop_();
Scl=1;
_nop_();_nop_();_nop_();_nop_();_nop_();
if(Sda)
temp=temp|0x01;
else
temp=temp&0xfe;

if(BitCounter-1)
{
temp1=temp<<1;
temp=temp1;
}
BitCounter--;
}
while(BitCounter);
return(temp);
}


/*------------------------------------------------
写入数据
------------------------------------------------*/
void WrToROM(unsigned char Data[],unsigned char Address,unsigned char Num)
{
unsigned char i;
unsigned char *PData;
PData=Data;
init();
WP = 0;
for(i=0;i<Num;i++) //数组长度
{
Start();
Send(AddWr); //写入芯片地址
Ack(); //应答
Send(Address+i); //写入芯片地址
Ack(); //应答
Send(*(PData+i)); //写数据
Ack(); //应答
Stop(); //停止总线
mDelay(20);
}
}


/*------------------------------------------------
读出数据
------------------------------------------------*/
void RdFromROM(unsigned char Data[],unsigned char Address,unsigned char Num)
{
unsigned char i;
unsigned char *PData;
PData=Data;
for(i=0;i<Num;i++)
{
Start();
Send(AddWr); //写入芯片地址
Ack();
Send(Address+i);//写入存储地址
Ack();
Start();
Send(AddRd); //读入地址
Ack();
*(PData+i)=Read();//读数据
Scl=0;
NoAck();
Stop();
}
}


void U16_Save(unsigned int *tmp,unsigned char add)
{
unsigned char buf[2]=0;
buf[0]= *tmp/256;
buf[1]= *tmp%256;
WrToROM(buf,add,2);
mDelay(50);
}

void U16_Read(unsigned int *tmp,unsigned char add)
{
unsigned char buf[2]=0;
RdFromROM(buf,add,2);
*tmp=256*(buf[0])+buf[1];
mDelay(50);
}
...全文
2728 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
kou_ching 2018-12-30
  • 打赏
  • 举报
回复
24c02读取与写入的时候,建议把延时调大,可以让数据完整的读取与写入。
诺水城子 2018-12-13
  • 打赏
  • 举报
回复
按要求延时时间5us左右,不确定你这个时间是否正确
诺水城子 2018-12-13
  • 打赏
  • 举报
回复
这个问题应该是操作芯片时时序的问题;注意读过程中的延时最好是忙等待,不要被其他线程给中断;
啃馒头 2018-12-10
  • 打赏
  • 举报
回复
本人遇到过这种问题,是时序的问题!
后来调整时序解决了,你可以试试 高低电平,第几个边沿 可以取数,传一个 方波
别看别人代码 没有,自己试着调整!
问题肯定是时序的问题!
并且 就是取数的 第几个沿 有问题,或者 上升沿 取数,或者下降沿取数
宙烨 2018-12-10
  • 打赏
  • 举报
回复
调通讯买个逻辑分析仪,看一下就知道了。30几块钱就能买到测这种的。
加班有前途么 2018-12-05
  • 打赏
  • 举报
回复
先调时序,读出累死芯片id之类的固定寄存器来验证时序的正确性。模拟iic在前期可以通过逻辑分析仪来分析时序的正确性,没有逻辑分析仪只能自己分析。自己手写模拟iic一次正确感觉还是有点儿难度。
sixto47 2018-12-02
  • 打赏
  • 举报
回复
引用 12 楼 vincentron 的回复:
速率调低点,IIC只有一个设备吗?

速率怎么调啊,不太清楚
sixto47 2018-12-02
  • 打赏
  • 举报
回复
引用 12 楼 vincentron 的回复:
速率调低点,IIC只有一个设备吗?

不止一个,还有DS1302时钟 LCD1602这些
sixto47 2018-12-02
  • 打赏
  • 举报
回复
引用 10 楼 一树梅 的回复:
楼主再改一下应答和非应答的代码。
/*------------------------------------------------
应答IIC总线
------------------------------------------------*/
void Ack(void)
{
Sda=0;
mDelay(3);
Scl=1;
mDelay(3);
Scl=0;
mDelay(3);
Sda=1;
}


/*------------------------------------------------
非应答IIc
------------------------------------------------*/
void NoAck(void)
{
Sda=1;
mDelay(3);
Scl=1;
mDelay(3);
Scl=0;
mDelay(3);
Sda=0;
}

还是不行 应答和非应答应该是没有问题的,毕竟能改
vincentron 2018-12-01
  • 打赏
  • 举报
回复
速率调低点,IIC只有一个设备吗?
fly 100% 2018-11-29
  • 打赏
  • 举报
回复
速率再调低点试试
yishumei 2018-11-28
  • 打赏
  • 举报
回复
楼主再改一下应答和非应答的代码。 /*------------------------------------------------ 应答IIC总线 ------------------------------------------------*/ void Ack(void) { Sda=0; mDelay(3); Scl=1; mDelay(3); Scl=0; mDelay(3); Sda=1; } /*------------------------------------------------ 非应答IIc ------------------------------------------------*/ void NoAck(void) { Sda=1; mDelay(3); Scl=1; mDelay(3); Scl=0; mDelay(3); Sda=0; }
sixto47 2018-11-28
  • 打赏
  • 举报
回复
引用 6 楼 一树梅 的回复:
[quote=引用 4 楼 sixto47 的回复:]
[quote=引用 3 楼 一树梅 的回复:]
楼主晶振用的多少MHz的?

12M的[/quote]
修改一下发送子函数
/*------------------------------------------------
发送一个字节
------------------------------------------------*/
void Send(unsigned char Data)
{
unsigned char BitCounter=8;
unsigned char temp;
do
{
temp=Data;
Scl=0;
if((temp&0x80)==0x80)
Sda=1;
else
Sda=0;
_nop_();_nop_();_nop_();_nop_();_nop_();
Scl=1;
temp=Data<<1;
Data=temp;
BitCounter--;
}
while(BitCounter);
Scl=0;
}[/quote]
有个很奇怪的现象,比如我设定的温度,设定大于15就会飘到31,设定小于15就飘到15去了,但1~5却能正常保存
sixto47 2018-11-28
  • 打赏
  • 举报
回复
引用 6 楼 一树梅 的回复:
[quote=引用 4 楼 sixto47 的回复:]
[quote=引用 3 楼 一树梅 的回复:]
楼主晶振用的多少MHz的?

12M的[/quote]
修改一下发送子函数
/*------------------------------------------------
发送一个字节
------------------------------------------------*/
void Send(unsigned char Data)
{
unsigned char BitCounter=8;
unsigned char temp;
do
{
temp=Data;
Scl=0;
if((temp&0x80)==0x80)
Sda=1;
else
Sda=0;
_nop_();_nop_();_nop_();_nop_();_nop_();
Scl=1;
temp=Data<<1;
Data=temp;
BitCounter--;
}
while(BitCounter);
Scl=0;
}[/quote]

引用 6 楼 一树梅 的回复:
[quote=引用 4 楼 sixto47 的回复:]
[quote=引用 3 楼 一树梅 的回复:]
楼主晶振用的多少MHz的?

12M的[/quote]
修改一下发送子函数
/*------------------------------------------------
发送一个字节
------------------------------------------------*/
void Send(unsigned char Data)
{
unsigned char BitCounter=8;
unsigned char temp;
do
{
temp=Data;
Scl=0;
if((temp&0x80)==0x80)
Sda=1;
else
Sda=0;
_nop_();_nop_();_nop_();_nop_();_nop_();
Scl=1;
temp=Data<<1;
Data=temp;
BitCounter--;
}
while(BitCounter);
Scl=0;
}[/quote]
改完,还是老样子诶
sixto47 2018-11-28
  • 打赏
  • 举报
回复
引用 5 楼 逍遥乄浅笑 的回复:
这几天刚调完这个芯片,用的是STM32单片机 ,你可以参考
https://blog.csdn.net/ggggyj/article/details/84098957

参考了下,还是老样子
yishumei 2018-11-27
  • 打赏
  • 举报
回复
引用 4 楼 sixto47 的回复:
[quote=引用 3 楼 一树梅 的回复:] 楼主晶振用的多少MHz的?
12M的[/quote] 修改一下发送子函数 /*------------------------------------------------ 发送一个字节 ------------------------------------------------*/ void Send(unsigned char Data) { unsigned char BitCounter=8; unsigned char temp; do { temp=Data; Scl=0; if((temp&0x80)==0x80) Sda=1; else Sda=0; _nop_();_nop_();_nop_();_nop_();_nop_(); Scl=1; temp=Data<<1; Data=temp; BitCounter--; } while(BitCounter); Scl=0; }
sixto47 2018-11-27
  • 打赏
  • 举报
回复
引用 1 楼 weixin_43583605 的回复:
EEPROM的初始值是否为0xFF?

没有设置初始值
^O^刺客 2018-11-27
  • 打赏
  • 举报
回复
EEPROM的初始值是否为0xFF?
诺水城子 2018-11-27
  • 打赏
  • 举报
回复
这几天刚调完这个芯片,用的是STM32单片机 ,你可以参考
https://blog.csdn.net/ggggyj/article/details/84098957
sixto47 2018-11-27
  • 打赏
  • 举报
回复
引用 3 楼 一树梅 的回复:
楼主晶振用的多少MHz的?

12M的
加载更多回复(1)

27,522

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧