stm32 at24c022为什么时序图不一样

21ic官方微信-->
后使用快捷导航没有帐号?
查看: 1809|回复: 7
模拟I2C时序AT24C02
&&未结帖(3)
主题帖子积分
初级技术员, 积分 57, 距离下一级还需 43 积分
初级技术员, 积分 57, 距离下一级还需 43 积分
主题帖子积分
专家等级:结帖率:16%
主题帖子积分
初级技术员, 积分 57, 距离下一级还需 43 积分
初级技术员, 积分 57, 距离下一级还需 43 积分
I2C在数据传输时候一个字节
每传输一位bit 数据线DIO, 在主机的SCK时钟的低电平变化 高电平保持& &
还是每个字节SCK保持高电平
读出数据的时候 SCK时钟线是由哪个设备提供的
21ic公开课,21ic网友共同的学习圈子!学单片机、嵌入式、模拟、电源……就看这里
移步更多21ic独家微课:
主题帖子积分
资深技术员, 积分 300, 距离下一级还需 200 积分
资深技术员, 积分 300, 距离下一级还需 200 积分
主题帖子积分
专家等级:结帖率:75%
主题帖子积分
资深技术员, 积分 300, 距离下一级还需 200 积分
资深技术员, 积分 300, 距离下一级还需 200 积分
sda电平状态在sck低电平时改变,所以是每传输一位在sck高电平是保持不变,sck由主设备提供
21ic公开课,21ic网友共同的学习圈子!学单片机、嵌入式、模拟、电源……就看这里
移步更多21ic独家微课:
主题帖子积分
初级技术员, 积分 57, 距离下一级还需 43 积分
初级技术员, 积分 57, 距离下一级还需 43 积分
主题帖子积分
专家等级:结帖率:16%
主题帖子积分
初级技术员, 积分 57, 距离下一级还需 43 积分
初级技术员, 积分 57, 距离下一级还需 43 积分
写一个字节进去之后 在第九个时钟 IIC器件会返回一个 回应信号&&为什么我的一直是H 而不是0
uchar iic_Answer(uchar number)
&&uchar i=0;
for(i=0;i&8;i++)
& && & SCK_L;&&
& && & OSRdyTbl(100);
& & if(number&0x80==0x80)
& && &SDA_H;
& && &SCK_H;
& && &OSRdyTbl(100);
& && &SDA_L;
& && &SCK_H;
& && &OSRdyTbl(100);
& && &number&&=1;
OSRdyTbl(100);
// OSRdyTbl(100);
while((P5IN&0x20)!=0x20)
& &number=0;
& &return 1;
// if((P5IN&0x20)==0x20)
//& &return 0;
//& & return 1;
21ic公开课,21ic网友共同的学习圈子!学单片机、嵌入式、模拟、电源……就看这里
移步更多21ic独家微课:
主题帖子积分
初级技术员, 积分 57, 距离下一级还需 43 积分
初级技术员, 积分 57, 距离下一级还需 43 积分
主题帖子积分
专家等级:结帖率:16%
主题帖子积分
初级技术员, 积分 57, 距离下一级还需 43 积分
初级技术员, 积分 57, 距离下一级还需 43 积分
MSP430F149&&8M 晶振
21ic公开课,21ic网友共同的学习圈子!学单片机、嵌入式、模拟、电源……就看这里
移步更多21ic独家微课:
主题帖子积分
初级工程师, 积分 2608, 距离下一级还需 392 积分
初级工程师, 积分 2608, 距离下一级还需 392 积分
主题帖子积分
专家等级:结帖率:100%
主题帖子积分
初级工程师, 积分 2608, 距离下一级还需 392 积分
初级工程师, 积分 2608, 距离下一级还需 392 积分
Master Device
21ic公开课,21ic网友共同的学习圈子!学单片机、嵌入式、模拟、电源……就看这里
移步更多21ic独家微课:
主题帖子积分
实习生, 积分 42, 距离下一级还需 8 积分
实习生, 积分 42, 距离下一级还需 8 积分
主题帖子积分
专家等级:结帖率:0%
主题帖子积分
实习生, 积分 42, 距离下一级还需 8 积分
实习生, 积分 42, 距离下一级还需 8 积分
21ic公开课,21ic网友共同的学习圈子!学单片机、嵌入式、模拟、电源……就看这里
移步更多21ic独家微课:
主题帖子积分
主题帖子积分
专家等级:结帖率:100%打赏:0.00受赏:6.00
主题帖子积分
时序问题么?
QQ:& &可接项目和毕设等
& && && && && && &可以出售各种LED灯,控制类产品和
& && && && && && &控制类方案。
主题帖子积分
中级技术员, 积分 138, 距离下一级还需 162 积分
中级技术员, 积分 138, 距离下一级还需 162 积分
主题帖子积分
专家等级:结帖率:50%
主题帖子积分
中级技术员, 积分 138, 距离下一级还需 162 积分
中级技术员, 积分 138, 距离下一级还需 162 积分
其实规格书上的时序图画的很清楚了;
21ic公开课,21ic网友共同的学习圈子!学单片机、嵌入式、模拟、电源……就看这里
移步更多21ic独家微课:
技术高手奖章
人才类勋章
时间类勋章
精华达人奖章
等级类勋章
湍急之河流
发帖类勋章
时间类勋章
技术奇才奖章
人才类勋章
时间类勋章
坚毅之洋流
发帖类勋章
核心会员奖章
等级类勋章
技术新星奖章
人才类勋章
时间类勋章  从今天早上开始看AT24C02的手册,凭着有些撮的英语水平,24页的资料,愣是啃了半天,上午的时光就过去了。
  AT24C02是一款EEPROM芯片,IIC接口,就是两条线:SDA与SCL;不过对于单单操纵这款芯片而言,没有设计到IIC总线协议之中所谓的仲裁。因而,大体看下了芯片手册,心中就知道大概怎么操作了。
  另外,24C02的2K是指2Kbit。一般的话,存储器都用字节来衡量,所以其实24c02只有256byte。是不是比较小?这256byte又分成了32pages,每页有8byte。
  现在来看看该如何编写代码,首先得知道起始与停止条件
