IIC读写EEPROM
I2C读写EEPROM文档说明

通过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低电平时才可以任意变换。
基于STM32的IIC_EEPROM案例说明

IIC_EEPROM说明书
一:原理图
IIC_EEPROM电路图
二:工作原理
使用IIC控制器读写IIC_EEPROM中的数据。
开启IIC控制器,IIC_SCL产生正确的时序,通过判断总线的状态,通过IIC_SDA传输数据。
请参考《STM32中文参考资料》的IIC相关内容。
三:实验现象及操作
本实验使用使用串口通信显示数据。
在上位机上打开串口助手,波特率设置为115200,无校验。
串口助手中使用文本接受模式。
按RESET键后,可发现串口助手接受区中显示,“这是一个IIC_EEPROM测试例程”字符串;
在按下一次K3键,程序网IIC_EEPROM中写入0x00,0x01,0x02,0x03等等共20个数据,在串口助手中有显示,然后会自动读取IIC_EEPROM中的数据并发送给PC机;
若再次按下K3键,数据会乘2再写入;
再按下K3键,数据则会乘3再写入;
依次类推。
用IO模拟IIC方式读写EEPROM容易出现的问题

用IO模拟IIC方式读写EEPROM容易出现的问题 在嵌入式软件开发过程中,经常会用模拟IO的方式读写EEPROM 的操作。
有时会因程序编码的问题,出现读写数据不正确的情况。
根据笔者多年的开发经验与大家分享希望对大家有所帮助。
对EEPROM的操作常见的有两种方式:I2C,SPI;在应用中经常会用到模拟IO方式读写EEPROM。
在编写此类代码时必须要掌握I2C 与SPI协议。
I2C总线上的数据稳定规则,SCL为高电平时SDA上的数据保持稳定,SCL为低电平时允许SDA变化。
如果SCL处于高电平时,SDA上产生下降沿,则认为是起始位,SDA上的上升沿认为是停止位。
通信速率分为常规模式(时钟频率100kHz)和快速模式(时钟频率400kHz)。
同一总线上可以连接多个带有I2C接口的器件,每个器件都有一个唯一的地址,既可以是单接收的器件,也可以是能够接收发送的器件。
SPI,串行外围设备接口。
是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便。
在操作中出现读取数据不正确,或者不能读取数据可能有以下原因:1.没有遵照通信协议:这两种通信方式都有各自独立的协议,如果在编写程序时不按通信协议,自然就不能正常通信了;2.时序不对:两处通讯方式都有严格的时序,编写程序时要严格按对应的时序;3.IO口方式方向设置不正确:在通信中数据有输入与输出的时候,特别是在I2C的方式下,有数据输入时相应的IO口要设置为输入,反之亦然,初学都容易犯这样的错误;4.看页的大小,超过一个页连续写就回滚,前面的就被覆盖。
其实里面有一个页地址计数器,如果页是8个byte,那么这个计数器就3bit,增加的地址(连续写的地址范围)就相当于溢出或者相当于按页取模。
在应用中的建议:1. SCL与SDA引脚用2.2K--4.7K电阻上拉;2. IO口与EEPROM的相应引脚不能直接相连,串一个几百欧电阻;3.为保证数据的正确性,在写入数据时最好对数据进行检验;4.采用循环地址的方式进行存储,避免只在一个固定地址上读写数据;。
IO口模拟I2C总线读写EEPROM

SDA = 1;
}
void I2cSendNack()
{
SDA_DIR = 0;
SDA = 1;
I2c_delay();
SCL = 0;
I2c_delay();
SCL = 1;
I2c_delay();
SCLபைடு நூலகம்= 0;
}
INT8U I2cCheckAck()
void WriteOneByte(INT8U cData);
INT8U ReadOneByte();
INT8U WriteI2cData(INT16U addr, INT8U cData);
INT8U ReadI2cData(INT16U addr);
void I2c_delay()
{
return 0;
}
cTemp = L_BYTE(addr);
WriteOneByte(cTemp);
if(I2cCheckAck() == 0)
{
return 0;
}
WriteOneByte(cData);
if(I2cCheckAck() == 0)
#define H_BYTE(wVal) *( (unsigned char*)&wVal+1)
#define L_BYTE(wVal) *( (unsigned char*)&wVal )
#define NOP() asm("nop")
#define INT8U unsigned char
if(I2cCheckAck() == 0)
基于STM32的IIC_EEPROM案例说明

