求51单片机大神指教IIC总线AT24C02使用。有某个地方不懂。是关于开机记忆。

求51单片机大神指教IIC总线AT24C02使用。有某个地方不懂。是关于开机记忆。,第1张

void main()
{
init();
sec=read_add(2);//问题就在此处,无论写什么地址,都在数码管上面没有显示。
if(sec>100) //若将此处去掉,则没有记忆功能。
sec=0; //
TMOD=0x01;
ET0=1;
EA=1;
/

sec = read_add(2); //这里是sec 读取I2C指定2地址的数据,仔细看下面代码
write_add(2,sec); //这里是吧sec写入指定地址2里面,所以上面必须从地址2里面读取数据。
if(sec>100) //若将此处去掉,则没有记忆功能。
sec=0; //

这一块就是往I2C指定地址写入数值应该0 - 100数值,你把这里去掉了,没有往I2C写入数值你说能读出来数据吗还会有记忆功能吗。
/

TH0=(65536-45872)/256;
TL0=(65536-45872)%256;
TR0=1;
while(1)
{
display(sec/100,sec/10,sec%10);
if(write==1) //
{ //
write=0; //
write_add(2,sec); //
}
}
}
//
void time0() interrupt 1
{
TH0=(65536-45872)/256;
TL0=(65536-45872)%256;
tcont++;
if(tcont==20)
{
tcont=0;
sec++;
write=1; //
if(sec>100)
sec=0;
}
}

的博客 - CSDN博客
2013年11月22日AT24C02使用I2C进行数据访问,板子上使用STM32的I2C控制器2和AT24C02进行连接。 具体来说,PB10作为SCL和AT24C02相连,PB11

这篇文章是写给一个学弟看的,关于IIC,关于24C02的单字节写入\读取页写入和读取,,学弟总是害怕协议,,,我总是对人家说,本来就这样的,协议就是人家这样规定的,,,如果你早生几十年你也可能规定个IIC协议
我的单片机和24C02通信,,,我的单片机就叫主机,,,24C02叫从机

先看IIC

IIC协议规定开始传输数据的时候要先发一个起始信号,,,目的应该是告诉从机要开始通信了,准备准备

终止信号就是拜拜啦,再见!

起始信号就是 在SCL在高电平期间SDA来一个下降沿,,终止信号就是在SCL在高电平期间SDA来一个上升沿(所以协议上才会说,在正常传输数据的时候,只有在SCL为低电平的时候,数据线SDA的高低电平状态才允许改变,要不然岂不是和起始信号或者终止信号冲突了)
/

起动总线函数

函数原型: void  Start_I2c();

功能:    启动I2C总线,即发送I2C起始条件

/voidStart_I2c()

{

SDA=1;/发送起始条件的数据信号/_Nop();

SCL=1;

_Nop();/起始条件建立时间大于47us,延时/_Nop();

_Nop();

_Nop();

_Nop();

SDA=0;/发送起始信号/_Nop();/起始条件锁定时间大于4μs/_Nop();

_Nop();

_Nop();

_Nop();

SCL=0;/钳住I2C总线,准备发送或接收数据/_Nop();

_Nop();

}
voidStop_I2c()

{

SDA=0;/发送结束条件的数据信号/_Nop();/发送结束条件的时钟信号/SCL=1;/结束条件建立时间大于4μs/_Nop();

_Nop();

_Nop();

_Nop();

_Nop();

SDA=1;/发送I2C总线结束信号/_Nop();

_Nop();

_Nop();

_Nop();

}
发送完起始信号就能传输数据了

下面是程序
voidSendByte(unsignedcharc)

{

unsignedcharBitCnt;//SCL=0; 起始信号最后是SCL=0;所以不用写了for(BitCnt=0;BitCnt<8;BitCnt++)/要传送的数据长度为8位/{if((c<

SDA=1;

}else{

SDA=0;

}

_Nop();

SCL=1;/置时钟线为高,通知被控器开始接收数据位/_Nop();

_Nop();/保证时钟高电平周期大于4μs/_Nop();

_Nop();

_Nop();

SCL=0;

}

_Nop();

_Nop();

SDA=1;/8位发送完后释放数据线,准备接收应答位/_Nop();

_Nop();

SCL=1;

_Nop();

_Nop();

_Nop();if(SDA==1)/判断是否接收到应答信号/ack=0;//没有接收到应答信号elseack=1;//接收到应答信号SCL=0;

_Nop();

_Nop();

}
现在说一下接收,,,假设上面发送完0xaa以后,从机就返回给我们数据(11001100, 0xcc),当然SCL为低电平的时候模块准备数据,,SCL为高电平的时候,从机就把数据放在了SDA上,这样循环8次,一个8位数据就过来了

整体上应该是

Start_I2c();起始信号程序

SendByte(0xaa);

判断下ack是不是等于1,应答了(是继续执行还是停止看自己了)

Data = RcvByte();//接收数据

Ack_I2c(1);//发送非应答,就是SDA=1;,这个程序在下面

Stop_I2c();发送停止信号

接收程序如下
unsignedcharRcvByte()

{

unsignedcharretc;

unsignedcharBitCnt;

retc=0;

SDA=1;/置数据线为输入方式/for(BitCnt=0;BitCnt<8;BitCnt++)

{

_Nop();

SCL=0;/置时钟线为低,准备接收数据位/_Nop();

_Nop();/时钟低电平周期大于47μs/_Nop();

_Nop();

_Nop();

SCL=1;/置时钟线为高使数据线上数据有效/_Nop();

_Nop();

retc=retc<<1;if(SDA==1)retc=retc+1;/读数据位,接收的数据位放入retc中/_Nop();

_Nop();

}

SCL=0;

_Nop();

_Nop();return(retc);

}
应答或者非应答程序如下
/

应答子函数

函数原型:  void Ack_I2c(bit a);

功能:      主控器进行应答信号(可以是应答0或非应答1信号,由位参数a决定)

/voidAck_I2c(bit a)

{if(a==0)SDA=0;/在此发出应答或非应答信号/elseSDA=1;

_Nop();

_Nop();

_Nop();

SCL=1;

_Nop();

_Nop();/时钟低电平周期大于4μs/_Nop();

_Nop();

_Nop();

SCL=0;/清时钟线,钳住I2C总线以便继续接收/_Nop();

_Nop();

}
IIC其实就这样了,主要看支持IIC通信的芯片的资料了,写好这些就是IIC通用的了

资料链接

>

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/13217144.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-06-22
下一篇 2023-06-22

发表评论

登录后才能评论

评论列表(0条)

保存