请求大侠帮助解决 24C02不能正确读存储和读取数据
1、第二行的m为什么初始化后显示26,而不是显示00,如果原来24C02里有数据,那么也不应该每次都显示26。
2、为什么m没有写入24C02,或者没有正确读取24C02的数据,程序在哪出了问题。
main.c文件:
#include<reg52.h>
#include"IIC.h"
#include"LCD.h"
sbit K1 = P1^0; //按键定义
uchar h = 0, //写入变量
m = 0, //写入变量
s = 0, //写入变量
hh , //读取变量
mm , //读取变量
ss ; //读取变量
/*主函数*/
void main()
{
InitLCD(); //初始换LCD
while(1)
{
if(K1 == 0) //按键按下
{
DelayMS(10); //消抖
while(!K1); //松开检测
s++; //自增
m++; //自增
h++; //自增
IIC_Write(1,s); //变量写入指定位置 地址1
IIC_Write(2,m); //变量写入指定位置 地址2
IIC_Write(3,h); //变量写入指定位置 地址3
}
hh = IIC_Read(1); //地址1读取数据
mm = IIC_Read(2); //地址2读取数据
ss = IIC_Read(3); //地址3读取数据
/*显示写入的数据*/
WriteCOM(0x80); //显示位置
WriteDAT('h'); //显示字母
WriteDAT(0x30+(h/10)); //显示十位
WriteDAT(0x30+(h%10)); //显示个位
WriteCOM(0x80+5); //显示位置
WriteDAT('m'); //显示字母
WriteDAT(0x30+(m/10)); //显示十位
WriteDAT(0x30+(m%10)); //显示个位
WriteCOM(0x80+10); //显示位置
WriteDAT('s'); //显示字母
WriteDAT(0x30+(s/10)); //显示十位
WriteDAT(0x30+(s%10)); //显示个位
/*显示读取的数据*/
WriteCOM(0x80+0x40); //显示位置
WriteDAT('h'); //显示字母
WriteDAT(0x30+(hh/10));//显示十位
WriteDAT(0x30+(hh%10));//显示个位
WriteCOM(0x80+0x40+5); //显示位置
WriteDAT('m'); //显示字母
WriteDAT(0x30+(mm/10));//显示十位
WriteDAT(0x30+(mm%10));//显示个位
WriteCOM(0x80+0x40+10);//显示位置
WriteDAT('s'); //显示字母
WriteDAT(0x30+(ss/10));//显示十位
WriteDAT(0x30+(ss%10));//显示个位
}
}
IIC.c文件:
#include "IIC.h"
/*延时函数*/
void DelayUS()
{
uchar a, b;
for(b=1; b>0; b--)
{
for(a=2; a>0; a--);
}
}
/*起始信号*/
void IIC_Start()
{
SDA = 1;
DelayUS();
SCL = 1;
DelayUS(); //建立时间是SDA保持时间>4.7us
SDA = 0;
DelayUS(); //保持时间是>4us
SCL = 0;
DelayUS();
}
/*停止信号*/
void IIC_Stop()
{
SDA = 0;
DelayUS();
SCL = 1;
DelayUS(); //建立时间大于4.7us
SDA = 1;
DelayUS();
}
/*发送一个字节*/
uchar IIC_SendByte(uchar dat, uchar ack)
{
uchar a = 0,b = 0; //最大255,一个机器周期为1us,最大延时255us。
for(a=0; a<8; a++) //要发送8位,从最高位开始
{
SDA = dat >> 7; //起始信号之后SCL=0,所以可以直接改变SDA信号
dat = dat << 1;
DelayUS();
SCL = 1;
DelayUS(); //建立时间>4.7us
SCL = 0;
DelayUS(); //时间大于4us
}
SDA = 1;
DelayUS();
SCL = 1;
while(SDA && (ack == 1)) //等待应答,也就是等待从设备把SDA拉低
{
b++;
if(b > 200) //如果超过200us没有应答发送失败,或者为非应答,表示接收结束
{
SCL = 0;
DelayUS();
return 0;
}
}
SCL = 0;
DelayUS();
return 1;
}
/*读取一个字节*/
uchar IIC_ReadByte()
{
uchar a = 0,dat = 0;
SDA = 1; //起始和发送一个字节之后SCL都是0
DelayUS();
for(a=0; a<8; a++) //接收8个字节
{
SCL = 1;
DelayUS();
dat <<= 1;
dat |= SDA;
DelayUS();
SCL = 0;
DelayUS();
}
return dat;
}
/*写数据*/
void IIC_Write(uchar addr,uchar dat)
{
IIC_Start();
IIC_SendByte(0xA0, 1); //发送写器件地址
IIC_SendByte(addr, 1); //发送要写入内存地址
IIC_SendByte(dat, 0); //发送数据
IIC_Stop();
}
/*读数据*/
uchar IIC_Read(uchar addr)
{
uchar num;
IIC_Start();
IIC_SendByte(0xA0, 1); //发送写器件地址,器件子地址全接地000
IIC_SendByte(addr, 1); //发送要读取的地址
IIC_Start();
IIC_SendByte(0xA1, 1); //发送读器件地址
num=IIC_ReadByte(); //读取数据
IIC_Stop();
return num;
}
现在出现什么现象呢?
两个写两个读之间加个延迟?
存入数据需要固化,资料上显示需要10ms,本程序中连续写入三个地址的数据,所以出现没有写入成功。
只要
IIC_Write(1,s); //变量写入指定位置 地址1
IIC_Write(2,m); //变量写入指定位置 地址2
IIC_Write(3,h); //变量写入指定位置 地址3
改为
IIC_Write(1,s); //变量写入指定位置 地址1
DelayMS(10); //延时固化数据
IIC_Write(2,m); //变量写入指定位置 地址2
DelayMS(10); //延时固化数据
IIC_Write(3,h); //变量写入指定位置 地址3
DelayMS(10); //延时固化数据
就OK了
只要
IIC_Write(1,s); //变量写入指定位置 地址1
IIC_Write(2,m); //变量写入指定位置 地址2
IIC_Write(3,h); //变量写入指定位置 地址3
改为
IIC_Write(1,s); //变量写入指定位置 地址1
DelayMS(10); //延时固化数据
IIC_Write(2,m); //变量写入指定位置 地址2
DelayMS(10); //延时固化数据
IIC_Write(3,h); //变量写入指定位置 地址3
DelayMS(10); //延时固化数据
就OK了
只要
IIC_Write(1,s); //变量写入指定位置 地址1
IIC_Write(2,m); //变量写入指定位置 地址2
IIC_Write(3,h); //变量写入指定位置 地址3
改为
IIC_Write(1,s); //变量写入指定位置 地址1
DelayMS(10); //延时固化数据
IIC_Write(2,m); //变量写入指定位置 地址2
DelayMS(10); //延时固化数据
IIC_Write(3,h); //变量写入指定位置 地址3
DelayMS(10); //延时固化数据
就OK了
只要
IIC_Write(1,s); //变量写入指定位置 地址1
IIC_Write(2,m); //变量写入指定位置 地址2
IIC_Write(3,h); //变量写入指定位置 地址3
改为
IIC_Write(1,s); //变量写入指定位置 地址1
DelayMS(10); //延时固化数据
IIC_Write(2,m); //变量写入指定位置 地址2
DelayMS(10); //延时固化数据
IIC_Write(3,h); //变量写入指定位置 地址3
DelayMS(10); //延时固化数据
就OK了
事实上在本程序中(STC89C52RC 11.0592M)
IIC_Write(1,s); //变量写入指定位置 地址1
DelayMS(3);
IIC_Write(2,m); //变量写入指定位置 地址2
DelayMS(3);
IIC_Write(3,h); //变量写入指定位置 地址3
就可以运行正常了,在实际应用中根据程序设计不是连续写入的话不需要延时的。
就是延时固化的问题,谢谢您的帮助。