基于STM32的IIC_EEPROM案例说明STM32是一系列由STMicroelectronics开发的32位ARM Cortex-M处理器的微控制器。
它具有高性能、低功耗和丰富的外设。
其中一个外设是I2C接口,可以用于连接外部器件,如EEPROM。
EEPROM(Electrically Erasable Programmable Read-Only Memory)是一种非易失性存储器,可以通过电量抹除并重新编程。
本文将说明如何在STM32微控制器上使用I2C接口来读取和写入EEPROM的数据。
以下是一个I2CEEPROM案例的步骤:1.硬件连接:找到适当的引脚连接STM32和EEPROM。
根据STM32型号和EEPROM的规格书,将SCL引脚连接到STM32的相应引脚,将SDA引脚连接到STM32的相应引脚。
确保EEPROM上的地址引脚正确连接到STM32的引脚,以选择EEPROM的地址。
另外,确保STM32的引脚配置正确。
2.初始化I2C外设:在STM32的代码中,首先需要初始化I2C外设。
这可以通过配置I2C控制器的寄存器来完成。
这些寄存器包含有关时钟速度、地址模式和使能I2C控制器的设置选项。
3.选择EEPROM地址:通过向I2C总线发送一个特定的命令字节,可以选择EEPROM的地址。
这个命令字节包含I2C总线上的设备地址和寻址模式。
4.读取EEPROM数据:为了从EEPROM读取数据,STM32将发送一个读取命令字节,将该命令字节传送到EEPROM,然后从EEPROM读取数据。
在读取数据之前,需要设置读取数据的长度和目标缓冲区。
5.写入EEPROM数据:为了向EEPROM写入数据,STM32将发送一个写入命令字节,将该命令字节传送到EEPROM,然后将数据写入EEPROM。
在写入数据之前,需要设置写入数据的长度和源缓冲区。
6.处理错误和超时:在进行I2CEEPROM读取和写入操作时,可能会出现错误和超时。
应用IIC总线方式读取EEPROM任务书

电气工程学院《嵌入式单片机原理及应用》课程改革三级项目任务书设计题目:应用IIC总线方式读取EEPROM一、项目设计目的通过该项目的学习和锻炼使学生熟悉、了解并掌握和STM32学习、开发相关的软、硬件环境;了解IIC总线协议,熟悉其主要特点及功能;练习使用库函数以IIC总线方式读取EEPROM芯片AT24C02中的数据。
二、项目设计要求(1)掌握Keil MDK软件的模板设计及工程配置。
(2)了解IIC总线协议,熟悉和掌握其主要特性、功能及基本原理。
(3)熟悉《STM32F103XXX参考手册》、《STM32固件库》,在此基础上能够根据特定要求进行相关内容的查找;(4)掌握STM32的库函数开发方法,实现以IIC总线协议对EEPROM芯片AT24C02的数据读写。
(5)设计的工程要能进行现场展示。
三、项目设计内容1)应用Keil Uvision4设计工程模板,并根据编译和仿真要求进行相关工程配置。
Version3.5版本的ST库源码可从ST的官方网站下载或者从讲课的资料中获取;工程设计模板要根据授课教师建立的方式进行设计;建立一个空的main()测试函数;仿真采用的STM32芯片为STM32F103VET6,数据通信可采用串口或Jlink两种形式。
2)设计IIC总线读取EEPROM芯片内数据的软件流程图。
了解IIC总线协议,熟悉STM32的I2C特性及架构,并在掌握AT24C02数据组织形式的基础上,根据库函数的开发方法设计IIC总线方式读取EEPROM芯片内数据的软件流程图。
3)使用库函数进行IIC总线读取EEPROM芯片内数据工程的开发。
建议使用stm32的库函数进行该项目的开发,如果有的同学想使用直接配置寄存器形式进行相关内容的设计,必须是在完成库开发的基础上实现;该项目设计的工程要求能在现场进行演示。
4.项目考核要求该项目考核采用现场答辩形式;准备的材料包含:电子版的相关原理性描述、和项目内容相关的PPT、纸质版项目设计报告一份;设计的项目工程要求能在指定的硬件上现场进行演示。
单片机模拟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;。
IIC总线读写EEPROM(深度诠释)

