基于51单片机IIC通信的AT24C02学习笔记
引言
最近在学习几种串行通信协议,感觉收获很多,这篇文章是学习IIC总线协议的第一篇文章,以后还会再写一篇关于PCF8591 IIC通信的ADDA转换芯片的文章.
关于IIC总线
IIC 即Inter-Integrated Circuit(集成电路总线),这种总线类型是由飞利浦半导体公司在八十年代初设计出来的一种简单、双向、二线制、同步串行总线,主要是用来连接整体电路(ICS) ,IIC是一种多向控制总线,也就是说多个芯片可以连接到同一总线结构下,同时每个芯片都可以作为实时数据传输的控制源。主要包括启始、停止、读、写、应答信号。这种方式简化了信号传输总线接口。
IIC总线上可以挂多个器件,而每个器件都有唯一的地址,这样可以标识通信目标。数据的通信的方式采用主从方式,主机负责主动联系从机,而从机则被动回应数据。

关于AT24C02
AT24C02是一个2K位串行CMOS E2PROM, 内部含有256个8位字节,CATALYST公司的先进CMOS技术实质上减少了器件的功耗。AT24C02有一个8字节页写缓冲器。该器件通过IIC总线接口进行操作,有一个专门的写保护功能。在单片机上的应用广泛, 可以实现掉电数据不丢失功能。

IIC总线数据有效性的规定

SCL=1期间,SDA必须保持稳定,SCL=0时,SDA才允许改变。
IIC 总线的几种信号
1.起始和终止信号:

从时序图可以看出,起始信号为,SCL=1,SDA下降沿;终止信号为SCL=1,SDA为上升沿,保持的时间是有限制的:

具体的程序实现如下:
起始信号:SDA=1保持时间大于4。7us,随后SDA=0保持时间大于4us
/*SDA下降沿*/
void start()
{
SDA = 1; //顺序不能反了,先是SDA=1;
SCL = 1;
delay();
SDA = 0;
delay();
}
终止信号:SDA=0保持时间大于4us,随后SDA=1保持时间大于4。7us
/*SDA上升沿*/
void end()
{
SDA = 0; //顺序不能反了,先是SDA=0;
SCL = 1;
delay();
SDA = 1;
delay();
}
2.应答信号:

传送的每一个字节必须保证是8位长度。数据传送时,先传送最高位(MSB),每一个被传送的字节后面都必须跟随一位应答信号(即一帧共有9位)。
如:主机往总线上发送一个字节的数据后,释放总线,从机会把总线拉低(即应答信号),以表示这一字节发送成功
同理主机从总线上读取完一个字节的数据后,主机会把总线拉低,"告诉"从机这一字节的数据接收成功

程序实现
应答信号:
void ack()
{
uchar i = 0;
SCL = 1;
delay();
while(SDA == 1 && i < 250)i++;
SCL = 0; //SCL=0,SDA可以改变
delay();
}
3.AT24C02的器件地址:

根据数据手册和原理图可以看出器件地址为:0x90/0x91其中最后一位是读写方向位,若下一个字节为向总线上发送数据,则为0x90,若下一个字节是从总线上读取数据,则为0x91。
4.往总线上写一字节的数据
程序实现:先写最高位,通过左移运算符,将一字节的数据一位一位的传送到总线上,其中CY存储的是左移后的进位
void write_byte(uchar dat)
{
uchar i;
for(i = 0; i < 8; i++)
{
dat = dat << 1; //如1011 0011 左移一位为0110 0110
SCL = 0; //SDL=0,才能往SDA送数据,或从SDA读数据
delay();
SDA = CY; //上面左移后进位为1
delay();
SCL = 1;
delay();
}
SCL = 0;
// delay();
SDA = 1; //释放SDA
delay();
}
5.从总线上读取一个字节的数据
程序实现:带返回值,先读高位,然后通过移位运算符,一位一位读入
uchar read_byte()
{
uchar dat = 0, tmp, i;
SCL = 0;
delay();
for(i = 0; i < 8; i++)
{
SCL = 1; //让SDA保持稳定,准备读取
delay();
tmp = SDA; //读取此时SDA的状态
dat = dat << 1;
dat = dat | tmp;
delay();
SCL = 0; //释放SDA总线,为下一次读取做准备
delay();
}
return dat;
}
AT24C02读写操作
1.通过以上几种信号的组合,可以向AT24C02指定单元地址写一字节的数据,可以看出,读写顺序为:起始,写器件地址,应答,写单元地址,应答,写数据,应答,终止。

