I2C 24CXX驱动程序(真正实用 全)
模拟IIC驱动24C02
MC430F14例程:模拟IIC驱动24C02这是国内卖得最为火热的MSP430单片机实验板之一!【作者】: 微控设计网DC版主原创【例程简介】: 利用MC430F14开发板上MSP430与AT24C02进行IIC总线模拟实验。
MSP430模拟IIC向AT24C02写入4个字节数据,然后读出4个字节.最后做数据校验。
如果读出来的数据与写入的原数据相同,则D2-LED会亮.否则D2-LED不亮。
【例程】://基于MC430F14开发板实验例程#include "msp430x14x.h"#include "define.h"//IIC总线操作成失标志#define error 0x01 //错误#define right 0x00 //正确#define AT24_ADD 0xA0 //24c02芯片地址#define write 0x00 //写#define read 0x01 //读#define Quantity 4 //操作数量#define incept_add 0x00 //操作内部地址首址//写入AT24C02数据表unsigned char write_table[4]={'a','b','c','d'};//读出AT24C02数据缓冲区unsigned char read_Buff[4]={'x','x','x','x'};unsigned char iic_check; //检查标志,可选的.//******************************************************//MSP430F14初始化void init (void){P1DIR |= BIT1; //LED输出P1OUT |= BIT1; //关LED}//******************************************************//软延时void delay(unsigned int n){ unsigned int k;for(k=0;k<n;k++);}//******************************************************//检验两组数据是否正确,如在检验数据中有一组不正确,则退出.//*Data_REF参考值数组,*Data_CHK被检验数组,n检验数量//并返回一个成败标志.unsigned char data_check(unsigned char *Data_REF, unsigned char *Data_CHK, unsigned char n){ unsigned char chk ;while(n){if(Data_REF[n-1]==Data_CHK[n-1]) //进行校对{ chk = right; //正确n--; //下一位}else{ chk = error; //校对有错continue; //马上退出}}return chk ; //返回校对成败标志.}//******************************************************void main(void){WDTCTL=WDTPW+WDTHOLD; //停止WDTinit(); //初始化//向AT24C02芯片写入4字节数据iic_check=IIC(write_table,Quantity,incept_add,(AT24_ADD|write));delay(600); //写入后,做一个适当的延时//向AT24C02芯片读出4字字节数据iic_check=IIC(read_Buff,Quantity,incept_add,(AT24_ADD|read));//判别校验是否成功if(!(data_check(write_table,read_Buff,Quantity)))P1OUT ^= BIT1; //LED亮则表示IIC总线写读操作成LPM1; //最后进入低功耗模式1}//******************************************************。
I2C24LC02C读写例程(PIC单片机)
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程序(AT24C1024)测试通过的
_nop_();
}
//*********************************************
//从机接收一位数据应答0
//*********************************************
voidACK(void)
{
SDA=0;
_nop_();
//从机接收到最后一位数据应答1
//*********************************************
voidNoACK(void)
{
SDA=1;
_nop_();
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
void stop(void)
{//发送停止条件的数据信号
SDA=0;
_nop_();
_nop_();
SCL=1;//发送停止条件的时钟信号
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SDA=1;//发送I2C总线停止信号
_nop_();
_nop_();
_nop_();
void write_1024(uchar send[])
{
int i;
start();
write_byte(0xa0);//启动总线
check_ACK();//发送器件地址
write_byte(0x00);//发送器件片内高8位地址
check_ACK();//检查从机是否应答
使用计算机串口读写24CXX
使用计算机串口读写24CXX
要使用计算机串口读写24CXX芯片,您可以按照以下步骤进行操作:
1.确保您的计算机具备串口功能,并且已经正确安装了串口驱动程序。
您可以在计算机的设备管理器中确认串口的存在和工作状态。
2.连接24CXX芯片到计算机的串口上。
24CXX芯片通常采用I2C总线
通信协议,需要通过串口与计算机进行通信。
您可以使用串口转I2C模块
将串口信号转换为I2C信号,然后连接到24CXX芯片上。
3. 在计算机上编写串口通信的程序。
您可以使用C、C++、Python等
编程语言来编写程序。
具体编程语言和操作系统平台有关。
4.打开串口,并设置串口通信参数。
在程序中使用相应的函数或API
打开串口,并设置波特率、数据位、停止位和校验位等参数。
一般情况下,24CXX芯片使用的I2C总线通信速率为100kHz或400kHz。
5.发送读写命令并接收数据。
通过向串口发送相应的读写命令,可以
实现对24CXX芯片中数据的读取和写入。
具体的读写命令格式和协议可以
参考24CXX芯片的数据手册或规格书。
6.处理读写数据。
接收到的数据可以存储在计算机内存中,或者直接
进行处理和显示。
需要注意的是,串口读写24CXX芯片的具体实现过程会受到芯片型号、计算机操作系统、编程语言和开发环境等因素的影响。
因此,您可能需要
参考相关的文档和示例代码来进行具体实现。
24Cxx I2C EEPROM字节读写驱动程序
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); //Thd:STA
SCL=0; //START
write_8bit(0xa0 | page); //写页地址和操作方式,对于24C32-24C256,page不起作用
ACK(ห้องสมุดไป่ตู้;
if(eepromtype>IIC24C16) //如果是24C01-24C16,地址为一字节;24C32-24C256,地址为二字节
调用方式:void WriteIIC_24CXX(enum EEPROMTYPE eepromtype,unsigned int address,unsigned char ddata) ﹫2001/09/18
函数说明:对于IIC芯片24CXX,在指定地址address写入一个字节ddata
SDA=0;
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); //Thd:STA
SCL=0; //START
write_8bit( (address<<1) | 0x01); //写页地址和操作方式
ACK();
while (i--)
{
SDA=1;
#include "reg51.h"
#include "intrins.h"
sbit SCL= P2^7;
sbit SDA= P2^6;
enum EEPROMTYPE {IIC24C01,IIC24C01A,IIC24C02,IIC24C04,IIC24C08,IIC24C16,IIC24C32,IIC24C64,IIC24C128,IIC24C256};
I2C总线 24C02芯片的读写应用
I2C总线24C02芯片的读写应用什么是I2C总线?I2C(Inter-Integrated Circuit)总线是一种由PHILIPS公司开发的两线式串行总线,用于连接微控制器及其外围设备。
也可以简单地理解为I2C是微控制器与外围芯片的一种通讯协议。
在不同的书籍中,可能会称为I2C,IIC,或者I平方C,但是概念也是一样的,只是叫法不同。
一﹑I2C总线特点I2C总线的优点非常多,其中最主要体现在1:硬件结构上具有相同的接口界面;2:电路接口的简单性;3:软件操作的一致性。
I2C总线占用芯片的引脚非常的少,只需要两组信号作为通信的协议,一条为数据线(SDA),另一条为时钟线(SCL)。
因此减少了电路板的空间和芯片管脚的数量,所以降低了互联成本。
总线的长度可高达25英尺,并且能够以10Kbps 的最大传输速率支持40个组件。
I2C总线还具备了另一个优点,就是任何能够进行发送和接收数据的设备都可以成为主控机。
当然,在任何时间点上只能允许有一个主控机。
图5-20(总线连接图)二﹑I2C总线工作原理图5-20为I2C总线的连接图。
I2C总线是由数据线SDA和时钟线SCL构成的串行总线,可发送和接收数据。
在单片机与被控IC之间,最高传送速率100kbps。
各种I2C器件均并联在这条总线上,就像电话线网络一样不会互相冲突,要互相通信就必须拨通其电话号码,每一个I2C模块都有唯一地址。
并接在I2C总线上的模块,既可以是主控器(或被控器),也可以是发送器(或接收器),这取决于它所要完成的功能。
I2C总线在传送数据过程中共有四种类型信号,它们分别是:起始信号、停止信号﹑应答信号与非应答信号。
三﹑I2C总线数据的传送规则起始信号:在I2C总线工作过程中,当SCL为高电平时,SDA由高电平向低电平跳变,定义为起始信号,起始信号由主控机产生。
如图5-21所示图5-21(开始信号)停止信号:当SCL为高电平时,SDA由低电平向高电平跳变,定义为停止信号,此信号也只能由主控机产生。
串行i2c总线e2prom at24cxxx的应用.
9.串行I2C总线E2PROM AT24CXXX的应用这一篇介绍I2C存储器的使用。
主要是介绍AT24CXX系列器件,它分为两类,主要是通过被存储容量地址来分的,一类是AT24C02-AT24C16,它的存储容量从256字节到2048字节。
另一类是AT24C32-AT24C1024,容量从4K-128K。
(理论上好像可以达到最高512K字节容量,但现在网上最高也就能看到AT24C1024也就是128K字节容量)原理:I2C总线是一种用于IC器件之间连接的二线制总线。
它通过SDA(串行数据线)及SCL(串行时钟线)两根线在连到总线上的器件之间传送信息,并根据地址识别每个器件:不管是单片机、存储器、LCD驱动器还是键盘接口。
I2C总线接口电路结构如图所示。
SDA和SCL均为双向I/O线,通过上拉电阻接正电源。
当总线空闲时,两根线都是高电平。
连接总线的器件的输出级必须是集电极或漏极开路,以具有线“与”功能。
I2C总线的数据传送速率在标准工作方式下为100kbit/s,在快速方式下,最高传送速率可达400kbit/s。
在I2C总线技术规范中,开始和结束信号(也称启动和停止信号)的定义如图所示。
当时钟线SCL为高电平时,数据线SDA由高电平跳变为低电平定义为“开始”信号;当SCL 线为高电平时,SDA线发生低电平到高电平的跳变为“结束”信号。
开始和结束信号都是由主器件产生。
在开始信号以后,总线即被认为处于忙状态;在结束信号以后的一段时间内,总线被认为是空闲的。
I2C总线的数据传送格式是:在I2C总线开始信号后,送出的第一个字节数据是用来选择从器件地址的,其中4-7位为器件码,如1010就是代表串行E2PROM器件。
1-3位为存储器的片选地址或存储器内的块地址码,如何区分?后面再做详细说明,第8位为方向位(R/W)。
方向位为“0”表示发送,即主器件把信息写到所选择的从器件;方向位为“1”表示主器件将从从器件读信息。
单片机模拟I2C总线读写EEPROM(24CXX)程序一
单片机模拟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;。
I2C-24CXX驱动程序(真正实用-全)
#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页的大小。
单片机模拟I2C总线及24C02
单片机模拟I2C总线及24C02(I2C EEPROM)读写实例(源代码)版权声明:CSDN是本Blog托管服务提供商。
如本文牵涉版权问题,CSDN不承担相关责任,请版权拥有者直接与文章作者联系解决。
/* 51系列单片机在使用时,有时需要模拟I2C总线,*//* 这里举出一个实例(读写串行EEPROM芯片at2402)*//************************************************************************//* Name:AT24C02存储器的读写程序,用到I2C总线,含相对独立的I2C总线读写函数*//* Language: C51单片机编程语言*//* Platform: Win98,Intel Celeron 433 Processor,伟福仿真器,仿真8751 *//* Author: StephenZhu javasdk@*//* Date: 2003年5月21日,5月22日,5月29日*//* Version: 1.1.1 *//* Others: None *//************************************************************************/ #include<string.h>#include<reg52.h>#include<intrins.h>#define DELAY_TIME 60 /*经实验,不要小于50!否则可能造成时序混乱*/#define TRUE 1#define FALSE 0sbit SCL=P1^7;/*假设由P1.7和P1.6控制*/sbit SDA=P1^6;/********** 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) /* SEND ACK */{/*发送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;elsereturn TRUE; }void WriteI2CByte(char b)reentrant{/*向I2C总线写一个字节*/char i;for(i=0;i<8;i++)if((b<<i)&0x80) /*&0x80相当于置SCL为第八bite* 依次读入b的8bite/ SEND_1();elseSEND_0();}char ReadI2CByte(void)reentrant{/*从I2C总线读一个字节*/char b=0,i;for(i=0;i<8;i++){SDA=1; /*释放总线*/SCL=1; /*接受数据*/DELAY(10);F0=SDA;DELAY(10);SCL=0;if(F0==1){b=b<<1;b=b|0x01;。
串行通信i2c总线协议简明教程(连接方式,读写时序,24CXX系列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。
I2C_24C64驱动程序
if(I2C_dat_t < I2C_SOP_NUM) {
I2C->DATA = *I2C_ptr ++; /* ??? */
I2C->CON.STA = 0; /* I2C */
I2C->CON.STO = 1; /* I2C */
I2C_end = 1;
}
I2C_dat_t ++;
}
}
}
else if(Device_addr == 0xa6)
{
I2C->CON.STO = 0; /* I2C */
}
else {
I2C->DATA = *I2C_ptr ++; /* ??? */
I2C->CON.STA = 0; /* I2C */
}
break;
case 0x58: /*receive a data and back a ACK bit */
*I2C_ptr = I2C->DATA ;
I2C->CON.STA = 0; /* I2C */
I2C->CON.STO = 1; /* I2C */
I2C->CON.STO = 0; /* I2C */
break;
case 0x18: /*?????????? ACK ? */
case 0x28: /*?????????? ACK ? */
I2C_f_t ++;
if(Device_addr == 0xa0)
SYS->IPRSTC2.I2C_RST = 0; /* I2C ?? ???? */
I2C总线式存储器24C0X系列读写程序模块
/*****************************************************************头文件名VIIC_C51.H这个头文件对应的库是VIIC_C51.LIB,库中有几个模拟I2C的函数,加入此文件即可使用I2C平台(主方式的软件平台),函数是对LPC764的I2C的I/O口实现,即其P1.3 (SDA) , P1.2(SCL),51系列机型可以通用.注意: 函数是采用软件延时的方法产生SCL脉冲,固对高晶振频率要作一定的修改....(本例是1us机器周期,即晶振频率要小于12MHZ).(函数的使用可参考给出的事例程序.)*****************************************************************/#ifdef uchar#define READYDEF 1 /*宏uchar已定义*/#else#define uchar unsigned char#endif/*******************************************************************无子地址发送字节数据函数功能: 从启动总线到发送地址,数据,结束总线的全过程,从器件地址sla.如果返回1表示操作成功,否则操作有误。
********************************************************************/ extern bit ISendByte(uchar sla,uchar c);/*******************************************************************有子地址发送多字节数据函数功能: 从启动总线到发送地址,子地址,数据,结束总线的全过程,从器件地址sla,子地址suba,发送内容是s指向的内容,发送no个字节。
AT24c1024 LPC23XX驱动 i2c
void I2CSendByte(unsigned char ch)//写一个字节数据
{
unsigned char Byte_count=8;
SDA_out;
while(Byte_count--)
{
FIO0CLR=SD2401_SCL;
I2CWait(50);
//延时大约8uS
//sramadd_lo:每块内的EE字节地址,
//sramdata:数据
unsigned char I2CReadEEram(unsigned char page,unsigned int sramadd_lo)
{
unsigned char ddata=0;
I2CStart();
if(page==0)I2CSendByte(0xA0);
unsigned char Byte_count=8; unsigned char ddata=0; SDA_in;
第2页
AT24c1024 LPC23XX驱动
FIO0SET=SD2401_SDA;
while (Byte_count--)
{
ddata<<=1;
FIO0CLR=SD2401_SCL;
I2CWait(50);
//延时大约8uS
FIO0SET=SD2401_SCL;
I2CWait(50);
//延时大约8uS
if(FIO0PIN&SD2401_SDA)ddata=ddata|1;
}
FIO0CLR=SD2401_SCL;
return ddata;
}
//page:00:选择块0,01:选择块1,
I2C总线及其驱动程序
SDA SCL 起始 信号 static void __zyI2cAckSend (void) { __ZY_I2C_SDA = 0; __ZY_I2C_DELAY(); __ZY_I2C_SCL = 1; __ZY_I2C_DELAY(); __ZY_I2C_SCL = 0; } 1 2 8 9 应答 信号 1 2 8 9 非应答 信号 停止 信号
1 0 1 0 1 0 1 0
MSB LSB
主机
MSB
LSB
从机
接收一个字节的数据
程序示例
static unsigned char __zyI2cByteReceive(void) { unsigned char ucRt; unsigned char i; // 接收数据 i = 8; do { ucRt = (ucRt << 1) + __zyI2cBitReceive(); } while (--i != 0); }
空闲时SDA状态未知, 需手动拉低
发送重复起始信号
在I2C总线忙时,产生起始条件,以改变数据收发方向。
SDA(I/O) SDA
80C51
SCL(I/O)
I2C从机
SCL
static void __zyI2cStartSend (void) { __ZY_I2C_SDA = 1; __ZY_I2C_DELAY(); __ZY_I2C_SCL = 1; __ZY_I2C_DELAY(); __ZY_I2C_SDA = 0; __ZY_I2C_DELAY(); __ZY_I2C_SCL = 0; }
从机具有I2C地址,内部寄存器均对应具体地址 主机对从机的操作即对寄存器的读写操作
初始化
读操作
(完整word版)24C02I2C驱动程序(详细全)
/*---------------------------------------24C02.h-----------------------------------*/ #ifndef _24C02_H#define _24C02_H/* Includes ----------------------------------------------------------------*/#include "STC15F2K60S2.h"#include "stdbool.h"/* Define ------------------------------------------------------------------*/#define WC24C02 0xa0//器件地址写#define RC24C02 0xa1//器件地址读#define MAXSIZE24C02 256//AT24C02最多256个字节2K bits 32页#define I2C_PAGESIZE 8//AT24C02每页有8个字节#define delayNOP() _nop_();_nop_();_nop_();_nop_() //延时sbit SDA = P2^5;//定义数据线sbit SCL = P2^6;//定义时钟线/* Private ------------------------------------------------------------------*//* Public -------------------------------------------------------------------*/uint idata ucSendBuffer[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};uint idata ucReceData;uint idata ucReceiveBuffer[8];//从器件中读出的多字节数据暂存区/* Function Declaration -----------------------------------------------------*/ bool I2CStart(void);//启动I2Cvoid I2CStop(void);//停止I2Cvoid I2CAck(void);//应答信号void I2CNoAck(void);//发送非应答信号bool I2CWaitAck(void);//检测应答位void I2CSendByte(u8 demand);//发送一字节数据u8 I2CReceiveByte(void);//接收一字节数据//extern bool I2C_ByteWrite(u8* pBuffer, u8 WriteAddr); //向24c02中写入1个字节extern bool I2C_PageWrite(u8* pBuffer, u8 WriteAddr, u8 n); //24c02页写(不超过一页)extern bool I2C_BufferWrite(u8* pBuffer, u8 WriteAddr, u16 n); //24c02数据块写(不超过256个字节)extern bool I2C_BufferRead(u8* pBuffer, u8 ReadAddr, u16 n); //从24C02中读出N字节数据(不超过256个字节)#endif/*----------------------------------------------end file-----------------------------------------------*//*---------------------------------------------24C02.c------------------------------------------------*//******************** (C) COPYRIGHT 2014 xxxx *********************************** 文件名:24c02.c* 描述:本函数是xxxxx的24C02的读写函数注:器件地址0xa0 数据地址:00H-FFH 2K bits 256Byte* 平台:Keil 4 A51* 库版本:使用了宏晶科技的相关资料及程序\ STM库3.50 I2C程序* 作者:xxxxxx* 时间:2014.9.3******************************************************************************* ***//* Includes ------------------------------------------------------------------*/#include "24c02.h"/********开启24c02的I2C总线********/bool I2CStart(void){SDA=1;SCL=1;delayNOP();delayNOP();if(!SDA)return false; //SDA线为低电平则总线忙,退出SDA=0;delayNOP();delayNOP();while(SDA)return false; //SDA线为高电平则总线出错,退出SCL=0;delayNOP();return true;}/********关闭24c02的I2C总线*******/ void I2CStop(void){SDA=0;SCL=0;delayNOP();delayNOP();SCL=1;delayNOP();delayNOP();SDA=1;}/*********发送ACK*********/void I2CAck(void){SDA=0;SCL=0;delayNOP();// delayNOP();SCL=1;delayNOP();// delayNOP();SCL=0;}/*********发送NO ACK*********/void I2CNoAck(void){SDA=1;SCL=0;delayNOP();// delayNOP();SCL=1;delayNOP();// delayNOP();SCL=0;}/*********读取ACK信号*********/bool I2CWaitAck(void) //返回为:1=有ACK,0=无ACK{SCL=0;SDA=1; //设置SDA为输入delayNOP();// delayNOP();SCL=1;delayNOP();// delayNOP();if(SDA){SCL=0;return false;}SCL=0;return true;}/************MCU向24c02发送一个字节数据*************/ void I2CSendByte(u8 demand) //数据从高位到低位//{u8 i=8;while(i--){SCL=0;_nop_();SDA=(bool)(demand&0x80);demand<<=1;delayNOP();// delayNOP();SCL=1;delayNOP();// delayNOP();}SCL=0;}/*********MCU从24c02读入一字节数据*********/u8 I2CReceiveByte(void) //数据从高位到低位//{u8 i=8;u8 ddata=0;SDA=1; //设置SDA为输入while(i--){ddata<<=1; //数据从高位开始读取SCL=0;delayNOP();// delayNOP();SCL=1;delayNOP(); //从高位开始ddata|=SDA;ddata<<=1// delayNOP();if(SDA){ddata|=0x01;}}SCL=0;return ddata;}/****************向24c02中写入1个字节****************//*bool I2C_ByteWrite(u8* pBuffer, u8 WriteAddr){I2CStart();//启动I2CI2CSendByte(WC24C02);//发送器件地址写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页的大小。
W24CXX并口I2C读写软件使用说明
W24CXX 并口编程软件说明程序版本:V1.1.0.20916增加功能:1. 用户可以设置并口地址2. 可以编辑Client区内容 (单击编辑后双击要编辑的字节)3. 修改了Client区界面4. 简体中文,英文双语界面5. 针对铁电EEPROM可以取消页写入延时加快写入速度注:并口地址若设置不正确可能导致计算机死机等发生(软件可以读写任意端口)程序开发:林晓斌 (sonicss)Email:sonicss@ 或 sos_lxb@开发工具:Borland C++ Builder 6.0 Updata 1WinDriver 5.05b开发环境:Windows 2000 Profressional SP3我的机器配置:Celeron 1.2G 128M Ram 笔记本运行环境:Win98/NT/2K/XP编写目的:24系列I2C芯片使用非常广泛,网上也有个用并口读写24CXX的软件- 24CXX.EXE,但他只能在DOS下运行,给使用带来了很多不便,所以写了这个软件,就叫做W24CXX.EXE 吧。
功能:和那个DOS版的程序差不多,能够编写24C01 ~ 256系列的芯片。
可以设置页写和块读的字节大小。
(软件为按页方式读出数据和写入数据的)如果使用时发现不能正常读出或写入,请到器件->设置中改变读写的字节数。
详细内容请查看附录1。
电路图:注:若读写成功率不高,请拿掉发光二极管。
原电路图:注:如使用DOS版的24CXX.EXE请不要接8,9两脚数据对比:24CXX.EXE(我没有测试过,网上找的,带校验编程时间) 芯片型号整片编程时间平均每字节编程时间备注24C321秒244微秒24C642秒244微秒24C2564秒122微秒W24CXX.EXE测试数据测试机器1:Celeron 1.2G 128MRAM (单位:秒)Win2000Profressional SP3 下测试型号 读芯片 写芯片(无校验) 自动(带校验) AT24C02 0.086 0.197 0.292FM24C04 0.174 0.297 0.470FM24C16 0.693 1.178 1.85124C256 11.300 14.625 25.689Windows98Se下测试结果型号 读芯片 写芯片(无校验) 自动(带校验) AT24C02 0.037 0.066 0.163FM24C04 0.074 0.083 0.243FM24C16 0.295 0.340 0.97124C256 4.818 5.637 11.631测试机器2:P41.6G 256MDDR RAM测试结果Win2000Profressional SP2型号 读芯片 写芯片(无校验) 自动(带校验) AT24C02 0.072 0.181 0.229FM24C04 0.145 0.267 0.412FM24C16 0.582 1.072 1.65424C256 9.468 13.111 22.594速度比Boan 的 24CXX.EXE慢了很多,用示波器看了他发出的脉冲,延时竟然只有4us,这在Windows下是不大可能实现的,照资料说,一个PostMessage就要执行4us。
I2C接口的EEPROM 24C64芯片的驱动方法
I2C接口的EEPROM24C64芯片的驱动方法与93C46类似的,24C64也是EEPROM,但不同的是24C64是I2C接口的,容量也要更大些,用来存储较大容量的数据,甚至在某些单片机中可以用作程序存储器。
24C64提供65536个位,它们是以字节方式进行组织的。
通过设置不同的地址,可以实现多达8个芯片共享两线总线。
它被广泛应用于工业、化工等需要低功耗与低电压的领域。
同时,它还提供诸如4.5V~5.5V、2.7V~5.5V、2.5V~5.5V与1.8V~5.5V各种工作电压范围的芯片,从而使其应用更加通用。
24C64的引脚定义:引脚功能详细描述:24C64的功能框图:引脚功能描述:串行时钟(SCL):在SCL的上升沿数据写入芯片中,在下降沿从芯片中读出数据。
串行数据(SDA):SDA用作双向数据传输。
这个引脚是漏极开路驱动,需要加上拉电阻。
设备地址(A2,A1,A0):A2~A0是设备地址设置引脚,可以通过接高或接低来设置不同的地址,也可以直接悬空。
设置为不同地址时最多可以在同一总线上存在多达8个芯片。
当这些引脚悬空时,默认地址为0。
写保护(WP):当此引脚接到GND上时,允许正常的写操作。
当WP接到V CC时,所有的写操作都是被禁止的。
如果悬空,则WP在内部被拉到GND。
24C64的组织方式:24C64在内部被组织为256个页,每个页32个字节。
可以按字节来进行操作,地址为13位。
24C64的操作方法:24C64是采用I2C接口来进行数据传输的,在这里不再介绍I2C接口数据传输的相关内容,具体的I2C总线协议在相关章节有详细讲解,敬请翻阅。
下面只针对于24C64的操作方法进行讲解。
1)设备寻址在开始条件使芯片使能后,需要给其写入一个8位的设备地址码,以使某一芯片被命中。
在地址码的开头有两个“10”序列,共4位,然后是3位的地址,最后是1位的读写标识位。
具体的地址码结构如下:24C64使用3个设备地址位A2、A1、A0使多达8个芯片同时存在于一条总线上。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#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#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库* 库版本:基于野火相关资料及程序上优化修改* 作者:天涯月下红颜醉* 时间:2015.4.19******************************************************************************* ***//* 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);//发送器件地址写return false;I2CSendByte(WriteAddr);if(I2CWaitAck() == 0)return false;I2CSendByte(*pBuffer);if(I2CWaitAck() == 0)return false;I2CStop();return true;}*//** 函数名:I2C_PageWrite* 描述:在EEPROM的一个写循环中可以写多个字节,但一次写入的字节数* 不能超过EEPROM页的大小。