北以北城 2022-11-03 00:39 采纳率: 25%
浏览 60

IIC通信,AT24C02读写程序,数码管显示数据,为什么单片机上总是显示255

#include <reg52.h>
#include <intrins.h>

#define uint unsigned int
#define uchar unsigned char
#define At24c02ADDR 0XA0
#define I2cRead 1
#define I2cWrite 0

sbit DU=P2^6;
sbit WE=P2^7;
sbit SCL=P2^1;
sbit SDA=P2^0;
uchar num;
bit AckFlag;

//共阴数码管段选表0—9
uchar code SMGduan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//数码管位选码
uchar code SMGwei[]={0xfe,0xfd,0xfb};

//毫秒级延时函数定义
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=114;y>0;y--);
}

void display(uchar i)
{
static uchar wei;
P0=0XFF;//打开位选锁存器
WE=1;//
P0=SMGwei[wei];
WE=0;//锁存位选数据
switch(wei)
{
case 0:DU=1;P0=SMGduan[i/100];DU=0;break;
case 1:DU=1;P0=SMGduan[i%100/10];DU=0;break;
case 2:DU=1;P0=SMGduan[i%10];DU=0;break;
}
wei++;
if(wei==3)
wei=0;
}

//定时器0初始化
void timer0Init()
{
EA=1;//打开总中断
ET0=1;//打开定时器0中断
TR0=1;//启动定时器0
TMOD|=0x01;//定时器工作模式1,16位计时模式
TH0=0xED;
TL0=0xFF;//定时50ms
}
/*****************************************
IIC通信代码
*****************************************/
void delay5us()
{
nop();
}

void I2cStart()
{
SCL=1;
SDA=1;
delay5us();
SDA=0;
delay5us();
}

void I2cStop()
{
SCL=0;
SDA=0;
SCL=1;
delay5us();
SDA=1;
delay5us();
}

bit ReadACK()
{
SCL=0;
SCL=1;
delay5us();
if(SDA)
{
SCL=0;
return(1);
}
else
{
SCL=0;
return(0);
}
}

void SendACK(bit i)
{
SCL=0;
if(i)
SDA=1;
else
SDA=0;
SCL=1;
delay5us();
SCL=0;
SDA=1;//释放数据总线
}

void I2cSendByte(uchar DAT)
{
uchar i;
for(i=0;i<8;i++)
{
SCL=0;
if(DAT & 0x80)
SDA=1;
else
SDA=0;
SCL=1;
DAT<<=1;
}
SCL=0;
SDA=1;//释放数据总线
}

void At24c02Write(uchar ADDR,DAT)
{
I2cStart();
I2cSendByte(At24c02ADDR+I2cWrite);//I2c发送一个字节
if(ReadACK())
AckFlag=1;//NOACK
else
AckFlag=0;//ACK
I2cSendByte(ADDR);//I2c发送一个字节
if(ReadACK())
AckFlag=1;
else
AckFlag=0;
I2cSendByte(DAT);//读一字节
if(ReadACK())
AckFlag=1;
else
AckFlag=0;
I2cStop();
}

uchar I2cReadByte()
{
uchar i,DAT;
for(i=0;i<8;i++)
{
DAT<<=1;
SCL=0;
SCL=1;
if(SDA)
DAT|=0x01;
}
return(DAT);
}

uchar At24c02Read(uchar ADDR)
{
uchar DAT;
I2cStart();
I2cSendByte(At24c02ADDR+I2cWrite);//I2c发送一个字节
if(ReadACK())
AckFlag=1;//NOACK
else
AckFlag=0;//ACK
I2cSendByte(ADDR);//I2c发送一个字节
ReadACK();
I2cStart();
I2cSendByte(At24c02ADDR+I2cRead);//I2c发送一个字节
if(ReadACK())
AckFlag=1;//NOACK
else
AckFlag=0;//ACK
DAT=I2cReadByte();
SendACK(1);
I2cStop();
return(DAT);
}

void main()
{
timer0Init();//定时器0初始化
EA=0;//屏蔽中断
At24c02Write(2,9);
delay(5);
num=At24c02Read(9);
if(AckFlag)//当从机非应答
P1 = 0;//亮P1所有灯
else
P1 = 0XFF;//灭P1所有灯
EA = 1;//开中断
while(1);
}

void timer0() interrupt 1
{
TH0=0xED;
TL0=0xFF;//定时5ms
display(num);
}

  • 写回答

2条回答 默认 最新

  • qllaoda 2022-11-03 07:02
    关注

    估计是你弄错了写入函数的参数顺序,
    At24c02Write(2,9);按函数原型 void At24c02Write(uchar ADDR,DAT),第一个参数是地址,第二个是数据
    你写入的是地址2,读的却是地址9,地址9一直是初始值,当然就是255了。
    eeprom函数读写细节没看,也不能排除这里还有其它问题。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 11月3日

悬赏问题

  • ¥15 远程访问linux主机超时
  • ¥15 odoo17存货管理优势于中国国内该行业传统ERP或MES的详细解读和举例
  • ¥15 CPU卡指令整合指令数据都在图片上
  • ¥15 火车票关联12306问题
  • ¥15 odoo17处理受托加工产品
  • ¥15 如何用MATLAB编码图三的积分
  • ¥15 圆孔衍射光强随孔径变化
  • ¥15 MacBook pro m3max上用vscode运行c语言没有反应
  • ¥15 ESP-PROG配置错误,ALL ONES
  • ¥15 结构功能耦合指标计算