程序实现:此函数无返回值,有两个形参, 内存单元地址,范围0-255;要写的数据,如0xfe;
void write_AT24C02(uchar unit_addr, uchar dat)
{
start();
write_byte(AT24C02_ADDR + 0); //下一个字节为写,所以是+0
ack();
write_byte(unit_addr);
ack();
write_byte(dat);
ack();
end();
}
2.从AT24C02任意单元地址读取数据,可以看出读写顺序为:起始,写器件地址+0(下一个字节为写),应答,写单元地址,应答,起始,写器件地址+1(下一个字节为读取),读取数据,终止。

具体程序实现:此函数有返回值,一个形参;单元地址,范围:0-255;
uchar read_AT24C02(uchar unit_addr)
{
uchar dat;
/*先写数据*/
start();
write_byte(AT24C02_ADDR + 0); //下一个字节为写
ack();
write_byte(unit_addr);
ack();
start();
write_byte(AT24C02_ADDR + 1); //下一个字节为读
ack();
dat = read_byte();
end();
return dat;
}
延时函数:
void delay() //短暂5us延时
{
;;
}
IIC初始化:
void I2C_init() //初始化
{
SDA = ;
delay();
SCL = ;
delay();
}
具体应用
有了以上几个函数,我们就可以写主函数了, 功能是向内存单元211,写入数据0xae,然后在从内存单元211中读取出来,送给P1口led显示.注意:写完后要延时一会才能读取,否则不能成功读取.
void main()
{
write_AT24C02(211, 0xae);
delay_10ms(); //写完后,必须延时一定的时间才可以读取,否则不行
P1 = read_AT24C02(211);
while(1);
}
总结
通过IIC 总线通信协议的学习,可以看出,IIC总线用IO口模拟操作起来还是很简单的,使用起来还是比较方便的,而且还可以多个IIC器件挂接在一条总线上,只需要SDA和SCL两根线即可,当然也有缺点,由于是只有一根数据线,所以不能全双工传输,传输速度也有一定的限制.
我是初学者,以上内容如有错误,欢迎指正.
参考资料:
AT24C02_百度百科
iic_百度百科
欢迎大家关注我的个人博客 http://www.wangchaochao.top/
微信扫码关注我的公众号

