ImageVerifierCode 换一换
格式:DOCX , 页数:23 ,大小:271.84KB ,
资源ID:24946530      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/24946530.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(I2C之AT24C04总结.docx)为本站会员(b****9)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

I2C之AT24C04总结.docx

1、I2C之AT24C04总结I2C之AT24C04总结I2C之AT24C04总结济南职业学院 电子工程系 朱志强1、AT24C04介绍2、AT24C04之准备工作3、AT24C04之小试牛刀4、对应源程序2010年7月28日1、AT24C04介绍关于I2C的介绍,这里就不用说了,直接介绍24C04了。24C04是4K位串行CMOS E2PROM。引脚的认识:SCL 串行时钟引脚 SDA 串行数据/地址 A0、 A1、 A2 器件地址输入端 WP 写保护(WP 管脚连接到Vcc, 所有的内容都被写保护(只能读)。当WP 管脚连接到Vss 或悬空,允许器件进行正常的读/写操作。)2、AT24C04之

2、准备工作首先,我们先查看一下实验板上面的接线图。如图1所示。图1 24c04连接图我们要注意的第一点是器件地址全部是0,即接地处理。第二点是读写保护WP接地,意味着我们可以随意存取。第三点是我们要用到的引脚连接到了P36和P37上。在这里还要提醒一下,就是引脚上一定要有上拉电阻!阻值在4701k都可以的,具体的数值可以参考相关的手册。在程序里我们需要先做以下定义:sbit AT24C04_SCL=P37;sbit AT24C04_SDA=P36;在写这个程序的时候,要使用到键盘,不用太多按键,我们暂时只用四个。把实验板上面的跳线JP8接到“-”端上,使第一行的按键变为独立键盘就可以了。线路图如

3、图2所示。图2 键盘部分电路图键盘这部分我就不说了吧,直接附上我用到的这部分程序,在我的程序中,并没有判断按键是否松开,而是使用的延时,这样的好处是一直按着按键,数据会一直在变化,要不然,频繁的按真的很累人。转到按键程序对于里面用到的延时函数,一个是US级延时函数,一个是ms级延时函数,分别调用一下是延时2us和1ms。对于显示部分吧,使用的就是LCD1602显示了。这部分程序参见这里。显示程序说完了这些,准备的就差不多了,我们可以对着PDF写AT24C04程序了。3、AT24C04之小试牛刀我们打破PDF中的介绍顺序,按照实际写程序时的顺序分开分析。第一项是我们要用她,那就要知道她是怎么开始

4、吧?这就是I2C总线时序中的开始和停止。时序图如下。图3 开始停止时序有一个需要注意的地方,就是当SCL为高电平时,所有的SDA的变化都会被认为是开始或停止信号。所以,我们必须注意,在对SDA进行操作之前,一定要注意SCL的值。例如在我们写开始信号之前,我们没法判断两个信号的具体电位,那么我们就要做最坏的打算。首先SDA=1,然后SDA=0,此间要让SCL保持在高电平。为保证SCL为高电平,我们要用SCL=1指令使SCL保持在高电平。SCL放在什么位置就成了重点。如果我们SDA变为高电平之前,这样却成了SCL=1后SDA=1,形成了停止信号!这个是我们要避免的,那么我们就要让SDA变化的时候,

5、全部避开SCL为高电平段。程序如下。void I2C_START() /AT24C04_SCL=0;delayus(1);/这样做有些繁琐,我们可以直接不用,因为我们跳出/所有的子函数时,都会让SCL=0! AT24C04_SDA=1;delayus(1);/注意先后顺序 AT24C04_SCL=1;delayus(1); AT24C04_SDA=0;delayus(1);/下降沿开始 AT24C04_SCL=0;delayus(1);我们以同样的思维,可以得到停止子函数,如下。void I2C_STOP() AT24C04_SCL=0;delayus(1); AT24C04_SDA=0;de

6、layus(1); AT24C04_SCL=1;delayus(1); AT24C04_SDA=1;delayus(1);/上升沿停止下面我们来看一下写的时序。图4 写时序时序的第一部分给我们展现了一个第八位数据写完后的情况,也就是说要有一个ACK应答信号。具体关于ACK应答信号的内容,可以参考器件手册。第二部分是从开始到停止。至于时序图中给出的时间我们可以不用考虑。只需要记住,当SDA变化时SCL为0,SDA变化完后,SCL在变为1来告知24C04接收数据线上的信号。具体的实现函数如下所示。void I2C_Wdata(unsigned char data4) unsigned char i

7、; unsigned char temp; temp=data4; for(i=0;i8;i+) AT24C04_SCL=0; temp=temp1;/先发送高位 AT24C04_SDA=CY;delayus(1); AT24C04_SCL=1;delayus(1); AT24C04_SCL=0;delayus(1);这里还需要注意的一点是我们每当SDA或者SCL变化一次,就会调用一下delayus(1)来延时2us,是用来稳定信号和保证信号保持的时间。上面是写的时序,我们还要有读的子函数啊其实,读得时序和写的时序差不多,只不过是反过来的。既然是读,发送方就是24C04,接收方式单片机。每次都

