24LC65 I2C EEPROM字节读写驱动程序
- 格式:doc
- 大小:39.00 KB
- 文档页数:6
通过I2C通讯协议对EEPROM进行读写操作发送串口进行通讯一.描述I2CI2C协议有启动,终止,应答,非应答四种信号,有按位发送数据,按位接收数据,有读操作和写操作。
1.启动I2C程序如下,保持SCL为高电平,SDA为高电平,当检测到SDA下降沿时,启动传送,如果2个信号没有被高则返回0。
程序启动成功返回1。
uint8 I2C_Start(void){CyDelayUs(10);SDA_Write(1);CyDelayUs(10);SCL_Write(1);CyDelayUs(10);if ( SDA_Read() == 0) return 0;if ( SCL_Read() == 0) return 0;SDA_Write(0);CyDelayUs(10);SCL_Write(0);CyDelayUs(10);return 1;}上面是模仿I2C启动时序2.终止传送程序如下SDA保持低电平SCL保持高电平而后拉高SDA,系统检测到SDA上升沿则终止传送。
void I2C_Stop(void){CyDelayUs(10);SDA_Write(0);CyDelayUs(10);SCL_Write(1);CyDelayUs(10);SDA_Write(1);CyDelayUs(10);}3.模拟应答信号,让SDA的低电平时间大于SCL的高电平时间,即可应答;也就是SDAvoid I2C_Ack(void){CyDelayUs(10);SDA_Write(0);CyDelayUs(10);SCL_Write(1);CyDelayUs(10);SCL_Write(0);CyDelayUs(10);}4.模拟非应答信号,让SDA的高电平时间大于SCL高电平时间,就是非应答void I2C_Nack(void){CyDelayUs(10);SDA_Write(1);CyDelayUs(10);SCL_Write(1);CyDelayUs(10);SCL_Write(0);CyDelayUs(10);}5.按位发送数据,按位发送数据的要求是数据位高电平的时间大于SCL,SCL高电平时不允许数据位电平变化,只有SCL低电平时才可以任意变换。
Linux环境下基于I2C总线的EEPROM 驱动程序1 引言I2C (Inter-Integrated Circuit1总线是一种由Philips公司开发的2线式串行总线,用于连接微控制器及其外围设备。
它是同步通信的一种特殊形式,具有接口线少、控制方式简单、器件封装形式小、通信速率较高等优点。
在主从通信中,可有多个I2C总线器件同时接到I2C总线上,通过地址来识别通信对象。
笔者在开发基于MPC8250的嵌入式Linux系统的过程中发现I2C总线在嵌入式系统中应用广泛,I2C总线控制器的类型比较多,对系统提供的操作接口差别也很大。
与I2C总线相连的从设备主要有微控制器、EEPROM、实时时钟、A/D转换器等.MPC8250处理器正是通过内部的I2C总线控制器来和这些连接在I2C总线上的设备进行数据交换的。
由于I2C总线的特性,Linux的I2C总线设备驱动程序的设计者在设计驱动程序时采用了独特的体系结构。
使开发I2C总线设备驱动程序与开发一般设备驱动程序的方法具有很大差别。
因此,开发I2C总线设备驱动程序除了要涉及一般Linux内核驱动程序的知识外.还要对I2C总线驱动的体系结构有深入的了解。
笔者在开发过程中使用设备型号为AT24C01A的EEPROM 来测试I2C总线驱动。
2 工作原理概述在介绍I2C总线结构之前。
要搞清楚两个概念:I2C总线控制器和I2C设备。
I2C总线控制器为微控制器或微处理器提供控制I2C总线的接口,它控制所有I2C总线的特殊序列、协议、仲裁、时序,这里指MPC8250提供的I2C总线控制接口。
I2C设备是指通过I2C总线与微控制器或微处理器相连的设备,如EEPROM、LCD驱动器等,这里指EEPROM。
在一个串行数据通道中.I2C总线控制器可以配置成主模式或从模式。
开发过程中,MPC8250的I2C总线控制器工作在主模式,作为主设备;与总线相连的I2C设备为AT24C01A 型EEPROM,作为从设备。
I2C24LC02C读写例程(PIC单片机)I2C 24LC02 C读写例程(PIC单片机)[单片机]发布时间:2008-04-22 10:11:001 I2C总线特点I2C总线最主要的优点是其简单性和有效性。
由于接口直接在组件之上,因此I2C总线占用的空间非常小,减少了电路板的空间和芯片管脚的数量,降低了互联成本。
总线的长度可高达25英尺,并且能够以10Kbps的最大传输速率支持40个组件。
I2C总线的另一个优点是,它支持多主控(multimastering),其中任何能够进行发送和接收的设备都可以成为主总线。
一个主控能够控制信号的传输和时钟频率。
当然,在任何时间点上只能有一个主控。
2 I2C总线工作原理I2C总线上的数据稳定规则,SCL为高电平时SDA上的数据保持稳定,SCL为低电平时允许SDA变化。
如果SCL处于高电平时,SDA 上产生下降沿,则认为是起始位,SDA上的上升沿认为是停止位。
通信速率分为常规模式(时钟频率100kHz)和快速模式(时钟频率400kHz)。
同一总线上可以连接多个带有I2C接口的器件,每个器件都有一个唯一的地址,既可以是单接收的器件,也可以是能够接收发送的器件。
每次数据传输都是以一个起始位开始,而以停止位结束。
传输的字节数没有限制。
最高有效位将首先被传输,接收方收到第8位数据后会发出应答位。
数据传输通常分为两种:主设备发送从设备接收和从设备发送主设备接收。
这两种模式都需要主机发送起始位和停止位,应答位由接收方产生。
从设备地址一般是1或2个字节,用于区分连接在同一I2C上的不同器件。
I2C总线在传送数据过程中共有三种类型信号,它们分别是:开始信号、结束信号和应答信号。
开始信号:SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据。
结束信号:SCL为高电平时,SDA由低电平向高电平跳变,结束传送数据。
应答信号:接收数据的IC在接收到8bit数据后,向发送数据的IC 发出特定的低电平脉冲,表示已收到数据。
I2C总线的读操作的流程
M24Cxx的读操作模式及其各种模式的操作流程如图1、图2所示。
1. 当前地址读
EEPROM内部具有保持当前地址的寄存器。
读取当前地址的数据时,不需要指定地址。
只要单纯给出读指令就可读出数据。
读取完毕后,内部所保持的当前地址将自动进位。
数据读操作后的ACK/NoACK信号由主机返回,但必须返回NoACK信号。
2. 随机读
随机读是由主机指定任意的地址读取的。
利用写指令设定地址,如果赋予读指令则可以读出当前地址。
所以,与字节写操作时相同,在第1字节的数据后面给出地址。
在这里,一旦发送出数据就成为写操作,在此设置开始条件,取消向写操作的迁移而发出读指令,将从事先设定的地址中读出数据。
此时,DEVSEL数据(前7位数据)必须设定与最初写指令所发送的相同的值。
3. 顺序读
在当前地址读操作之后,如果主机返田ACK信号,则为顺序读模式,器件将准备下一个地址的数据,主机取回该数据。
一旦到达要读出的最终地址,主机将返回NoACK信号,通知器件这已是最后的数据。
4. 顺序随机读
当指定任意地址、希望由此连续读出数据时,可利用该模式。
只要认为这是与对应于当前读的顺序读相同的模式即可。
顺序随机读模式与随机读同样进行读操作,接收到数据后如果是ACK应答,则器件将准各下一个地址的数据;如果是最终数据,则返回NoACK信号,结束数据的传输。
欢迎转载,信息。
单片机模拟I2C总线读写EEPROM(24CXX)程序一下面是一个最简单的读写程序,可以用来检测线路状况。
先附上程序和电路,后面附有说明。
电路:说明:P2 口的LED 都是我用来检测电路执行到哪一步的,个人觉得一目了然。
程序:#include #define unit unsigned int#define uchar unsigned charint ok;sbit scl=P0;sbit sda=P0;sb it led0=P2;sbit led1=P2;sb it led2=P2 ;sbit led3=P2;sb it led4=P2;sb it led5=P2 ;sbit led6=P2;sb it led7=P2;delay(void) //delay{ int i; led1=1; for(i=0;istart(void) //start{ sda=1; scl=1; delay(); sda=0; delay(); scl=0; led0=0;}stop(void) //stop{ sda=0; scl=1; delay(); sda=1; delay(); scl=0;}checkanswer(void) //check answer{ sda=1; scl=1; if(sda==1) { F0=1; led7=0; } scl=0; led3=0;}sendabyte(int temps) //send a byte{ uchar n=8; while(n--) { led2=1; if((temps&0x80)==0x80){ sda=1; scl=1; delay(); scl=0;}else{ sda=0; scl=1; delay(); scl=0;}temps=tempsreciveabyte() //recive a byte{ uchar n=8,tempr; while(n--) {//uchar idata *abyte scl=1;tempr=temprmain(void) //MAIN{start();sendabyte(0xa0);checkanswer();if(F0==1) return;sendabyte(0x00);checkanswer();if(F0==1) return;sendabyte(0x11);checkanswer();if(F0==1) return;/*-----------------------*/start(); sendabyte(0xa0);checkanswer();if(F0==1) return;。
#ifndef _24cXX_H#define _24cXX_H/* Includes ----------------------------------------------------------------*/#include "stm32f10x.h"#include "value.h"//#include "stdbool.h"/* Define ------------------------------------------------------------------*//* EEPROM Addresses defines *///注:32 64 的字地址是16位2个字节如果使用32或64请简单修改驱动即可#define WC24cXX 0x00 // 器件地址写#define RC24cXX 0x01 // 器件地址读#define USE_24C08 //使用24C08#ifdef USE_24C02#define MAXSIZE24cXX 256 // 总容量Bytes //级联时请修改本参数和硬件驱动#define BLOCK_SIZE 256 // 块容量Bytes#define I2C_PAGESIZE 8 // 8个字节每页#endif#ifdef USE_24C04#define MAXSIZE24cXX 512 // 总容量Bytes //级联时请修改本参数和硬件驱动#define BLOCK_SIZE 256 // 块容量Bytes#define I2C_PAGESIZE 16 // 16个字节每页#endif#ifdef USE_24C08#define MAXSIZE24cXX 1024 // 总容量Bytes //级联时请修改本参数和硬件驱动#define BLOCK_SIZE 256 // 块容量Bytes#define I2C_PAGESIZE 16 // 16个字节每页/* user define */#define YBCV_ADDR_0 0x0000 //定义仪表控制数据结构体的EEPROM 存储地址0#define YBCV_ADDR_1 0x0200 //定义仪表控制数据结构体的EEPROM存储地址1#define EEPROM_VERIFY YB_CTRL_V ALE_SIZE //EEPROM仪表通道修正参数存储地址#endif#ifdef USE_24C16#define MAXSIZE24cXX 2048 // 总容量Bytes#define I2C_PAGESIZE 16 // 16个字节每页#endif#ifdef USE_24C32#define MAXSIZE24cXX 4096 // 总容量Bytes //级联时请修改本参数和硬件驱动#define BLOCK_SIZE 4096 // 块容量Bytes#define I2C_PAGESIZE 32 // 16个字节每页#endif#ifdef USE_24C64#define MAXSIZE24cXX 8192 // 总容量Bytes //级联时请修改本参数和硬件驱动#define BLOCK_SIZE 8192 // 块容量Bytes#define I2C_PAGESIZE 32 // 16个字节每页#endif#define I2CInit I2C_GPIO_Config#define SCL(a) if (a) \GPIO_SetBits(GPIOB, GPIO_Pin_10);\else \GPIO_ResetBits(GPIOB,GPIO_Pin_10)#define SDA(a) if (a) \GPIO_SetBits(GPIOB, GPIO_Pin_11);\else \GPIO_ResetBits(GPIOB,GPIO_Pin_11)#define SCLO GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_10)#define SDAO GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11)/* Private ------------------------------------------------------------------*//* Public -------------------------------------------------------------------*//*uint idata ucSendBuffer[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};uint idata ucReceData;uint idata ucReceiveBuffer[8];//从器件中读出的多字节数据暂存区*//* Function Declaration -----------------------------------------------------*/extern bool I2C2_Init(void);//I2C初始化//extern bool I2C_ByteWrite(u8* pBuffer, u8 WriteAddr); //向24cXX中写入1个字节extern bool I2C_PageWrite(u8* pBuffer, u8 BlockCode, u16 WriteAddr, u8 n); //24cXX页写(不超过一页)extern bool I2C_BlockWrite(u8* pBlock, u8 BlockCode, u16 WriteAddr, u16 n); //24cXX数据块写(不超过BLOCK_SIZE个字节)extern bool I2C_BufferWrite(u8* pBuffer, u16 WriteAddr, u16 n); //24cXX数据写(不超过MAXSIZE24cXX个字节)extern bool I2C_BufferRead(u8* pBuffer, u16 ReadAddr, u16 n); //从24cXX中读出N字节数据(不超过MAXSIZE24cXX个字节)//extern void I2C_EE_WaitEepromStandbyState(void); //等待24CXX内部写周期结束#endif /*_24cXX_H*//******************** (C) COPYRIGHT 2015 XXXXX *********************************** 文件名:24cXX.c* 描述:本函数是xx项目的24cXX的读写函数* 平台:Keil 4 MDK \ stm32 3.5.0库* 库版本:基于野火相关资料及程序上优化修改* 作者:天涯月下红颜醉**********************************************************************************/ /* Includes ------------------------------------------------------------------*/#include "24cXX.h"#include "value.h"#include "systick.h"#include <stdlib.h>/** 函数名:I2C2_Init* 描述:I2C2初始化* 输入:无* 输出:无* 调用:内部调用*/bool I2C2_Init(void){bool s = true;GPIO_InitTypeDef GPIO_InitStructure;/* 使能与I2CGPIO 有关的时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);/* PB10-I2C2_SCL、PB11-I2C2_SDA*/GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; // 普通开漏输出GPIO_Init(GPIOB, &GPIO_InitStructure);SDA(1);SCL(1);Delay_nop();Delay_nop();if(!SDAO) s = false;if(!SCLO) s = false;SDA(0);Delay_nop();Delay_nop();if(SDAO) s = false;SCL(0);Delay_nop();SDA(0);SCL(0);Delay_nop();Delay_nop();if(SDAO) s = false;if(SCLO) s = false;SCL(1);Delay_nop();Delay_nop();SDA(1);return s;}/********开启24cXX的I2C总线********/static bool I2CStart(void){SDA(1);SCL(1);Delay_nop();Delay_nop();if(!SDAO)return false; //SDA线为低电平则总线忙,退出SDA(0);Delay_nop();Delay_nop();if(SDAO)return false; //SDA线为高电平则总线出错,退出SCL(0);Delay_nop();return true;}/********关闭24cXX的I2C总线*******/static void I2CStop(void){SDA(0);SCL(0);Delay_nop();Delay_nop();SCL(1);Delay_nop();Delay_nop();SDA(1);}/*********发送ACK*********/static void I2CAck(void){SDA(0);SCL(0);Delay_nop();// Delay_nop();SCL(1);Delay_nop();// Delay_nop();SCL(0);}/*********发送NO ACK*********/static void I2CNoAck(void){SDA(1);SCL(0);Delay_nop();// Delay_nop();SCL(1);Delay_nop();// Delay_nop();SCL(0);}/*********读取ACK信号*********/static bool I2CWaitAck(void) //返回为:1=有ACK,0=无ACK {SCL(0);SDA(1); //设置SDA为输入Delay_nop();// Delay_nop();SCL(1);Delay_nop();// Delay_nop();if(SDAO){SCL(0);return false;}SCL(0);return true;}/************MCU向24cXX发送一个字节数据*************/ static void I2CSendByte(u8 demand) //数据从高位到低位//{u8 i=8;while(i--){SCL(0);Delay_nop();SDA((bool)(demand&0x80));demand<<=1;Delay_nop();// Delay_nop();SCL(1);Delay_nop();// Delay_nop();}SCL(0);}/*********MCU从24cXX读入一字节数据*********/static u8 I2CReceiveByte(void) //数据从高位到低位//{u8 i=8;u8 ddata=0;SDA(1); //设置SDA为输入while(i--){ddata<<=1; //数据从高位开始读取SCL(0);Delay_nop();// Delay_nop();SCL(1);Delay_nop(); //从高位开始ddata|=SDA;ddata<<=1// Delay_nop();if(SDAO){ddata|=0x01;}}SCL(0);return ddata;}/** 函数名:I2C_EE_WaitEepromStandbyState* 描述:Wait for EEPROM Standby state* 输入:无* 输出:无* 返回:无* 调用:*/static void I2C_EE_WaitEepromStandbyState(u8 BlockCode){int i = 50;do{Delay_us(100);I2CStart();I2CSendByte(BlockCode | WC24cXX);//发送器件地址写}while(I2CWaitAck() == 0 && i-- > 0);I2CStop();}/****************向24cXX中写入1个字节****************//*static bool I2C_ByteWrite(u8* pBuffer, u8 WriteAddr){I2CStart();//启动I2CI2CSendByte(WC24cXX);//发送器件地址写if(I2CWaitAck() == 0)return false;I2CSendByte(WriteAddr);if(I2CWaitAck() == 0)return false;I2CSendByte(*pBuffer);if(I2CWaitAck() == 0)return false;I2CStop();return true;}*//** 函数名:I2C_PageWrite* 描述:在EEPROM的一个写循环中可以写多个字节,但一次写入的字节数* 不能超过EEPROM页的大小。
四川理工学院课程设计书学院计算机学院专业计算机科学与技术班级2013级 4 班课程嵌入式系统软硬件开发及应用实践题目I2C EEPROM读写设计与制作教师杨维剑学生龚程金黄雨杨坤陈超王俊枭摘要随着计算机系统及电子系统的飞速发展,信息的存储也越来越重要,EEPROM (电可擦写可编程只读存储器)是可用户更改的只读存储器(ROM),其可通过高于普通电压的作用来擦除和重编程(重写),断电后存在其中的数据不会丢失,通常用于存放硬件信息,如mac地址、BIOS芯片等,并在嵌入式ARM系统中应用广泛,IIC作为一种常见的总线技术,其方便扩展外围设备的特性使得其应用广泛,AT24C02是一款性价比超高的IIC接口EEPROM,擦写次数多、稳点不易丢失数据,本文将设计并制作ARM系统,并在Linux中实现I2C EEPROM读写。
关键词:ARM,EEPROM,IIC,AT24C02,Linux目录一、LinuxI2C驱动--概述 (1)1.1 设计任务与要求 (1)1.2 I2C (1)1.3 硬件 (1)1.4 软件 (1)二、硬件电路设计 (2)2.1 电路设计要求 (2)2.2 原理图的绘制 (2)2.2.1电源接口 (2)2.2.2UART接口 (3)2.2.3AT24C02接口 (3)2.3 PCB板的制作 (3)三、LinuxI2C驱动--I2C总线 (5)3.1 I2C总线物理结构 (5)3.2 I2C总线特性 (5)3.3 开始和停止条件 (6)3.4 数据传输格式 (6)3.5 响应 (7)3.6 总线仲裁 (8)四、LinuxI2C驱动--解析EEPROM的读写 (9)4.1 概述 (9)4.2 设备地址 (9)4.3 读eeprom (9)4.4 写eeprom (10)五、LinuxI2C驱动--访问eeprom (10)5.1 通过sysfs文件系统访问I2C设备 (10)5.2 通过devfs访问I2C设备 (11)5.3 总结 (11)六、LinuxI2C驱动--浅谈LinuxI2C驱动架构.. 126.1 I2C体系结构 (13)6.2 I2C重要数据结构 (13)七、LinuxI2C驱动--I2C设备驱动 (14)7.1 eeprom板级设备资源 (14)7.2 AT24C02 EEPROM 的I2C设备驱动 (14)7.2.1 at24_driver (14)7.2.3 at24_bin_read() (15)7.2.4 at24_bin_write() (15)7.3 总结 (15)八、LinuxI2C驱动--I2C总线驱动 (16)8.1 三星S3C2410 i2c适配器的硬件描述 (16)8.2 i2c总线驱动的加载/卸载 (17)8.3 i2c总线驱动的probe (17)8.4 启动i2c传输 (18)8.5 通过中断来推进i2c的传输 (18)课程设计体会 (19)参考文献 (20)附录 A (21)附录 B (29)一、LinuxI2C驱动--概述1.1 设计任务与要求1)通过软件基于I2C协议对EEPROM读写功能的实现。
串行通信i2c总线协议简明教程(连接方式,读写时序,24CXX系列EEPROM)一、技术性能:标准速率100kbit/s,快速模式400kbit/s,高速模式略;支持多机通讯;支持多主控模块,但同一时刻只允许有一个主控;由数据线SDA和时钟SCL构成串行总线;每个电路和模块都有唯一的地址;每个器件可以使用独立电源但是必须共地;--------------------------------------------------------------二、连接方式:连接到总线的两个器件端口(SDA和SCL)必须是漏极开路或者集电极开路,这样才能执行线与功能,所以SDA和SCL都还要通过一个上拉电阻接正的电源电压。
--------------------------------------------------------------三、总线基本状态:1、总线空闲(A)数据线和时钟线同时为高电平。
2、启动数据传输(B)时钟(SCL)为高电平时,SDA 从高电平变为低电平表示起始条件产生。
起始条件必须先于所有的命令产生。
3、停止数据传输(C)时钟(SCL)为高电平时,SDA 从低电平变为高电平表示停止条件产生。
所有操作都必须以停止条件结束。
4、数据传送/数据有效(D)数据线的状态表明数据何时有效。
在起始条件之后,数据线在时钟处于高电平期间保持稳定。
必须在时钟信号为低电平期间改变数据线。
一个数据位对应一个时钟脉冲。
数据的每次传输以起始条件开始,以停止条件结束。
在起始条件和停止条件之间传输的数据字节数目由主器件决定。
5、确认信号(ACK)每一个被寻址的接收器在接收到每一字节数据后,应发送一个确认位。
主器件必须提供一个额外的时钟以传输确认位。
在确认时钟脉冲内,器件确认须拉低 SDA 线。
在确认时钟的高电平期间,SDA线以这种方式保持稳定的低电平。
当然,还必须考虑建立时间和保持时间。
6、无应答信号(NACK)在时钟的第9个脉冲期间发送器释放数据总线,接收器不拉低数据总线表示一个 NACK,NACK有两种用途:a、一般表示接收器未成功接收数据字节;b、当接收器是主控器时,它收到最后一个字节后,应发送一个NACK信号,以通知被控发送器结束数据发送,并释放总线,以便主控接收器发送一个停止信号STOP。
K24C系列EEPROM烧写操作流程一:烧录器型号适用于K24C系列EEPROM的烧录器有:周立功EasyPro系列,SmartPro系列、LPC Pro 等二:烧写步骤1)确认烧录器、软件版本支持烧录该型号之组件。
2)将烧录器与电脑连接,并上电。
3)将EEPROM装入烧录器的插座中(注意方向)。
4)鼠标双击桌面上的快捷图标SmartPRO Programmer, 见下图5)弹出下图对话框,选择烧录器的型号,并点击OK。
若无需选择直接跳过这一步。
6)选择好型号后,您可以看到以下界面。
7)“芯片”菜单,点击“选择芯片”,或在快捷工具栏中点击“选择”。
见下图参见下图红色标记处。
9)打开“选项”菜单,点击“系统设置”,或点击快捷工具栏内的“设置”,参见下图10)在设置对话框内选中所需设置,点击“确定”。
11)点击“编辑”菜单,选择“编辑缓冲区”或“填充缓冲区”,或点击“打开”菜单其中:“编辑缓冲区”您可以进行所有字节编辑,填写您所需数据。
光标停留处可以通过键盘输入。
“填充缓冲区”您可以对所有字节进行编辑,但填充的数据是单一的。
当然您可以通过“打开”文件菜单,导入您所需要的hex文件。
12)若您对每个芯片设置不同的ID,可以点击“芯片”菜单,选择“芯片编号”13)在“芯片编号”对话框中填写您要设定的不同ID的地址段,变化量(自增步长),初始值,自增方式。
例如,我要求每个芯片除了00000040h---00000045h的数据不同,其余地址数据都相同,那么在“自增首址”中填入00000040h,“自增末址”中填入00000045h,自增步长为“1”,初始文件为“00”。
既第一个芯片的00000040h的数据为00,第二个芯片的00000040h的数据为01,其余数据都相同。
14)点击快捷工具栏的“编程”,开始烧录数据。
见下图,若您进行了第12、13步的操作,请在“芯片编号自增”栏打勾。
15)编程结束后,您可以选择“校验”,对烧录好的数据进行对比是否出错。
24LC65 I2C EEPROM字节读写驱动程序[龙啸九天] [786次] 01-3-24 下午07:54:15/*————————————————————〖说明〗24LC65 I2C EEPROM字节读写驱动程序,芯片A0-A1-A2要接VCC。
现缺页写、页读,和CRC校验程序。
以下程序经过50台验证,批量的效果有待考察。
为了安全起见,程序中很多NOP是冗余的,希望读者能进一步精简,但必须经过验证。
51晶振为11.0592MHz〖文件〗24LC65.c ﹫2001/03/23〖作者〗龙啸九天 c51@ <a href= target=_blank></a> 〖修改〗修改建议请到论坛公布 <a href= target=_blank></a> 〖版本〗V1.00A Build 0323—————————————————————*/#define SDA P0_0#define SCL P0_1/*----------------------------------------------------------------------------调用方式:write_8bit(uchar ch) ﹫2001/03/23函数说明:内函数,私有,用户不直接调用。
------------------------------------------------------------------------------*/write_8bit(uchar ch){uchar i=8;SCL=0;_nop_();_nop_();_nop_();_nop_();_nop_();while (i--){SDA=(bit)(ch&0x80);_nop_();_nop_();_nop_();_nop_();_nop_();ch<<=1;SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();SCL=0;_nop_();_nop_();_nop_();_nop_();_nop_();}_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}/*--------------------------------------------------------------------------------调用方式:void ACK(void) ﹫2001/03/23函数说明:内函数,私有,用户不直接调用。
---------------------------------------------------------------------------------*/void ACK(void){SDA=1;SCL=0;_nop_();_nop_();_nop_();_nop_();_nop_();SCL=1;time_1=5;while(SDA) {if (!time_1) break;} //ACKSCL=0;_nop_();_nop_();_nop_();_nop_();_nop_();}/*--------------------------------------------------------------------------------调用方式:void Write24LC65(uint address,uchar ddata) ﹫2001/03/23函数说明:在指定地址address(address<0x2000)写入一个字节ddata ---------------------------------------------------------------------------------*/void Write24LC65(uint address,uchar ddata){SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); //Tsu:STASDA=0;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); //Thd:STASCL=0; //STARTwrite_8bit(0xae); //写从地址ACK();write_8bit(address>>8);ACK();write_8bit(address&0x00FF);ACK();write_8bit(ddata);ACK();SDA=0;_nop_();SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_ ();SDA=1; //STOP_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();delay(10);}/*--------------------------------------------------------------------------------调用方式:uchar Read24LC65(uint address) ﹫2001/03/23函数说明:读取24LC65指定地址address(address<0x2000)的数据。
---------------------------------------------------------------------------------*/uchar Read24LC65(uint address){uchar ddata=0;uchar i=8;SDA=0;_nop_();SCL=0; //STARTwrite_8bit(0xae); //写从地址ACK();write_8bit(address>>8);ACK();write_8bit(address&0x00FF);ACK();//以上是一个“哑”写操作,相当于设置当前地址SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); //Tsu:STASDA=0;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); //Thd:STASCL=0; //STARTwrite_8bit(0xaf); //写从地址,置为读模式ACK();while (i--){SDA=1;ddata<<=1;SCL=0;_nop_();_nop_();_nop_();_nop_();_nop_();SCL=1;if (SDA) ddata|=0x01;}SCL=0;_nop_();SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();SDA=0;_nop_();SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();SDA=1; //STOP_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();delay(5);return ddata;}∙24c65 和24c64 可通用,俺的编程器就这样[haotz] [48次] 01-3-24 下午09:50:14∙24LC65 I2C EEPROM字节读写驱动程序(修正版)[龙啸九天] [538次] 01-5-12 下午12:27:07修改,在读写EEPROM过程中关闭掉中断,否则在同时读写EEPROM和串口通讯时会有随机的误码,请大家注意!/*---------------------------------------------------------------------------调用方式:void Write24LC65(uint address,uchar ddata) ﹫2001/03/23函数说明:在指定地址address(address<0x2000)写入一个字节ddata-----------------------------------------------------------------------------*/void Write24LC65(uint address,uchar ddata){EA=0;SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); //Tsu:STASDA=0;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); //Thd:STASCL=0; //STARTwrite_8bit(0xae); //写从地址ACK();write_8bit(address>>8);ACK();write_8bit(address&0x00FF);ACK();write_8bit(ddata);ACK();SDA=0;_nop_();SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();SDA=1; //STOP_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();EA=1;delay(10);}/*------------------------------------------------------------------------------调用方式:uchar Read24LC65(uint address) ﹫2001/03/23函数说明:读取24LC65指定地址address(address<0x2000)的数据。
------------------------------------------------------------------------------*/uchar Read24LC65(uint address){uchar ddata=0;uchar i=8;EA=0;SDA=0;_nop_();SCL=0; //STARTwrite_8bit(0xae); //写从地址ACK();write_8bit(address>>8);ACK();write_8bit(address&0x00FF);ACK();//以上是一个“哑”写操作,相当于设置当前地址SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); //Tsu:STASDA=0;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); //Thd:STASCL=0; //STARTwrite_8bit(0xaf); //写从地址,置为读模式ACK();while (i--){SDA=1;ddata<<=1;SCL=0;_nop_();_nop_();_nop_();_nop_();_nop_();SCL=1;if (SDA) ddata|=0x01;}SCL=0;_nop_();SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();SDA=0;_nop_();SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();SDA=1; //STOP_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();EA=1;delay(5);return ddata;}∙龙版主,time_1是防止芯片损坏出现死循环吗?但是好像没起作用,能不能解释一下?[半夜开车] [4次] 01-9-18 下午01:45:12∙问题大大的。