& & & & & & & & & & & &
所谓起始条件:在SCL高电平期间,SDA的一个下降沿;
所谓停止条件:在SCL高电平期间,SDA的一个上升沿;
当然起始和停止条件与普通的位传送是不同的,位传送的时序如图所示
可以看到,在SCL的高电平期间,SDA是不允许变化的;而只有在SCL的电平期间,SDA才能够出现变化;
当传输完1字节之后,可能需要有一个应答信号。说到这儿,就需要明白几个概念:发送器、接受器、主器件、从器件。
发送器:在总线上发送数据的器件。
接受器:在总线上接受数据的器件。
主器件:控制信息交互的器件,产生SCL时钟信息,产生起始与停止条件。
从器件:受从器件控制的器件。
那这儿的应答信号,就是总线上的接受器每接受到一个字节后产生的应答。如图所示:
需要注意的是,在等待应答信号之前,需要将SDA置高,即释放掉总线。
24c02写的方式有两种:字节写、页写(就是连续写多个字节)。
掌握了字节写,对于页写就容易的多了。
字节写的时序如图所示:
字节写的时序:首先是起始条件(由MCU产生),接着单片机向总线上传送器件地址,总线上地址相同的器件会有一个ACK(即应答信息),然后向器件写入字地址(告诉24c02想把信息写在那个地址,24c02刚好有256个字节,8bit的字地址信息刚好表示),同样会有一个应答信息,紧接着需要写入需要传送的数据(8位),同理会有一个应答信息。最后,需要主器件产生一个停止条件。Ok,写字节就结束了,是不是很简单,页写只不过是在这一步没有发送停止条件,而是接着发数据,这个时候24c02会知道你要写下一个字节,它会自动的加地址。
再来看看如何读取,读取有三种方式:当前地址读、随机读(我得承认这个名字不是太好)、顺序读。
当前地址读取是指你可以读取到芯片内部地址计数器(最近一次操作留下的值)加上1的地址上的值。看清楚是加上1地址上的值,不过不太明白有何用处。
接下来的随机读取跟是让我迷惑(刚看手册时候),随机的意思不就是产生一个无脑的地址,然后去读取,这样的话,读取有什么意义?不过我想错了,你可以看看时序图:
看到了,先发写命令了,也传送了字地址,然后没有发写的内容。转而,重新开始发起始条件、器件地址(这次最后一位是读),然后再接受总线传送来的数据,此后主控器作为接受方,不用发应答信号,直接发一个停止条件,就ok了。
所以要想指定一个地址,就可以用随机读这个方法。不过随机读说法不太形象,改为指定地址读跟容易理解。
顺序读跟页写是对应的,只是在随机读或当前地址读后面接着接受数据。
写了三页,貌似不是很长。那就贴上代码,来充长。
个人喜欢写一个头文件,然后,再写一个c文件。
头文件部分:
#ifndef __hal_24c02_h__
#define __hal_24c02_h__
#include"reg52.h"
#include"hal.h"
#include"datatype.h"
#include"delay.h"
sbit scl=P3^7;//IIC时钟线
sbit sda=P3^6;//IIC数据线
#define SCL scl
#define SDA sda
//起始条件,SCL高电平时候,SDA的一个下降沿
#define HAL_24C02_START() {SDA=1;SCL=1;SDA=0;}
//停止条件,SCL高电平时候,SDA的一个上升沿
#define HAL_24C02_STOP() {SDA=0;SCL=1;SDA=1;}
#define HAL_24C02_BYTE_ADDR(addr) hal_24c02_send_char(addr)
#define HAL_24C02_ACK() hal_24c02_acknowledge(0)
void hal_24c02_init();
void hal_24c02_send_char(uchar val);
uchar hal_24c02_receive_char();
void hal_24c02_search_device(bit a2,bit a1,bit a0,bit rw);
void hal_24c02_acknowledge(bit mcu);
//学会使用以下两个函数即可
//需要注意写完之后,等待5ms之后,再去读取
void hal_24c02_byte_write(bit a2,bit a1,bit a0,uchar byte_addr,uchar byte_data);
uchar hal_24c02_byte_read(bit a2,bit a1,bit a0,uchar byte_addr);
C文件部分:
#include"hal_24c02.h"
//初始化,需将时钟线和数据线拉高
void hal_24c02_init()
&&&&&&&& SCL=1;
&&&&&&&& SDA=1;
//IIC协议要求从高位开始传送,传送1字节
void hal_24c02_send_char(uchar val)
&&&&&&&& SCL=0;//此时,SCL被拉低,才允许SDA变化
&&&&&&&& for(i=0;i&8;i++)
&&&&&&&& {
&&&&&&&&&&&&&&&&&& &if(val&(0x80&&i))
&&&&&&&&&&&&&&&&&& &&&&&&& SDA=1;
&&&&&&&&&&&&&&&&&& &else
&&&&&&&&&&&&&&&&&& &&&&&&& SDA=0;
&&&&&&&&&&&&&&&&&& SCL=1;//拉高SCL,不允许SDA变化
&&&&&&&&&&&&&&&&&& delay_ms(1);
&&&&&&&&&&&&&&&&&& SCL=0;//拉低SCL,开始下1bit传送
&&&&&&&& }
&&&&&&&& //不包括应答脉冲,此时,SCL被拉低,SDA未被释放
&&&&&&&& SDA=1;//释放数据线
&&&&&&&& //SCL处于低电平;SDA处于高电平
uchar hal_24c02_receive_char()
&&&&&&&& &//SCL低电平 SDA高电平
&&&&&&&& &uchar tmp=0,i;
&&&&&&&& &for(i=0;i&8;i++)
&&&&&&&& &{
&&&&&&&& &&&&&&& SCL=1;
&&&&&&&&&&&&&&&&&& if(SDA)
&&&&&&&&&&&&&&&&&&&&&&&&&&& tmp=tmp|(0x80&&i);
&&&&&&&&&&&&&&&&&& SCL=0;
&&&&&&&& &}
&&&&&&&& &
&&&&&&&& &//SCL低电平 SDA高电平
//a2、a1、a0:表示器件地址
//rw:1 代表读操作;0 代表写操作
void hal_24c02_search_device(bit a2,bit a1,bit a0,bit rw)
&&&&&&&& tmp=0xa0|(a2?0x08:0x00)|(a1?0x04:0x00)|(a0?0x02:0x00)|
&&&&&&&& hal_24c02_send_char(tmp);
//参数mcu=1,表示由主机主动产生应答信号,此时还需要将SDA拉低
//参数mcu=0,表示非主机参数应答信号,此时主机只需要产生SCL脉冲
//返回1:表示有应答;0:无应答
void hal_24c02_acknowledge(bit mcu)
&&&&&&&& //SCL处于低电平;SDA处于高电平
&&&&&&&& if(mcu)&&&&& SDA=0;//产生1应答信号
&&&&&&&& SCL=1;
&&&&&&&& delay_ms(1);
&&&&&&&& while(SDA);//等待应答
&&&&&&&& SCL=0;
&&&&&&&& if(mcu)&&&&& SDA=1;//释放总线
&&&&&&&& //SCL处于低电平;SDA处于高电平
//参数a2,a1,a0:器件地址
//参数byte_addr:字节地址
//参数byte_data:需要写的数据
void hal_24c02_byte_write(bit a2,bit a1,bit a0,uchar byte_addr,uchar byte_data)
&&&&&&&& &HAL_24C02_START()
&&&&&&&& &hal_24c02_search_device(a2,a1,a0,0);
&&&&&&&& &HAL_24C02_ACK();
&&&&&&&& &HAL_24C02_BYTE_ADDR(byte_addr);
&&&&&&&& &HAL_24C02_ACK();
&&&&&&&& &hal_24c02_send_char(byte_data);
&&&&&&&& &HAL_24C02_ACK();
&&&&&&&& &HAL_24C02_STOP()
//参数a2 a1 a0为器件地址;
//参数byte_char为需要读取的字节地址
//返回一个uchar型
uchar hal_24c02_byte_read(bit a2,bit a1,bit a0,uchar byte_addr)
&&&&&&&& &uchar val=0;
&&&&&&&& &HAL_24C02_START()
&&&&&&&& &hal_24c02_search_device(a2,a1,a0,0);//伪写
&&&&&&&& &HAL_24C02_ACK();
&&&&&&&& &HAL_24C02_BYTE_ADDR(byte_addr);//伪写的目的,就是为了传送地址
&&&&&&&& &HAL_24C02_ACK();
&&&&&&&& &HAL_24C02_START();
&&&&&&&& &hal_24c02_search_device(a2,a1,a0,1);//真读
&&&&&&&& &HAL_24C02_ACK();
&&&&&&&& &val=hal_24c02_receive_char();
&&&&&&&& &//NO ACK
&&&&&&&& &HAL_24C02_STOP()
&&&&&&&& &
阅读(...) 评论()}

我要回帖

更多关于 at24c02读写程序 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信