8、是让SCL为1,使得24C04掌握对SDA的控制权。而单片机的任务就是在把SCL拉高后,监视SDA的变化并读出SDA上的数据。下面就是读的子函数。unsigned char I2C_Rdata() unsigned char i; unsigned char temp; unsigned char k; AT24C04_SCL=0;delayus(1); AT24C04_SDA=1;/等待24C02发回来的信号 for(i=0;i8;i+) AT24C04_SCL=1;delayus(1); if(AT24C04_SDA=1) k=1; else k=0; temp=temp1; temp=t

9、emp|k;/读数据时高位在前 AT24C04_SCL=0; delayus(1); return temp; 此时,我们还需要添加上ACK回应信号。我们先来看看它的时序图。图5 ACK 应答信号 从时序图我们可以看出,ACK就是24C04还给单片机的一个低电平信号,它发生在第九个时钟脉冲上。如果我们用不到哪个ACK的话,我们只需要给出第九个时钟脉冲就可以了。示例程序如下。 void I2C_ACK() unsigned char i;/可以去掉 AT24C04_SCL=1;delayus(1); while(AT24C04_SDA=1)&(i511)/这部分可以去掉 i+;/可以去掉 AT2

10、4C04_SCL=0;delayus(1);以上三个是读写的重要子函数,加上开始和停止,有关于AT24C04的函数部分,都是由这五个组成的。下面我们来分析一下可操作的和写。先来分析写字节函数吧。下面是它的时序图。图6 字节写时序从时序图中我们可以看到,第一部分是开始(START),这部分调用开始函数就可以了。第二部分器件地址,这个是由单片机发送给24C04的,选用写子函数就可以了。别忘了还有一个ACK应答。第三部分是字节地址,就是你想把要存储的数据存储到哪个单元里。第四部分是发送要存储的数据。第五部分就是停止部分(STOP)。现在我们来分析一下什么是器件地址吧。在I2C总线的协议中,某些器件被

11、指定为特定的地址,这个特定的地址占用了器件地址的前四位。具体的怎么定义的可以参考部分资料。I2C器件的手册里也给出了自己的器件地址。我们以AT24C04的器件地址为例分析吧。图7 AT24C04的器件地址A2,A1是我们自己可以选择的,对应的是可以接地或者接高电平。a8是可以用单片机控制的,但是我们的实验板上直接当做A0给接地处理了。这样做虽然是使器件地址变简单了,但是,24c04有一半的存储区域我们没有用到,也就相当于用了一个AT24C02了。最后一位读写控制位,从非号“”我们看出,此位是1表示读,此位是0则表示写!那么我们就可以得到对24C04写的器件地址是0XA0,读的器件地址是0XA1

12、(见图1)。由此我们就可以按顺序写出字节写的子函数了。如下所示。void I2C_xie(unsigned char data5,unsigned char data6) I2C_START(); I2C_Wdata(0xa0);/写入型总线 I2C_ACK(); I2C_Wdata(data5);/写入数据的存储地址 I2C_ACK(); I2C_Wdata(data6);/待写入的数据 I2C_ACK(); I2C_STOP();我们在用同样的方法分析一下选择性读的时序。时序图如下。图8 选择性读时序图有这个图我们可以分析到如下的选择性读子函数。unsigned char I2C_du(u

13、nsigned char data7) unsigned char data8; I2C_START(); I2C_Wdata(0xa0);/写入型总线 I2C_ACK(); I2C_Wdata(data7);/需要读出数据的地址 I2C_ACK(); I2C_START();/再一次重新开始 I2C_Wdata(0xa1);/读出型总线 I2C_ACK(); data8=I2C_Rdata();/转存读出的数据 I2C_STOP(); return data8;/返回读出的数据现在我们基本上就把AT24C04的读写的部分完成了。至于PDF中提到的其他的用法,大家可以自己琢磨琢磨。比如,下面是

14、页写的时序图。图9 页写时序图我们就得到了如下的页写程序。/* * AT24C04页写函数 变量:data5 页写首地址 data6 页写的数据的个数* */void I2C_YExie(unsigned char data5,unsigned char data6) unsigned char *p; unsigned char i; unsigned char k; p=tab; /unsigned char tab= / 0123456789 / ; k=data6; I2C_START(); I2C_Wdata(0xa0); I2C_ACK(); I2C_Wdata(data5); I

15、2C_ACK(); for(i=0;ik;i+) I2C_Wdata(*p+); I2C_ACK(); I2C_STOP();4、对应源程序最后附上全体函数,有利于大家临摹学习。使用实验板的时候,先调节跳线帽的位置并添加上1602液晶,程序使用的是1602A(即普通16脚液晶)显示。按照按键电路图的顺序定义K1,K2,K3和K4。K1是显示的数据加1,K2是显示的数据减1,K3是将显示的数据存储进AT24C04中,K4是将存储在AT24C04中的数据显示出来。这个函数没有使用到页写和一些其他的功能,大家可以自己写一个更好的,将存储的字节位置也能够用户定义。网上有些不错的例子,比如通过每次复位初

