{
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通用的了
资料链接
>
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)