/*----------------------------------------------------------------------------------------------------------IIC总线读写EEPROM(串行扩展eeprom,24c02)(STC12C系列单片机自带eeprom,且有另外的eeprom操作方式)作者:Allen.H(帮同学修改的一个程序)时间:2010.11.5----------------------------------------------------------------------------------------------------------*/#include <reg52.h>#include <intrins.h>//是用括号还是双引号看情况,本地头文件用双引号,系统头文件用括号//这里使用了_nop_()函数,所以调用此头文件#define TRUE 1/*define宏定义一般用大写,宏定义并不会减少最终代码空间define多行语句时,每一行末尾写上\,最后一行可以不写,有时比较短的语句写成一个子函数会牺牲更多的时间,因为函数调用耗时比较多,这个时候用一个define语句更好*/#define FALSE 0typedef unsigned char uchar;//良好的程序风格,不应该用#define//#define uchar unsigned charsbit sda=P2^0; //---------你把sda和scl引脚可能定反了,我换过来了-------------------------------sbit scl=P2^1;//等号对其,变量名长短不一时,注意,且测试等于号"=="或者其他双目关系运算符两边都空一格//-----------------------------------------------------------------void delay(uchar z)//带参数很好{//大括号所在行不要写代码uchar i,j;//局部变量中用来自加自减可以用i,j之类的定义,计数建议不要用i,j//局部变量不占内存,函数调用时生成堆栈,不应该定义局部变量时作初始化//----局部变量命名后空一格,写正式代码for(i=z;i>0;i--)for(j=100;j>0;j--);//注明多少时间,在调试模式下,看窗口左边的SEC值}//函数与函数之间空一格void delay_7nop()//子程序命名最好顾名思义,比如delay_1ms(),这里考虑都是使用7nop,不带参数{/*程序代码每进一层逻辑就缩进一格TAB键,TAB设置为3,4格,在keil的view->options里面设置,不要使用几个空格来缩进,统一使用TAB键*/_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();//这里0-1000多个_nop_都可以}//delay函数都放在一起,函数顺序不要乱放,相关的放一起,//--------------------------------------------------------------------void init(){sda=1;delay_7nop();scl=1;delay_7nop();}//---SCL线为高电平期间,SDA线由高电平向低电平的变化表示起始信号;//SCL线为高电平期间,SDA线由低电平向高电平的变化表示终止信号。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
i2c_Init.I2C_DutyCycle = I2C_DutyCycle_2;
i2c_Init.I2C_OwnAddress1 = I2C_EE_24C256_PARA;
i2c_Init.I2C_Ack = I2C_Ack_Enable;
* I2C_EE_Drv_WriteByte()
*
* Description :将一个字节的数据写入EEPROM的指定的地址
*字节写模式:
*
*起始信号
* ->从器件地址(包括写命令)
* [a]-> EEPROM存储空间地址高字节
* [a]-> EEPROM存储空间地址低字节
* [a]->数据
* [a]->停止信号
gpio_Init.GPIO_Speed = GPIO_Speed_10MHz;
gpio_Init.GPIO_Mode = GPIO_Mode_Out_OD; //开漏输出模式
GPIO_Init(I2C1_WP_Port, &gpio_Init);
//----------- I2C1 configuration ------------------
* Description :
*-------------------------------------------------------------------------------------------------------
*********************************************************************************************************
BSP_IntDis(BSP_INT_ID_I2C1_ER); //失能错误中断
I2C_EE_Drv_BusDis();
//-------------------------------------------
//超时时间计算(5ms超时)
//-------------------------------------------
if(err)
{
if(--retry == 0 ) //已经试了5次,写下一个数据
{
retry = 5;
pbuf++;
addr++;
len--;
}
}
else //顺利,写下一个数据
{
pbuf++;
addr++;
len--;
}
}
I2C_EE_Drv_BusDis(); //失能总线,写保护
}
/*
*********************************************************************************************************
*/
u8 I2C_EE_Drv_WriteByte(u8 xChip, u16 xAddr, u8 xDat)
{
u32 tmr;
u8 errcnt;
// _WriteEn(); //写使能
// I2C_Cmd(I2C1, ENABLE); //使能总线
errcnt = 0;
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
* Modified by :
* Modified date :
* Description :
*-------------------------------------------------------------------------------------------------------
u32 ulTimeOut_Time;
/*
*********************************************************************************************************
* I2C_EE_WriteStr()
*
* Description :将一个数据块写入EEPROM的指定的地址
*/
void I2C_EE_Drv_Init( u32 xI2C_EE_Speed )
{
I2C_InitTypeDef i2c_Init;
GPIO_InitTypeDef gpio_Init;
RCC_ClocksTypeDef rcc_clocks;
//
BSP_PeriphEn(I2C1_PORT_ID);
* I2C_EE_Drv_Init()
*
* Description : I2C1初始化,默认情况下,I2C接口工作在从模式下。
*
* Argument(s) : xI2C_EE_Speed -总显的速度100000 - 400000
*
* Return(s) : none.
*
* Caller(s) : Application.
* Description :
*-------------------------------------------------------------------------------------------------------
*********************************************************************************************************
*
* Note(s) : (1)
*-------------------------------------------------------------------------------------------------------
* Modified by :
* Modified date :
RCC_GetClocksFreq(&rcc_clocks);
ulTimeOut_Time = (rcc_clocks.SYSCLK_Frequency /10 *5 /1000); //等待程序的执行时间:10个指令周期
}
/*
*********************************************************************************************************
*********************************************************************************************************
*/
void I2C_EE_WriteStr(u8 xChip, u16 xAddr, u8 *xpBuf, u16 xLen)
*/
void I2C_EE_ReadStr(u8 xChip, u16 xAddr, u8 *xpBuf, u16 xLen)
{
u8 *pbuf;
u8 err;
u8 retry;
u16 addr;
u16 len;
//
pbuf = xpBuf;
addr = xAddr;
len = xLen;
I2C_EE_Drv_BusEn(); //允许总线,写允许
* Modified date :
* Description :
*-------------------------------------------------------------------------------------------------------
*********************************************************************************************************
*
* Argument(s) : xChip -从器件地址
* xAddr - EEPROM存储空间地址
* xpBuf -数据缓冲区指针
* xLen -数据长度
*
* Return(s) : none.
*
* Caller(s) : Application.
*
* Note(s) : (1)
*-------------------------------------------------------------------------------------------------------
* I2C_EE_ReadStr()
*
* Description :从EEPROM的指定的地址读出一个数据块
*
* Argument(s) : xChip -从器件地址
* xAddr - EEPROM存储空间地址
* xpBuf -数据缓冲区指针
* xLen -数据长度
*
* Return(s) : none.
i2c_Init.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
i2c_Init.I2C_ClockSpeed = xI2C_EE_Speed;
I2C_Init(I2C1, &i2c_Init);
BSP_IntDis(BSP_INT_ID_I2C1_EV); //失能事件中断
gpio_Init.GPIO_Speed = GPIO_Speed_50MHz;