课程设计(论文)-基于I2C协议的EEPROM读写功能实现.doc_第1页
课程设计(论文)-基于I2C协议的EEPROM读写功能实现.doc_第2页
课程设计(论文)-基于I2C协议的EEPROM读写功能实现.doc_第3页
课程设计(论文)-基于I2C协议的EEPROM读写功能实现.doc_第4页
课程设计(论文)-基于I2C协议的EEPROM读写功能实现.doc_第5页
已阅读5页,还剩19页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

基于i2c协议eeprom读写功能的实现目录一设计要求2二设计目的2三器件eeprom的介绍21eeprom简介22eeprom24xx系列功能概述2四i2c协议的介绍31i2c协议总线特征32 i2c协议工作原理33i2c协议总线基本状态34寻址约定5五eeprom读写功能实现51写操作5(1)字节写操作6(2)页写入操作62确认查询73读操作7(1)当前地址的读操作8(2)随机读操作8(3)连续读操作9六具体设计过程101程序流程图102系统组成模块结构及功能12(1)函数定义12(2)主函数main( )133源程序14七设计心得体会23八参考文献24基于i2c协议的eeprom读写功能实现一设计要求 1)通过软件基于i2c协议对eeprom读写功能的实现。 2)需要有eeprom读写功能的具体实现过程 。二设计目的 通过设计,了解i2c协议的基本原理,并对eeprom读写功能的实现有个系统的概念,对其实现过程比较清楚。同时,在设计中,巩固我们所学的理论知识。三器件eeprom的介绍1eeprom简介eeprom (electrically erasable programmable read-only memory),电可擦可编程只读存储器-一种掉电后数据不丢失的存储芯片。 eeprom 可以在电脑上或专用设备上擦除已有信息,重新编程。 eeprom即电可擦写可编程只读存储器,其可通过高于普通电压的作用来擦除和重编程(重写)。不像eprom芯片,eeprom不需从计算机中取出即可修改。在一个eeprom中,当计算机在使用的时候是可频繁地重编程的,eeprom的寿命是一个很重要的设计考虑参数。eeprom的一种特殊形式是闪存,其应用通常是个人电脑中的电压来擦写和重编程。dram断电后存在其中的数据会丢失,而eeprom断电后存在其中的数据不会丢失。 另外,eeprom可以清除存储数据和再编程。 2eeprom24xx系列功能概述1)每一个24xx 器件都支持双向。2)线数据传输协议:如果器件被定义为发送器,则该器件发送数据到总线;如果器件被定义为接收器,则该器件接收来自总线的数据。总线由主器件控制, 24xx 作为从器件。主器件提供串行时钟(scl),控制总线访问和产生起始和停止条件。主器件和从器件皆可作为发送器或接收器,但必须由主器件决定采取何种工作模式。四i2c协议的介绍1i2c协议总线特征总线协议定义如下: 只有在总线空闲时才可启动数据传输。 数据传输期间,在时钟线为高电平时,无论何时,数据线都必须保持稳定。在时钟线为高电平时改变数据线将视为起始或停止条件。i2c总线最主要的优点是其简单性和有效性。由于接口直接在组件之上,因此i2c总线占用的空间非常小,减少了电路板的空间和芯片管脚的数量,降低了互联成本。总线的长度可高达25英尺,并且能够以10kbps的最大传输速率支持40个组件。i2c总线的另一个优点是,它支持多主控,其中任何能够进行发送和接收的设备都可以成为主总线。一个主控能够控制信号的传输和时钟频率。当然,在任何时间点上只能有一个主控。2 i2c协议工作原理 以启动信号start来掌管总线,以停止信号stop来释放总线;每次通讯以start开始,以stop结束;启动信号start后紧接着发送一个地址字节,其中7位为被控器件的地址码,一位为读/写控制位r/w,r. /w位为0表示由主控向被控器件写数据,r/w为1表示由主控向被控器件读数据;当被控器件检测到收到的地址与自己的地址相同时,在第9个时钟期间反馈应答信号;每个数据字节在传送时都是高位(msb)在前。 3i2c协议总线基本状态1)总线空闲(a)数据线和时钟线同时为高电平。2)启动数据传输(b)时钟(scl)为高电平时,sda 从高电平变为低电平表示起始条件产生。起始条件必须先于所有的命令产生。3)停止数据传输(c)时钟(scl)为高电平时, sda 从低电平变为高电平表示停止条件产生。所有操作都必须以停止条件结束。4)数据传送/数据有效 (d)数据线的状态表明数据何时有效。在起始条件之后,数据线在时钟处于高电平期间保持稳定。必须在时钟信号为低电平期间改变数据线。一个数据位对应一个时钟脉冲。数据的每次传输以起始条件开始,以停止条件结束。在起始条件和停止条件之间传输的数据字节数目由主器件决定图1 i2c总线在传输数据位时的sda和scl的基本状态5)确认信号(ack)每一个被寻址的接收器在接收到每一字节数据后,应发送一个确认位。主器件必须提供一个额外的时钟以传输确认位。在确认时钟脉冲内,器件确认须拉低 sda 线。在确认时钟的高电平期间,sda线以这种方式保持稳定的低电平。当然,还必须考虑建立时间和保持时间。读操作期间,主器件必须发送一个结束信号给从器件,而不是在从器件输出最后一个数据字节之后产生一个确认位。这种情况下,从器件(24xx)将释放数据线为高电平,从而使主器件能够产生停止条件。图2 确认时序6)无应答信号(nack)在时钟的第9个脉冲期间发送器释放数据总线,接收器不拉低数据总线表示一个 nack,nack有两种用途:a、一般表示接收器未成功接收数据字节;b、当接收器是主控器时,它收到最后一个字节后,应发送一个nack信号,以通知被控发送器结束数据发送,并释放总线,以便主控接收器发送一个停止信号stop。4寻址约定1)不带功能性地址输入引脚的器件寻址在起始条件之后,从主器件接收的第一个字节是控制字节。控制字节以4 位控制码开始。对于24xx器件,这4 位设置为 1010以便进行读写操作。随后的3 位为存储块选择位 (b2、 b1、 b0)。主器件用它们来选择将要访问的大小为 256 字的存储块。实际上,这些位是字地址中3 个最高有效位。控制字节的最后一位定义将要进行的操作。 设置为1,选择读操作;设置为0,选择写操作。在起始条件发生后,24xx 器件始终监视sda 总线。一旦接收到 1010码、存储块选择位和 r/w 位,从器件输出确认信号到 sda 总线。在确认信号之后传输地址字节。2)带功能性地址输入引脚的器件寻址在起始条件之后,从主器件接收的第一个字节是控制字节。控制字节以4 位控制码开始。在24xx器件,这4 位设置为 1010以便进行读写操作。随后的3 位 为片选位(a2、 a1、 a0)。片选位的不同组合允许在同一条总线上使用的24xx 器件达八个,并用于选择访问哪一个器件。控制寄存器中的片选位必须与相应器件引脚a2、 a1 和 a0上的逻辑电平保持一致。实际上这些位是字地址中3 个最高有效位。起始条件发生之后,24xx 器件始终监视sda 总线。一旦接收到 1010码、器件片选位和 r/w 位,从器件输出确认信号到 sda 总线。在确认信号之后传输地址字节。五eeprom读写功能实现1写操作写数据过程:1)主控在检测到总线空闲的状况下,首先发送一个start信号掌管总线;2)发送一个控制字节(包括7位器件地址码和一位r/w);(某些器件的地址字节可能带有其他功能)3)当被控器件检测到主控发送的地址与自己的地址相同时发送一个应答信号(ack);4)主控收到ack后开始发送第一个数据字节;5)被控器收到数据字节后发送一个ack表示继续传送数据,发送nack表示传送数据结束;6)主控发送完全部数据后,发送一个停止位stop,结束整个通讯并且释放总线;写数据时序。(1)字节写操作字节写操作以来自于主器件的起始位开始, 4 位控制码紧随其后(图3)。接下来的3 位是存储块寻址位(不带地址输入引脚的器件)或片选位(带地址输入引脚的器件)。然后主发送器将r/w 位(该位为逻辑低电平)发送到总线。从器件在第九个时钟周期产生一个确认位,主器件发送的第二个字节是地址字节或高位地址字节。24xx 器件会对每一个地址字节作出确认,并把地址位锁存进器件内部的地址计数器。对于24xx00 器件,只使用地址字节的低4 位。高4 位可为任意值。送出最后一个地址字节后, 24xx 器件发出确认信号ack。主器件在接收到该确认信号后即发送数据字,该数据字将被写入已寻址的存储器位置。24xx 器件再次发出确认信号,之后主器件产生停止条件,启动内部写周期。如果在 wp 引脚保持高电平时进行存储器写操作,器件会确认命令,但不会启动写周期,也不会写入数据,而会立即接受新的命令。写命令为一个字节,在发送写命令后,内部地址计数器增加,指向下一个要寻址的位置。写周期期间, 24xx 不会对命令进行确认。图3 字节写操作(注:图中控制字节指器件地址码和读写控制位;地址字节指器件内部的储存器地址。下同。)(2)页写入操作页写入操作时,被控器件完成一个写字节操作后内部地址计数器自动加一。写控制字节、字地址字节和首个数据字节以和写操作字节基本相同的方式发送给 24xx 器件(见图4 )。不同的是,主器件发送的是多至一整页的数据字节(1),而不是停止条件,这些数据字节临时存储在片内页缓冲器中。在主器件发送停止条件之后,这些数据将被写入存储器。每接收一个字,内部地址计数器加一。如果在停止条件产生前,主器件有超出一页的数据要发送,地址计数器将会翻转,先前写入的数据将被覆盖。对于字节写操作,一旦接收到停止条件,内部写周期开始。在写周期期间, 24xx 器件不会对命令作出确认。页写入操作在一页内可以写入任意个数的数据(最多为一页),并且可以在此页中的任意地址开始写入。被寻址的数据只能在该页内变动。如果在 wp 引脚保持高电平时进行存储器写操作,器件会确认命令,但不会启动写周期,也不会写入数据,而是立即接受新的命令。图4 页写入操作2确认查询在写周期期间器件不会对命令作出确认,这可用来确定写周期何时完成(这个特点可以优化总线的吞吐量,使其最大化) 。如果主器件已经发出写命令的停止条件,器件将启动内部定时写周期。可以随时进行确认查询。这包括在主器件发出起始条件后,再发送用于写命令(r/w = 0)的控制字节。如果器件仍处在写周期内,则不返回确认信号。一旦没有返回确认信号,起始位和控制字节必须重新发送。如果写周期结束,器件返回确认信号,主器件就可以执行下一个读或写命令。参见流程图( 图 9)。3读操作读数据过程:1)主控在检测到总线空闲的状况下,首先发送一个start信号掌管总线;2)发送一个控制字节(包括7位器件地址码和一位r/w);(某些器件的地址字节可能带有其他功能)3)当被控器件检测到主控发送的地址与自己的地址相同时发送一个应答信号(ack);4)主控收到ack后释放数据总线,开始接收第一个数据字节;5)主控收到数据后发送ack表示继续传送数据,发送nack表示传送数据结束;6)主控发送完全部数据后,发送一个停止位stop,结束整个通讯并且释放总线;除了控制寄存器的r/w 位设置为1外,读操作与写操作基本相同。有三种基本的读操作:当前地址的读操作、随机读操作和连续读操作 。(1)当前地址的读操作当前地址的读操作,被控器件内部储存器地址计数器保留最后一次访问的地址。24xx 内置一个自动加1地址计数器,该计数器保留最后一次访问的地址。因此,如果先前对地址n(n 为任意合法地址)进行读或写操作,则下一条读操作命令将可能从地址n+1 访问数据。接收到r/w 位设置为1的控制字节后,24xx 发出确认信号,并发送 8 位数据字节。主器件不会对数据传输作出确认,但会产生停止条件,24xx 即停止数据发送(图5)图5 当前地址读操作 (2)随机读操作随机读操作允许主器件以随机方式访问任意存储器,主控器件先发写命令,然后发要读的地址,然后发读命令。执行该指令前必须先设置地址字节。作为写操作的一部分,通过发送字节地址给24xx 来完成地址字节的设置(r/w 设置为0)。字节地址发送完后,主器件一接收到确认信号即产生起始条件。内部地址计数器设置完之后写操作即被终止。主器件再次发送控制字节,而该字节中 r/w 位设置为1。之后24xx 会发出确认信号, 并发送8 位数据字节。主器件不会对数据传输作出确认,但会产生停止条件, 24xx 即停止数据发送(图6)。在随机读取命令之后,内部地址计数器加1 指向下一条地址。图6 随机读操作(3)连续读操作连续读操作的起动过程和随机读操作相同,只是在24xx发送完第一个数据字节后,主器件发出确认信号,而在随机读操作中发送的是停止条件,在连续读操作时被控器件完成一个读字节操作后内部地址计数器自动加一。确认信号指示24xx 器件发送下一个连续地址的数据字节(图7)。在24器件向主器件发送完最后一个字节后,主器件不会产生确认信号,而是产生停止条件。为了可以进行连续读操作, 24xx 器件内置了一个地址指针,在每次操作完成后该指针加1。地址指针允许一次操作连续读取整个存储器的内容。在达到最后一个地址字节后,地址指针将翻转到地址 0x00。图7 连续读操作六具体设计过程1程序流程图启动i2c总线发送控制字节检测应答信号ack发送第一个数据字节检测应答信号ack继续传送数据发送停止位,释放i2c总线完成数据的写操作传送数据结束nyny图 8 写数据的流程图发送写命令发送停止条件以启动写周期发送起始位发送控制字节(其中 r/w = 0)器件确认否?(ack = 0)?ny下一步操作图9 确认查询流程图启动i2c总线发送控制字节检测应答信号ack释放总线,接收第一个数据字节检测应答信号ack继续接收数据发送停止位,释放i2c总线完成数据的读操作传送数据结束nyny图10 读数据流程图2系统组成模块结构及功能(1)函数定义函数定义是对各个基础函数的定义,并且设置需要运用的信息,便于调用#include#include #include#define delay_time 60 /*延时时间*/ #define true 1/*设置ack*/#define false 0/*定义0为错误*/sbit scl=p17;sbit sda=p16; /*假设由p1.7和p1.6控制*/void delay(unsigned int t) /*延时函数*/void i2c_start(void) /*启动i2c总线*/void i2c_stop(void) /*终止i2c总线*/void send_0(void) /* 设置时钟,发送0,在scl为高电平时使sda信号为低*/void send_1(void) /* 设置时钟,发送1,在scl为高电平时使sda信号为高*/bit check_acknowledge(void) /*发送完一个字节后检验设备的应答信号*/void writei2cbyte(char b)reentrant/*向i2c总线写一个字节*/char readi2cbyte(void)reentrant/*从i2c总线读一个字节*/void write_one_byte(char addr,char thedata) /*字节写入函数*/void write_a_page(char *buffer,char addr) /*页写入函数*/char read_one_byte(char addr) /*随机读函数*/void read_n_bytes(char *buffer,char n,char addr) /*顺序读函数*/(2)主函数main( )主函数是程序的主流程,首先定义使用到的常数、全局变量及函数原型说明,然后初始化图形系统,调用函数 write_one_byte(char addr,char thedata) 完成字节写入,调用write_a_page(char *buffer,char addr) 完成页写入,调用 read_one_byte(char addr) 完成随机读,调用read_n_bytes(char *buffer,char n,char addr) /*完成顺序读*/。void main() int i; char mybyte; char myarray8; char myarray28; char rdarray16; for(i=0;i8;i+) myarrayi=i; myarray2i=i+0x08; write_one_byte(0x20,0x28); write_a_page(myarray,0x10); write_a_page(myarray2,0x18); mybyte=read_one_byte(0x20); read_n_bytes(rdarray,16,0x10);3源程序 /*/#include #include #include#define delay_time 60 /*经实验,不要小于50!否则可能造成时序混乱*/ #define true 1 #define false 0sbit scl=p17;/*假设由p1.7和p1.6控制*/sbit sda=p16;/* function definition函数定义 */void delay(unsigned int t) /*延时函数*/ while(t!=0)t-; void i2c_start(void) /*启动i2c总线的函数,当scl为高电平时使sda产生一个负跳变*/ sda=1; scl=1; delay(delay_time); sda=0; delay(delay_time); scl=0; delay(delay_time); void i2c_stop(void) /*终止i2c总线,当scl为高电平时使sda产生一个正跳变*/ sda=0; scl=1; delay(delay_time); sda=1; delay(delay_time); scl=0; delay(delay_time);void send_0(void) /* 设置时钟 */ /*发送0,在scl为高电平时使sda信号为低*/ sda=0; scl=1; delay(delay_time); scl=0; delay(delay_time); void send_1(void) /*发送1,在scl为高电平时使sda信号为高*/ sda=1; scl=1; delay(delay_time); scl=0; delay(delay_time); bit check_acknowledge(void) /*发送完一个字节后检验设备的应答信号*/ sda=1; scl=1; delay(delay_time/2); f0=sda; delay(delay_time/2); scl=0; delay(delay_time); if(f0=1) return false; return true; void writei2cbyte(char b)reentrant /*向i2c总线写一个字节*/ char i; for(i=0;i8;i+) if(bi)&0x80) send_1(); else send_0(); char readi2cbyte(void)reentrant /*从i2c总线读一个字节*/ char b=0,i; for(i=0;i8;i+) sda=1; /*释放总线*/ scl=1; /*接受数据*/ delay(10); f0=sda; delay(10); scl=0; if(f0=1) b=b1; b=b|0x01; else b=b1; return b;/*以下为读写函数*/void write_one_byte(char addr,char thedata)bit acktemp=1; /*write a byte to mem*/ i2c_start(); writei2cbyte(0xa0); acktemp=check_acknowledge(); writei2cbyte(addr);/*address*/ acktemp=check_acknowledge(); writei2cbyte(thedata);/*thedata*/ acktemp=check_acknowledge(); i2c_stop();void write_a_page(char *buffer,char addr) bit acktemp=1; bit wrtmp; int i; /*write a page to at24c02*/ i2c_start(); writei2cbyte(0xa0); acktemp=check_acknowledge(); writei2cbyte(addr);/*address*/ acktemp=check_acknowledge(); for(i=0;i7;i+) writei2cbyte(bufferi); if(!check_acknowledge() i2c_stop(); i2c_stop();char read_one_byte(char addr) bit acktemp=1; char mydata; /*read a byte from mem*/ i2c_start(); writei2cbyte(0xa0); acktemp=check_acknowledge(); writei2cbyte(addr);/*address*/ acktemp=check_acknowledge(); i2c_start(); writei2cbyte(0xa1); acktemp=check_acknowledge(); mydata=readi2cbyte(); acktemp=check_acknowledge(); return mydata; i2c_stop();void read_n_bytes(char *buffer,char n,char addr) bit acktemp=1; int i=0; /*read 8 bytes from mem*/ i2c_start(); writei2cbyte(0xa0); acktemp=check_acknowledge(); writei2cbyte(addr);/*address*/ acktemp=check_acknowledge(); i2c_start(); writei2cby

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论