16、始化的时候给AT24C04中的一个数据加1来统计单片机复位的次数。大家可以试着写一下,无非就是对一个存储的数据先读,加1,在写回到原来的存储字节中。#include /*/sbit LCD1602_RS=P27;sbit LCD1602_RW=P26;sbit LCD1602_E=P25;sbit AT24C04_SCL=P37;sbit AT24C04_SDA=P36;/*/unsigned char x;/用于统计计数,存入unsigned char tab= 0123456789;/*/void delayus(unsigned int us) while(us-);void delay

17、ms(unsigned int ms) unsigned int i; while(ms-) for(i=0;i125;i+) ; /*液晶显示程序 返回*/void LCD_WByte(unsigned char data1,unsigned char data2) P0=data2; LCD1602_RS=data1;/0为指令,1为数据 LCD1602_RW=0;/写入 LCD1602_E=1;/下降沿有效 LCD1602_E=0; delayus(20);/执行指令用40us/*/void LCD_chushihua() LCD_WByte(0,0x38); LCD_WByte(0,0

18、x0c); LCD_WByte(0,0x06); LCD_WByte(0,0x01);/清屏 delayms(2);/等待2毫秒到清屏结束/* *单个字符显示函数 变量:x 在1602第一行的第x个位置显示 data3 需要显示的字符*/void LCD_disp(unsigned char x,unsigned data3) unsigned char add; add=0x80+x; LCD_WByte(0,add); LCD_WByte(1,*tab+data3);/使用表格来显示数字字符void LCD_disps(unsigned char *dat4)/字符串显示函数 unsign

19、ed char *p; p=dat4; LCD_WByte(0,0);/显示的位置为初始坐标 while(*p!=0) LCD_WByte(1,*p+); /*/void xianshi(unsigned char data9) unsigned char i; i=data9/100; LCD_disp(10,i); i=(data9%100)/10; LCD_disp(11,i); i=data9%10; LCD_disp(12,i);/*/void I2C_START() /AT24C04_SCL=0;delayus(1);/这样做有些繁琐,我们可以直接不用 AT24C04_SDA=1;

20、delayus(1);/注意先后顺序 AT24C04_SCL=1;delayus(1); AT24C04_SDA=0;delayus(1);/下降沿开始 AT24C04_SCL=0;delayus(1);void I2C_STOP() AT24C04_SCL=0;delayus(1); AT24C04_SDA=0;delayus(1); AT24C04_SCL=1;delayus(1); AT24C04_SDA=1;delayus(1);/上升沿停止/*/void I2C_Wdata(unsigned char data4) unsigned char i; unsigned char tem

21、p; temp=data4; for(i=0;i8;i+) AT24C04_SCL=0; temp=temp1;/先发送高位 AT24C04_SDA=CY;delayus(1); AT24C04_SCL=1;delayus(1); AT24C04_SCL=0;delayus(1);/*/unsigned char I2C_Rdata() unsigned char i; unsigned char temp; unsigned char k; AT24C04_SCL=0;delayus(1); AT24C04_SDA=1;/等待24C02发回来的信号 for(i=0;i8;i+) AT24C0

22、4_SCL=1;delayus(1); if(AT24C04_SDA=1) k=1; else k=0; temp=temp1; temp=temp|k;/读数据时高位在前 AT24C04_SCL=0; delayus(1); return temp; /*/void I2C_ACK() /unsigned char i; AT24C04_SCL=1;delayus(1); /while(AT24C04_SDA=1)&(i511) /i+; AT24C04_SCL=0;delayus(1);/* * 给AT24C04写数据 变量:data5 要写入的地址 data6 要写入的数据 _ _ _

23、_ _ _ _ _ AT24C04 | 1| 0| 1| 0|A2|A1|A0|RW| 器件地址 * */void I2C_xie(unsigned char data5,unsigned char data6) I2C_START(); I2C_Wdata(0xa0); I2C_ACK(); I2C_Wdata(data5); I2C_ACK(); I2C_Wdata(data6); I2C_ACK(); I2C_STOP();/* * AT24C04页写函数 变量:data5 页写首地址 data6 页写的数据的个数* */* void I2C_YExie(unsigned char da

24、ta5,unsigned char data6) unsigned char *p; unsigned char i; unsigned char k; p=tab; /unsigned char tab= / 0123456789 / ; k=data6; I2C_START(); I2C_Wdata(0xa0); I2C_ACK(); I2C_Wdata(data5); I2C_ACK(); for(i=0;ik;i+) I2C_Wdata(*p+); I2C_ACK(); I2C_STOP(); */* * 读AT24C04中的数据 变量: data7 要读出数据的地址 返回读出的数据d

25、ata8*/unsigned char I2C_du(unsigned char data7) unsigned char data8; I2C_START(); I2C_Wdata(0xa0); I2C_ACK(); I2C_Wdata(data7); I2C_ACK(); I2C_START(); I2C_Wdata(0xa1); I2C_ACK(); data8=I2C_Rdata(); I2C_STOP(); return data8;/*按键程序 返回*/unsigned char scan_key(void) unsigned char temp; temp=P1; return temp; unsigned char KEY_pad() unsigned char key_val; key_val=scan

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1