不定期更新个人学习笔记和技术总结,欢迎大家互相学习交流!
基于51单片机IIC通信的AT24C02学习笔记的更多相关文章
- 基于51单片机IIC通信的PCF8591学习笔记
引言 PCF8591 是单电源,低功耗8 位CMOS 数据采集器件,具有4 个模拟输入.一个输出和一个串行I2C 总线接口.3 个地址引脚A0.A1 和A2 用于编程硬件地址,允许将最多8 个器件连接 ...
- 51单片机RAM 数据存储区学习笔记
转自:http://www.eepw.com.cn/article/216237_2.htm 1.RAM keil C语言编程 RAM是程序运行中存放随机变量的数据空间.在keil中编写程序,如果当前 ...
- ET 与RETI 基于51单片机中断跳出指令“RETI”浅议
最近在基于51单片机编程的过程中出现了个很奇怪的问题“程序执行中在寄存器EA=1,ET0=1,TR0=1条件下,单TF0=1时并没有执行中断”.在有过单片机中断编程经历者都知道当EA=1,ET0=1的 ...
- 基于51单片机个LCD1602的万年历程序
小白 第一次跟新博客 基于51单片机和LCD1602的万年历程序 可实现走时和调时功能 有简单的1602菜单制作 欢迎大家交流 LCD1602和51单片机的连接方法 RS = P3^5; //数据/命 ...
- 基于51单片机的CAN通讯协议C语言程序
//-----------------------函数声明,变量定义-------------------------------------------------------- #includ ...
- Flex与51单片机socket通信 策略问题
直接把<cross-domain-policy> <allow-access-from domain="*" to-ports="*"/> ...
- 基于jdk1.8的HashMap源码学习笔记
作为一种最为常用的容器,同时也是效率比较高的容器,HashMap当之无愧.所以自己这次jdk源码学习,就从HashMap开始吧,当然水平有限,有不正确的地方,欢迎指正,促进共同学习进步,就是喜欢程序员 ...
- 线程之间的通信socketpair【学习笔记】【原创】
平台信息:内核:linux3.1.0系统:android5.0平台:tiny4412 作者:庄泽彬(欢迎转载,请注明作者) 说明: 韦老师的安卓视频学习笔记 一.在一个进程中多个线程如何进行通信,主要 ...
- 基于【 MySql 】二 || mysql详细学习笔记
mysql重点学习笔记 /* Windows服务 */ -- 启动MySQL net start mysql -- 创建Windows服务 sc create mysql binPath= mysql ...
随机推荐
- 1113: [Poi2008]海报PLA
1113: [Poi2008]海报PLA Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 765 Solved: 466[Submit][Status ...
- 【转载】扩展Robot Framework,实现失败用例自动再执行(失败重跑)
使用自动化脚本进行测试,经常受环境影响等各方面导致本能成功的脚本失败,下面介绍了RFS框架下,失败重跑的方法: 通过改写RobotFramework源代码增加--retry选项,实现test级别的失败 ...
- python 接口自动化测试--代码实现(八)
用例读入数据库: #! /usr/bin/python # coding:utf-8 import sys,os from Engine import DataEngine reload(sys) s ...
- android 中判断WiFi是否可用的可靠方法 ,android 是否联网
http://alex-yang-xiansoftware-com.iteye.com/blog/619841 在一些程序中,需要从网上下载数据,或者通过其他方式对网络产生流量,当wifi不可用时应该 ...
- java操作txt文本(一):遇到指定字符换行
想法由来:有时查看网页源代码的css文件内容,竟是恼人的压缩后代码(不换行),如下图所示-- 它的可读性很差,所以写了下面这个简单的程序,实现自动换行. 适用条件:遇到指定字符换行(本例中遇到'}'换 ...
- ubuntu14.04下安装有道词典
1.打开官方下载链接:http://cidian.youdao.com/index-linux.html 2.下载相应版本的安装包 3.直接双击安装包进行安装 可能会存在软件打不开的情况,更新下系统, ...
- [TPYBoard - Micropython 之会python就能做硬件 9] 五分种学会用TPYBoard V102 制作避障小车(升级版)
转载请注明:@小五义 http://www.cnblogs.com/xiaowuyi 欢迎加入讨论群 64770604 感谢山东萝卜电子科技公司授权 一.实验器材 1.TPYboard V102板 ...
- android中在java代码中设置Button按钮的背景颜色
android中在java代码中设置Button按钮的背景颜色 1.设置背景图片,图片来源于drawable: flightInfoPanel.setBackgroundDrawable(getRes ...
- iOS开发之UINavigationController
1.概述: 利用UINavigationController,可以轻松地管理多个控制器,轻松完成控制器之间的切换,典型例子就是系统自带的“设置”应用. 2.UINavigationController ...
- shell脚本监控目录下文件被篡改时报警
思路: 目录下文件被篡改的几种可能: 1.被修改 2.被删除 3.新增文件 md5命令详解 参数: -b 以二进制模式读入文件内容 -t 以文本模式读入文件内容 -c 根据已生成的md5值,对现存文件 ...