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低电平时才可以任意变换。
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读取和写入操作时,可能会出现错误和超时。
二线制I2C CMOS 串行EEPROM 读写操作
reg[10:0]main_state;//主状态寄存器
reg[7:0]data_from_rm;//EEPROM读寄存器
reglink_sda;//SDA数据输入EEPROM开关
reglink_read;//EEPROM读寄存器开关
reglink_head;//启动信号开关
sh8in_bit6= 10'b0000000100,
sh8in_bit5= 10'b0000001000,
sh8in_bit4= 10'b0000010000,
sh8in_bit3= 10'b0000100000,
sh8in_bit2= 10'b0001000000,
sh8in_bit1= 10'b0010000000,
sh8out_end= 9'b100000000;
////////////串行数据并行输出状态定义///////////////////////////////////////////////////
parameter
sh8in_begin= 10'b0000000001,
sh8in_bit7= 10'b0000000010,
// //synthesis parallel_case //case语句综合为并行多路选择器
// //synthesis full_case //case语句分支项完备
// //synthesis translate_on //开始综合以下内容
// //synthesis translate_off //停止综合以下内容,以下内容仅供仿真
main_state<= READ_START;
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线由低电平向高电平的变化表示终止信号。
基于IIC总线的EEPROM读写驱动
/****************************************************************************** * 对基于IIC总线的EEPROM进行读写C文件** file: eeprom_device.c* name: zhzhchang* time: 2010.3.17* V1.0* blogs: /zhzht19861011* Nots: 本文件基于at24c02,仅寻址一个字节地址,若是使用大容量eeprom器件,只需增加相应地址即可******************************************************************************* **/#include<reg52.h>#include"eeprom_device.h"//模拟IIC总线延时程序,对不同的CPU应根据相应的主频改变此处的延时时间//at24c512B: t(LOW)=0.4um,t(HIGH)=0.4us,t(WR)=5msvoid delay(void){unsigned char i;for(i=0;i<5;i++);}void mDelay(unsigned char j)//A normal delay{unsigned int i;for(;j>0;j--){for(i=0;i<125;i++){;}}}//启动IIC总线//时钟线保持高电平期间,数据线电平从高到低的跳变作为I2C 总线的起始信号void Start(void){Sda=1;delay();Scl=1;delay();delay();Scl=0;}//停止IIC总线//时钟线保持高电平期间,数据线电平从低到高的跳变作为I2C 总线的停止信号void Stop(void){Sda=0;delay();Scl=1;delay();Sda=1;delay();Scl=0;}//应答IIC总线void Ack(void){Sda=0;delay();Scl=1;delay();Scl=0;delay();}//非应答IIC总线void NoAck(void){Sda=1;delay();Scl=1;delay();Scl=0;delay();}/*发送完一个字节后检验设备的应答信号*/bit Check_Ack (void){bit q;Sda=1;Scl=1;delay();q=Sda;delay();Scl=0;delay();if (q==1)return 0;elsereturn 1;}//发送一个字节void Send(unsigned char Data){unsigned char BitCounter=8;unsigned char temp;do{temp=Data;Scl=0;delay();if((temp&0x80)==0x80)Sda=1;elseSda=0;Scl=1;temp=Data<<1;Data=temp;BitCounter--;}while(BitCounter);Scl=0;}//读一个字节并返回变量unsigned char Read(void){unsigned char temp=0;unsigned char temp1=0;unsigned char BitCounter=8;Sda=1;do{Scl=0;delay();Scl=1;delay();if(Sda)temp=temp|0x01;elsetemp=temp&0xfe;if(BitCounter-1){temp1=temp<<1;temp=temp1;}BitCounter--;}while(BitCounter);return(temp);}//write to ROM,循环写入,每循环一次写一个字节void WrToROM(unsigned char Data[],unsigned char Address,unsigned char Num) {unsigned char i;for(i=0;i<Num;i++){Start();Send(AddWr);//Write AddressAck();Send(Address+i);//Write sub AddressAck();Send(*(Data+i));//Write DataAck();Stop();mDelay(20);}}//读一个字节void RdFromROM(unsigned char Data[],unsigned char Address){bit ack;Start();Send(AddWr);//Write Addressack=Check_Ack();Send(Address);//Write sub Addressack=Check_Ack();Start();Send(AddRd);//Read Addressack=Check_Ack();*(Data)=Read();//Read DataScl=0;NoAck();Stop();}//a按页写//一次可以写一页,一页的大小根据芯片而定.//比如at24c02,每页8个字节,可以一次写入地址00H~07H共8个字节数据,当然,也可以从04H连续写4个字节数据//但是若从04H写入6个字节的数据时,写入数据的最后两个数据会写入00H,01H内,即超过一页地址的数据会在本页内循环写void WrToROMPage(unsigned char Data[],unsigned char Address,unsigned char Num){unsigned char i;bit ack=1;Start();Send(AddWr);//Write Addressack=Check_Ack();Send(Address);//Write sub Addressack=Check_Ack();for(i=0;i<Num;i++){Send(*(Data+i));//Write Dataif(!Check_Ack())Stop();}Stop();mDelay(20);}//连续读void RdFromRomNByte(unsigned char Data[],unsigned char Address,unsigned char Num) {unsigned char i;bit ack=1;Start();Send(AddWr);//Write Addressack=Check_Ack();Send(Address);//Write sub Addressack=Check_Ack();Start();Send(AddRd);//Read Addressack=Check_Ack();for(i=0;i<Num;i++){*(Data+i)=Read();//Read DataScl=0;if(i!=Num-1){Ack();}elseNoAck();}Stop();}头文件:/****************************************************************************** * 对基于IIC总线的EEPROM进行读写头文件** file: eeprom_device.h* name: zhzhchang* time: 2010.3.17* blogs: /zhzht19861011* V1.0******************************************************************************* **/#define AddWr 0xae //Write Address//8 位从器件地址的高4 位固定为1010,接下来的3位A2 A1 A0 为器件的地址位用来定义哪个器件//以及器件的哪个部分被主器件访问,8位地址的最低位作为读写控制位'1' 表示对从器件进行读操作,'0' 表示对从器件进行写操作.#define AddRd 0xaf //Read Address//全局变量sbit Sda=P1^2; //定义总线连接端口sbit Scl=P1^1; //定义时钟线sbit WP=P1^0; //写保护管脚void mDelay(unsigned char j);//A normal delay//write to ROMvoid WrToROM(unsigned char Data[],unsigned char Address,unsigned char Num);//任意读一个字节void RdFromROM(unsigned char Data[],unsigned char Address);//按页写void WrToROMPage(unsigned char Data[],unsigned char Address,unsigned char Num);//连续读void RdFromRomNByte(unsigned char Data[],unsigned char Address,unsigned charNum);。
ds2431读写方法
ds2431读写方法DS2431是一种基于I2C总线的1K位EEPROM芯片,具有读写功能。
以下是DS2431的读写方法的详细描述。
读取数据:DS2431芯片是通过I2C总线进行数据读取的,以下是DS2431的读取数据的步骤:1.启动I2C总线:首先,需要启动I2C总线,将总线拉低一个周期。
2.发送设备地址:然后,发送DS2431的设备地址,以确定要与DS2431通信。
3.发送读命令:发送读命令给DS2431,以告知芯片需要读取数据。
4.接收数据:然后,等待DS2431芯片发送要读取的数据。
在接收数据期间,主设备必须提供时钟信号。
5.停止I2C总线:最后,主设备向DS2431芯片发送停止信号,以结束I2C通信。
写入数据:DS2431芯片也可以通过I2C总线进行数据写入。
以下是DS2431的写入数据的步骤:1.启动I2C总线:首先,需要启动I2C总线,将总线拉低一个周期。
2.发送设备地址:然后,发送DS2431的设备地址,以确定要与DS2431通信。
3.发送写命令:发送写命令给DS2431,以告知芯片需要写入数据。
4.发送数据:接下来,发送要写入的数据到DS2431芯片。
在发送数据期间,主设备必须提供时钟信号。
5.停止I2C总线:最后,主设备向DS2431芯片发送停止信号,以结束I2C通信。
以上是DS2431读写数据的基本步骤,以下是一些注意事项和建议:1.DS2431芯片的设备地址是固定的,为0x18、在与DS2431通信之前,需要确保该地址正确。
2.读取和写入数据时,需要提供适当的时钟信号,以确保数据的顺利传输。
3.在读取数据之前,需要确保已经正确初始化I2C总线。
通常,需要设置I2C的时钟速度和选择适当的模式。
4.在写入数据之前,需要确保已经正确初始化I2C总线,并验证写入数据的有效性。
5.在进行连续读写操作时,需要留出适当的延迟时间,以确保DS2431正确响应所有操作。
总而言之,DS2431是一种功能强大的EEPROM芯片,通过I2C总线进行数据的读写。
STM32F4利用I2C向EEPROM写入、读取数据步骤
STM32F4利⽤I2C向EEPROM写⼊、读取数据步骤
写⼊⼀个字节:
第⼀步:使⽤库函数I2C_GenerateSTART()产⽣I2C起始信号,调⽤库函数I2C_CheckEvent()检测事件,若检测到下⼀事件,则进⼊通讯下⼀阶段
第⼆步:调⽤库函数I2C_Send7bitAddress()发送EEPROM的设备地址,并把数据传输⽅向设置为I2C_Direction_Transmitter(即发送⽅向),发送地址后以同样的⽅式检测相应的事件。
第三步:调⽤库函数I2C_SendData向EEPROM发送要写⼊的地址,发送完后等待EV8事件的产⽣。
第四步:继续调⽤库函数I2C_SendData向EEPROM发送要写⼊的数据,然后等待EV8事件的产⽣。
第五步:通讯结束,调⽤I2C_GenerateSTOP发送停⽌信号。
读取⼀字节的数据:
第⼀步:通过库函数I2C_GETFlagStatus()查询库函数是否处于忙碌状态,若不忙碌,则进⼊下⼀状态。
第⼆步:使⽤库函数I2C_GenerateSTART()产⽣起始信号,调⽤库函数I2C_CheckEvent()检测Event1,若检测成功则进⼊下⼀阶段。
第三步:发送EEPROM的设备地址,⽅向为I2C_Direction_Transmitter(即写⽅向),检测事件6
第四步:利⽤库函数I2C_Cmd重新使能I2C外设
第五步:利⽤库函数I2C_Senddata()发送要读取的EEPROM的内部地址,检测Event8事件的产⽣
第六步:产⽣第⼆次I2C起始信号,并检测相关事件
第七步:发送I2C设备地址
第⼋步:读取数据。
EEPROMI2C操作说明
EEPROMI2C操作说明EEPROM (Electrically Erasable Programmable Read-Only Memory)是一种非易失性存储器,可以通过电子方式擦除和编程,同时可以通过I2C总线进行操作。
本文将详细介绍EEPROM的I2C操作说明。
I2C(Inter-Integrated Circuit)是一种串行通信接口协议,可以在多个设备之间进行通信。
在EEPROM的I2C操作中,需要了解以下几个重要的概念和步骤。
1.设备地址:每个通过I2C连接的设备都有一个唯一的设备地址。
在EEPROM的I2C操作中,需要使用设备地址来与EEPROM进行通信。
2.起始条件和停止条件:I2C通信中,起始条件表示通信的开始,停止条件表示通信的结束。
起始条件由一个高电平到低电平的SCL上升沿和一个低电平的SDA下降沿组成,停止条件由一个低电平到高电平的SCL上升沿和一个高电平的SDA上升沿组成。
3. 数据传输:I2C通信中,数据可以以字节的形式进行传输。
每个字节由8个bit组成,包括7个数据位和1个校验位。
在进行EEPROM的I2C操作时,通常需要经过以下几个步骤:1.发送起始条件:将SCL和SDA引脚拉高,然后将SDA引脚拉低,形成起始条件。
2.发送设备地址和写命令:根据EEPROM的设备地址,将设备地址和写命令(0)发送到SDA引脚。
3.发送要写入的地址:将要写入数据的地址发送到SDA引脚。
4.发送数据:将要写入的数据发送到SDA引脚。
5.发送停止条件:将SCL引脚拉高,然后将SDA引脚拉高,形成停止条件。
实际的EEPROM的I2C操作可能还包括以下一些操作:1.读操作:通过发送读命令(1)和读取数据的地址,可以从EEPROM 中读取数据。
读操作与写操作类似,只是需要在发送设备地址时,将写命令(0)改为读命令(1)。
2.擦除操作:EEPROM的主要特点之一是可以擦除数据。
通过发送擦除命令和要擦除的数据的地址,可以将指定数据段擦除为初始值。
基于IIC协议的EEPROM读写功能的实现
基于IIC协议的EEPROM 读写功能的实现(一)设计要求能用IIC协议实现对EEPROM的数据储存与读出。
(二)设计目的1. 通过本项课程设计,可以培养独立思考、综合运用所学有关相应知识的能力,能更好的巩固《单片机原理与应用》课程学习的内容,掌握工程软件设计的基本方法,强化上机动手编程能力,闯过理论与实践相结合的难关!更加了解了单片机的好处和其可用性!同时增加了同学之间的团队合作精神!更加也体会到以后在工作中团队合作的重要性和必要性!2. 通过课程设计,使学生了解高级程序设计语言的结构,掌握基本的程序设计过程和技巧,掌握基本的分析问题和利用计算机求解问题的能力,具备初步的高级语言程序设计能力。
为后续各门课程的学习和毕业设计打下坚实基础。
3、知道IIC串行总线协议原理与运用,明白EEPROM的存储结构,知道用keil51软件和proteus仿真进行连调,实习单片机开发。
(三) 所用仪器设备电脑、keil51和proteus软件(四) 方案选择由于用IIC串行总线读写EEPROM我们不能直观的观察他们的读写现象,所以我们选择的是用液晶1602进行读写显示,用4*4矩阵键盘进行读写控制和数字的输入,选用AT89C51为主控制器,选用AT24C02进行存储。
所以这个课程设计主要分为三个模块:1、IIC串行总线读写EEPROM模块;2、液晶显示模块;3、矩阵键盘控制模块;(五) 具体的设计过程现将IIC协议与AT24C02的工作原理讲解如下,关于液晶与AT89C51的工作原理这里不再讲解。
一、IIC串行总线的组成与通信原理I2C总线是PHLIPS公司推出的一种串行总线,是具备多主机系统所需的包括总线裁决和高低速器件同步功能的高性能串行总线。
I2C总线只有两根双向信号线。
一根是数据线SDA,另一根是时钟线SCL。
I2C总线通过上拉电阻接正电源。
当总线空闲时,两根线均为高电平。
连到总线上的任一器件输出的低电平,都将使总线的信号变低,即各器件的SDA及SCL都是线“与”关系。
s3c2440 IIC读写EEPROM程序
//结束写
rIICCON = 0xaf; Delay(1);
//重新赋值,清应答中断位 //延迟等待结束生效
//上面写一个字节处理已经完成,但是最后一个应答后 rIICDS 无新数据,造成 //SCL 无法翻转,故下面再来个重复写设备地址操作,来等待最后一个数据发 送结束
for(;;)
{
rIICDS = slave_addr;
bit[3:0]:TxCLK = IICCLK/16
rIICSTAT = 1<<4;
//Enable Rx/Tx
rIICADD = 0x10;
//slave address
IIC 写数据格式: 1、开始写(start):rIICSTAT = 0xf0; 2、写设备地址带写命令 lave_addr:7 位+0(自动) 返回 ACK 3、写数据写入地址 IIC_addr 返回 ACK 4、写数据 IIC_data,可连续写多个数据,每个数据结束必须返回 ACK 5、结束写(stop):rIICSTAT = 0xd0;
S3C2440 程序---读写 EEPROM(不开中断)
硬件 IIC 类似软件模拟 IIC,硬件 IIC 读取 ACK 需要判断寄存器 IICCON 的 bit4 是否发生中断为 1。
初始化: rGPEUP = 0xc000; rGPECON = 0xa0000000;
//SDA SCL 关上拉 //GPE14 GPE15 设为 SDA SCL 功能
for(j=0;j<Read_Count;j++)
{
if(j==(Read_Count-1))
{ rIICCON = 0x2f;
//最后一个字节,返回 NOACK
EEPROM------AT24C01A_IIC总线驱动读写程序
/*河北工程大学信电学院自动化系调试成功EEPROM------A T24C01A_IIC总线驱动读写程序晶振:6MHz目标板:STC90C52AD编译环境:Keil C uVision V2.38a*/#include <reg52.h>#include <intrins.h>//由于是01A,1Kbit,故此这里第一个字节的读写格式是1010,A2,A1,A0,R/W #define Read_Addr 0xa1#define Write_Addr 0xa0#define uchar unsigned char//总线的定义,时钟线P1.0,数据线P1.1sbit SCL=P1^0;sbit SDA=P1^1;//短码数组uchar tab[]={2,5,6};void Start(){SDA=1;_nop_();SCL=1;_nop_();SDA=0;_nop_();SCL=0; //可以视作第一个SCL=0}void Stop(){SDA=0;_nop_();SCL=1;_nop_();SDA=1;}//------------------------------------------------------------------------- bit Write_Byte(uchar DA TA){bit Ack;uchar i;for(i=0;i<8;i++){SDA=(bit)(DA TA&0x80);_nop_();SCL=1;_nop_();_nop_();SCL=0; //第九个SCL=0DA TA<<=1;}SDA=1; //主机释放SDA_nop_();_nop_();SCL=1; //第九个SCL=1_nop_();//SDA=1; //对程序好像没出来影响Ack=SDA; //前面是否先置1,特别注意是否是准双向口SCL=0; //下一个字节的第一个SCL=0return (Ack);}uchar Read_Byte(){uchar DA TA,i;for(i=0;i<8;i++){SCL=1;DA TA<<=1;//注意强制类型转换SDA=1; //对程序好像没出来影响DA TA|=(uchar)SDA;//前面是否先置1,特别注意是否是准双向口SCL=0;}return(DA TA);}//-------------------------------------------------------------------------//读当前地址的数据uchar Read_Current_Addr(){uchar DA TA;Start();Write_Byte(Read_Addr);DA TA=Read_Byte();Stop();return(DA TA);}//向指定地址读数据uchar Read_Random_Addr(uchar addr) //256*8byte=1024Kbit,uchar类型正好合适{uchar DA TA;Start();Write_Byte(Write_Addr);Write_Byte(addr);DA TA=Read_Current_Addr();return(DA TA);}/*-------------------------------------------------------------功能:从EEPROM中给定一个地址连续读NLEN个字节数据存放在以指针nContent开头的往下内容。
基于STM32F103的I2C总线EEPROM的读写(带超时检测)
基于STM32F103的I2C总线EEPROM的读写(带超时检测)————————————————————————————————作者:————————————————————————————————日期:【原创】基于STM32F103的I2C总线EEPROM的读写(带超时检测)本人最近参考了st 公司关于STM32的I2C的例程,觉得不是很适合我的应用,于是自己写了一个基于STM32F103的I2C总线EEPROM(24C256)的读写程序,总线的最高速度可达400K,现在将源代码原原本本的公布如下,希望得到高手的指点,也希望能够给和我有同样想法的同仁们一些参考价值。
注意:最好将固件库升级一下,st网站上面有V2。
03库的补丁。
u32 ulTimeOut_Time;/***********************************************************************************************************I2C_EE_WriteStr()** Description : 将一个数据块写入EEPROM 的指定的地址**Argument(s) : xChip - 从器件地址* xAddr — EEPROM存储空间地址*xpBuf —数据缓冲区指针* xLen - 数据长度**Return(s) : none.**Caller(s) : Application.** Note(s) :(1)*——--—-——----————--—-——---——--—--—---—-—----———--—-—-————-——-——---—-—--—————----——--—————-—-——--——-———--*Modified by :* Modified date :* Description :*—---———----———-—------——--—--—-——————-—-————-——-———-——---—--——-——————--—————----———-—---—-——-——-—-——--—**********************************************************************************************************/void I2C_EE_WriteStr(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(); // 允许总线,写允许retry = 5; // 重试5次while(len){err = I2C_EE_Drv_WriteByte(xChip,addr, *pbuf);if(err){if(--retry == 0 ) // 已经试了5次,写下一个数据{retry = 5;pbuf++;addr++;len——;}}else // 顺利,写下一个数据{pbuf++;addr++;len--;}}I2C_EE_Drv_BusDis(); // 失能总线,写保护}/*********************************************************************************************************** I2C_EE_ReadStr()**Description :从EEPROM 的指定的地址读出一个数据块** Argument(s) : xChip —从器件地址* xAddr - EEPROM存储空间地址*xpBuf - 数据缓冲区指针*xLen - 数据长度**Return(s) : none.** Caller(s) : Application。
EEPROM读写程序的设计及说明(v1.1改进版)
EEPROM读写程序的设计及说明一、I2C 总线概述I2C 总线是PHILIPS 公司推出的芯片间串行数据传输总线。
I2C 总线通过两根线(串行数据线SDA 和串行时钟线SCL)使挂接到总线上的器件相互进行信息传递,能够十分方便地地构成多机系统和外围器件扩展系统。
I2C 器件是把I2C 的协议植入器件的I/O 接口,使用时器件直接挂到I2C 总线上即可。
总线使用软件寻址来识别每个器件--微控制器、存储器、LCD、驱动器时钟芯片及其它I2C 总线器件,而无须使用片选信号,是否选中是由主器件发出的I2C 从地址决定的而I2C 器件的从地址是由I2C 总线委员会实行统一发配的。
总线上的每一次数据传送活动都是主控器先发送起始信号,然后主控器发送被控器的地址及读写位1个字节,这之后是主控器等待被控器的应答信号(接着的第九位),再接着就是主控器发送数据给被控器(写被控器)或接收被控器发出来的数据(读被控器),最后由主控器发出停止信号通知被控器结束整个数据传送过程。
I2C 总线的数据传送过程如下图所示。
I2C 总线协议规定传送的数据长度为8位,而每次传送的数据字节数由被控器所限制如24C01(128 字节EEPROM)规定一次最多可以传送8个字节,24C02(256字节EEPROM)规定一次最多可传送16个字节。
按照I2C总线协议,总线上非单片机类型的外围器件地址由器件编号地址(高4位D7~D4由器件类型决定)和器件引脚地址(D3~D1)组成,如24C01/02/03/04的器件编号地址为1010。
器件的引脚地址由A2A1A0三根硬件地址线决定,最后一位为读写控制位,1表示读,0表示写,如下图示。
二、程序框图三、EEPROM应用程序1、整体功能说明本程序利用NEC公司的9177芯片,用软件的模拟方法实现对EEPROM器件(如24C04)的读写操作。
2、变量说明EEDATA 所需读或写的EEPROM参数个数PARAADD EEPROM读写的地址变量EEWRDELAY 写EEPROM的延时时间计时变量3、标志说明_EEPRW 读写标志(0=EEPROM写,1=EEPROM读)_ACKERR EEPROM有无应答标志(1=无应答,0=有应答)_ERRORFG EEPROM出错标志(1=EEPROM出错,0=EEPROM无错)_PARAERR EEPROM参数错误(1=EEPROM参数出错,0=EEPROM参数无错)4、常量说明SLAW EQU 0A0H 表示EEPROM器件地址及EEPROM写SLAR EQU 0A1H 表示EEPROM器件地址及EEPROM读P_EESDA EQU P1.1 连接EEPROM数据线(SDA)的芯片管脚P_EESCL EQU P1.0 连接EEPROM 时钟线(SCL)的芯片管脚5、模块使用说明(1)本EEPROM读写模块可直接调用,在NEC9177调用方法为:CALL !EEPROMRW;(2)调用前需给以下几个参数进行赋值所需读写的EEPROM参数个数:EEDATA 例如:MOV EEDATA,#32所需读写的EEPROM参数初始地址:PARAADD 例如:MOV PARAADD,#0读写EEPROM数据所存放的地址:HL 例如:MOVW HL,#PARABUF程序要求为读或写EEPROM标志:_EEPRW 例如:SET1 _EEPRW6、应用范围此程序段可应用于NEC9177作为主芯片的电控中,其中外围的EEPROM器件应具有I2C总线的特性(如24C04),其他具有I2C特性的器件也可做参考。
I2C协议—24C08读写操作源程序
I2C协议—24C08读写操作源程序以下是一个基于Arduino的24C08 I2C协议读写操作的源程序示例:#include <Wire.h>#define EEPROM_ADDRESS 0x50 // 24C08的I2C地址#define EEPROM_SIZE 1024 // EEPROM 的总容量为1KBvoid setuWire.begin(; // 初始化 I2C 总线Serial.begin(9600); // 初始化串口通信void loo//写入数据到EEPROM的地址0byte dataToWrite = 100;writeByte(0, dataToWrite);//从EEPROM的地址0读取数据byte dataRead = readByte(0);Serial.print("Data read from EEPROM: ");Serial.println(dataRead);delay(1000);void writeByte(int address, byte data)//将地址分成高8位和低8位byte highAddress = address >> 8;byte lowAddress = address & 0xFF;Wire.beginTransmission(EEPROM_ADDRESS); // 开始 I2C 传输//写入内存地址Wire.write(highAddress);Wire.write(lowAddress);//写入数据Wire.write(data);Wire.endTransmission(; // 结束 I2C 传输delay(5); //等待写入完成byte readByte(int address)//将地址分成高8位和低8位byte highAddress = address >> 8;byte lowAddress = address & 0xFF;Wire.beginTransmission(EEPROM_ADDRESS); // 开始 I2C 传输//写入内存地址Wire.write(highAddress);Wire.write(lowAddress);Wire.endTransmission(false); // 结束 I2C 传输,但保持连接Wire.requestFrom(EEPROM_ADDRESS, 1); // 从EEPROM读取1个字节byte dataRead;if (Wire.available()dataRead = Wire.read(;}return dataRead;在该示例中,我们使用了Arduino的Wire库来与24C08 EEPROM芯片进行I2C通信。
i2c读写eeprom手册
i2c读写eeprom手册
I2C读写EEPROM的手册主要包括以下步骤:
1. 确定EEPROM的设备地址:I2C通讯时,地址跟读写方向连在一起构成一个8位数。
当R/W位为0时,表示写方向,加上7位地址,其值为
“0xA0”,常称该值为I2C设备的“写地址”;当R/W位为1时,表示读方向,加上7位地址,其值为“0xA1”,常称该值为“读地址”。
2. 准备读写操作:主机产生并发送起始信号到从机,将控制命令写入从机设备,读写控制位设置为低电平,表示对从机进行数据写操作,控制命令的写入高位在前低位在后。
3. 发送存储地址:从机接收到控制指令后,回传应答信号,主机接收到应答信号后开始存储地址的写入。
4. 进行读写操作:根据一次读操作读取数据量的多少,读操作可分为随机读操作和顺序读操作。
随机读操作可以理解为单字节数据的读取。
5. 结束操作:读写操作完成后,主机发送停止信号结束操作。
请注意,所有I2C设备均支持单字节数据写入操作,但只有部分I2C设备支持页写操作;且支持页写操作的设备,一次页写操作写入的字节数不能超过设备单页包含的存储单元数。
此外,EEPROM芯片中还有一个WP引脚,
具有写保护功能,当该引脚电平为高时,禁止写入数据,当引脚为低电平时,可写入数据。
以上步骤仅供参考,如果使用实验板EEPROM的型号、设备地址或控制引
脚不一样,需根据实际工程修改。
13-I2C读写EEPROM(AT24C02)0
I2C( EEPROM-AT24C02 ) 偠㗙fireE-Mail firestm32@QQ313303034⹀ӊ 䞢☿STM32⠜ ST3.0.0偠 䗄˖ EERPOM ˈ 䇏 ˈ䖯㸠 偠ˈ䗮䖛І Ϣ䇏 ⱘ ˈ 䕧 偠㒧 DŽ⹀ӊ䖲 ˖PB6-I2C1_SCLˈPB7-I2C1_SDAӊ˖startup/start_stm32f10x_hd.cCMSIS/core_cm3.cCMSIS/system_stm32f10x.cFWlib/stm32f10x_gpio.cFWlib/stm32f10x_rcc.cFWlib/stm32f10x_usart.cFWlib/stm32f10x_i2c.c⫼ ӊ: USER/main.cUSER/stm32f10x_it.cUSER/usart1.cUSER/i2c_ee.c䞢☿STM32 I2C-EEPROM⹀ӊ ⧚ ˖I2Cㅔҟ->I2C(㢃⠛䯈) 㒓 䖲 І㸠I2C 㒓DŽ կ Џ 㛑ˈ I2C 㒓⡍ ⱘ ǃ 䆂ǃӆ㺕 DŽ 䗳ϸ⾡ ˈstm32ⱘI2C ҹՓ⫼DMA DŽ䞢☿STM32 ⫼ⱘ STM32F103VET6DŽ 2ϾI2C DŽI/O НЎPB6-I2C1_SCLˈPB7-I2C1_SDA˗PB10-I2C2_SCLˈPB11-I2C2_SDADŽ 偠Փ⫼I2C1ˈ 䖲 EERPOM˄ ˖AT24C02˅ⱘSCL SDA㒓DŽ ⦄I2C䗮䆃ˈ EERPOM䖯㸠䇏 DŽ偠䞛⫼Џ ˈ ⫼Џ 䗕 Џ DŽ䗮䖛 䆶џӊⱘ ⹂ ℷ 䗮䆃DŽ偠䆆㾷->佪 㽕⏏ ⫼ⱘ ӊˈ ӊ ϟFwlibϟ Ӏ䳔⏏ ҹϟ ӊ˖1.stm32f10x_gpio.c2.stm32f10x_rcc.c3.stm32f10x_usart.c4.stm32f10x_i2c.c䖬㽕 stm32f10x_conf.hЁ Ⳍ ⱘ ӊ⏏ 䖯 ˖1./*Uncomment the line below to enable peripheral header file inclusion*/2./*#include"stm32f10x_adc.h"*/3./*#include"stm32f10x_bkp.h"*/4./*#include"stm32f10x_can.h"*/5./*#include"stm32f10x_crc.h"*/6./*#include"stm32f10x_dac.h"*/7./*#include"stm32f10x_dbgmcu.h"*/8./*#include"stm32f10x_dma.h"*/9./*#include"stm32f10x_exti.h"*/10./*#include"stm32f10x_flash.h"*/11./*#include"stm32f10x_fsmc.h"*/12.#include"stm32f10x_gpio.h"13.#include"stm32f10x_i2c.h"14./*#include"stm32f10x_iwdg.h"*/15./*#include"stm32f10x_pwr.h"*/16.#include"stm32f10x_rcc.h"17./*#include"stm32f10x_rtc.h"*/18./*#include"stm32f10x_sdio.h"*/19./*#include"stm32f10x_spi.h"*/20./*#include"stm32f10x_tim.h"*/21.#include"stm32f10x_usart.h"22./*#include"stm32f10x_wwdg.h"*/23./*#include"misc.h"*//*High level functions for NVIC and SysTick(add-on to CMSIS functions)*/䜡㕂 䳔ⱘ ӊП ˈ Ӏ Ңmain ˖1./*2.* ˖main3.* 䗄˖Џ4.*䕧 ˖5.*䕧 ˖6.*䖨 ˖7.*/8.int main(void)9.{10./*䜡㕂㋏㒳 䩳Ў72M*/11.SystemInit();;12.13./*І 1 */ART1_Config();15.16./*I2C 䆒 (AT24C02) */17.I2C_EE_Init();18.ART1_printf(USART1,"\r\n䖭 ϔϾI2C 䆒(AT24C02)䇏 ⌟䆩՟\r\n");ART1_printf(USART1,"\r\n("__DATE__"-"__TIME__")\r\n");21.22.I2C_Test();23.24.while(1)25.{26.}27.}㋏㒳 SystemInit(); ㋏㒳 䩳䆒㕂Ў72MˈUSART1_Config();䜡㕂І ˈ Ѣ䖭ϸϾ ⱘ ԧ䆆㾷 ҹ 㗗 䴶ⱘ ˈ䖭䞠ϡ 䆺䗄DŽ/*1.* ˖I2C_EE_Init2.* 䗄˖I2C 䆒(EEPROM)3.*䕧 ˖4.*䕧 ˖5.*䇗⫼˖ 䚼䇗⫼6.*/7.void I2C_EE_Init(void)8.{9.10.I2C_GPIO_Config();11.12.I2C_Mode_Configu();13.14./*ḍ ӊi2c_ee.hЁⱘ Н 䗝 EEPROM㽕 ⱘ */15.#ifdef EEPROM_Block0_ADDRESS16./*䗝 EEPROM Block0 */17.EEPROM_ADDRESS=EEPROM_Block0_ADDRESS;18.#endif19.20.#ifdef EEPROM_Block1_ADDRESS21./*䗝 EEPROM Block1 */22.EEPROM_ADDRESS=EEPROM_Block1_ADDRESS;23.#endif24.25.#ifdef EEPROM_Block2_ADDRESS26./*䗝 EEPROM Block2 */27.EEPROM_ADDRESS=EEPROM_Block2_ADDRESS;28.#endif29.30.#ifdef EEPROM_Block3_ADDRESS31./*䗝 EEPROM Block3 */32.EEPROM_ADDRESS=EEPROM_Block3_ADDRESS;33.#endif}I2C_EE_Init(); ⫼ 㓪 ⱘ ˈ Ё䇗⫼њI2C_GPIO_Config();䜡㕂 I2C ⫼ⱘI/Oッ ˈ䇗⫼I2C_Mode_Configu();䆒㕂I2Cⱘ DŽ Փ㛑Ⳍ 䆒ⱘ 䩳DŽ Ёⱘ ӊ㓪䆥⹂ њEERPOMⱘ ӊ ˈ Ӏⱘ⹀ӊ䆒㕂 ˈ Ў0xA0˗1./*2.* ˖I2C_EE_Test3.* 䗄˖I2C(AT24C02)䇏 ⌟䆩DŽ4.*䕧 ˖5.*䕧 ˖6.*䖨 ˖7.*/8.void I2C_Test(void)9.{10.u16i;11.12.printf(" ⱘ \n\r");13.14.for(i=0;i<=255;i++)// 㓧15.{16.I2c_Buf_Write[i]=i;17.18.printf("0x%02X",I2c_Buf_Write[i]);19.if(i%16==15)20.printf("\n\r");21.}22.23.// I2c_Buf_WriteЁ乎 䗦 ⱘ EERPOMЁ24.I2C_EE_BufferWrite(I2c_Buf_Write,EEP_Firstpage,256);25.26.printf("\n\r䇏 ⱘ \n\r");27.// EEPROM䇏 乎 I2c_Buf_ReadЁ28.I2C_EE_BufferRead(I2c_Buf_Read,EEP_Firstpage,256);29.30.// I2c_Buf_ReadЁⱘ 䗮䖛І31.for(i=0;i<256;i++)32.{33.if(I2c_Buf_Read[i]!=I2c_Buf_Write[i])34.{35.printf("0x%02X",I2c_Buf_Read[i]);36.printf("䫭䇃:I2C EEPROM Ϣ䇏 ⱘ ϡϔ㟈\n\r");37.return;38.}39.printf("0x%02X",I2c_Buf_Read[i]);40.if(i%16==15)41.printf("\n\r");42.43.}44.printf("I2C(AT24C02)䇏 ⌟䆩 \n\r");45.}I2C_Test(void) 䖭Ͼ՟Ё Џ㽕ⱘ䚼 ˈ 0~255 乎 㓧 䗮䖛І ッ ˈ ⴔ 㓧 ⱘ 䗮䖛䇗⫼I2C_EE_BufferWrite() EEPROMDŽ1./*2.* ˖I2C_EE_BufferWrite3.* 䗄˖ 㓧 Ёⱘ I2C EEPROMЁ4.*䕧 ˖-pBuffer㓧 䩜5.*-WriteAddr ⱘEEPROMⱘ6.*-NumByteToWrite㽕 EEPROMⱘ 㡖7.*䕧 ˖8.*䖨 ˖9.*䇗⫼˖ 䚼䇗⫼10.*/11.void I2C_EE_BufferWrite(u8*pBuffer,u8WriteAddr,u16NumByteToWrite)12.{13.u8NumOfPage=0,NumOfSingle=0,Addr=0,count=0;14.15.Addr=WriteAddr%I2C_PageSize;16.count=I2C_PageSize-Addr;17.NumOfPage=NumByteToWrite/I2C_PageSize;18.NumOfSingle=NumByteToWrite%I2C_PageSize;19.20./*If WriteAddr is I2C_PageSize aligned*/21.if(Addr==0)22.{23./*If NumByteToWrite<I2C_PageSize*/24.if(NumOfPage==0)25.{26.I2C_EE_PageWrite(pBuffer,WriteAddr,NumOfSingle);27.I2C_EE_WaitEepromStandbyState();28.}29./*If NumByteToWrite>I2C_PageSize*/30.else31.{32.while(NumOfPage--)33.{34.I2C_EE_PageWrite(pBuffer,WriteAddr,I2C_PageSize);35.I2C_EE_WaitEepromStandbyState();36.WriteAddr+=I2C_PageSize;37.pBuffer+=I2C_PageSize;38.}39.40.if(NumOfSingle!=0)41.{42.I2C_EE_PageWrite(pBuffer,WriteAddr,NumOfSingle);43.I2C_EE_WaitEepromStandbyState();44.}45.}46.}47./*If WriteAddr is not I2C_PageSize aligned*/48.else49.{50./*If NumByteToWrite<I2C_PageSize*/51.if(NumOfPage==0)52.{53.I2C_EE_PageWrite(pBuffer,WriteAddr,NumOfSingle);54.I2C_EE_WaitEepromStandbyState();55.}56./*If NumByteToWrite>I2C_PageSize*/57.else58.{59.NumByteToWrite-=count;60.NumOfPage=NumByteToWrite/I2C_PageSize;61.NumOfSingle=NumByteToWrite%I2C_PageSize;62.63.if(count!=0)64.{65.I2C_EE_PageWrite(pBuffer,WriteAddr,count);66.I2C_EE_WaitEepromStandbyState();67.WriteAddr+=count;68.pBuffer+=count;69.}70.71.while(NumOfPage--)72.{73.I2C_EE_PageWrite(pBuffer,WriteAddr,I2C_PageSize);74.I2C_EE_WaitEepromStandbyState();75.WriteAddr+=I2C_PageSize;76.pBuffer+=I2C_PageSize;77.}78.if(NumOfSingle!=0)79.{80.I2C_EE_PageWrite(pBuffer,WriteAddr,NumOfSingle);81.I2C_EE_WaitEepromStandbyState();82.}83.}84.}85.}ЎAT24C02 ⱘEEPROM 义 Ё↣义 㡖 Ў8 㡖ˈ㢹䍙䖛8 㡖 Ӯ 䆹义ⱘ䍋 㽚Ⲫ ˈ ℸ䳔㽕I2C_EE_BufferWrite() ⧚ ԡ㕂 㓧 ⱘ DŽ ⧚ ⱘ Ѹ㒭I2C_EE_PageWrite() ˈ䖭Ͼ ϢEEPROM䖯㸠I2C䗮䆃ⱘ ˈҹϟ Ӏ䗮䖛 I2C_EE_PageWrite() њ㾷stm32ⱘI2C䗮䆃 ⊩DŽ1./*2.* ˖I2C_EE_PageWrite3.* 䗄˖ EEPROMⱘϔϾ ⦃Ё ҹ Ͼ 㡖ˈԚϔ ⱘ 㡖4.*ϡ㛑䍙䖛EEPROM义ⱘ DŽAT24C02↣义 8Ͼ 㡖DŽ5.*䕧 ˖-pBuffer㓧 䩜6.*-WriteAddr ⱘEEPROMⱘ7.*-NumByteToWrite㽕 EEPROMⱘ 㡖8.*䕧 ˖9.*䖨 ˖10.*䇗⫼˖ 䚼䇗⫼11.*/12.void I2C_EE_PageWrite(u8*pBuffer,u8WriteAddr,u8NumByteToWrite)13.{14.while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));//Added by Najoua27/08/200815.16./*Send START condition*/17.I2C_GenerateSTART(I2C1,ENABLE);18.19./*Test on EV5and clear it*/20.while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));21.22./*Send EEPROM address for write*/23.I2C_Send7bitAddress(I2C1,EEPROM_ADDRESS,I2C_Direction_Transmitter);24.25./*Test on EV6and clear it*/26.while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));27.28./*Send the EEPROM's internal address to write to*/29.I2C_SendData(I2C1,WriteAddr);30.31./*Test on EV8and clear it*/32.while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));33.34./*While there is data to be written*/35.while(NumByteToWrite--)36.{37./*Send the current byte*/38.I2C_SendData(I2C1,*pBuffer);39.40./*Point to the next byte to be written*/41.pBuffer++;42.43./*Test on EV8and clear it*/44.while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));45.}46./*Send STOP condition*/47.I2C_GenerateSTOP(I2C1,ENABLE);48.}Ңstm32 㗗 ⱘ ҹⳟ ˈ I2Cⱘ䗮䆃䖛ЁˈӮѻ⫳ϔ㋏ ⱘџӊˈ ⦄џӊ Ⳍ ⱘ ЁӮѻ⫳ 㕂ԡDŽ㞾ljSTM32 㗗 Ё NJDŽӀ I2C䗮䆃 ˈ ҹ䗮䖛 ⦃䇗⫼ I2C_CheckEvent()䖯㸠 䆶ˈҹ⹂ Ϟϔ ϟϔϾI2C䗮䆃䆃 DŽ ˖ ⹂ SDA 㒓ぎ䯆ⱘП ˈЎЏ 䗕 ⱘstm32 䍋 䆃 ˈ㢹 ˈ䖭 Ӯѻ⫳Āџӊ5ā˄EV5˅ˈ Ӏ䇗⫼while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT)); Ẕ⌟䖭Ͼџӊˈ⹂ Ẕ⌟ П 㸠ϟϔ DŽĀI2C_EVENT_MASTER_MODE_SELECTā ӊ Ё ҹ 䖭 ĀEV5āⱘ ˈ 䴶ⱘⳌ ㉏ԐDŽ⦄ Ӏ I2C_EE_BufferWrite()䖭Ͼ ˈ ↣䇗⫼ I2C_EE_PageWrite() ˈ䛑䇗⫼њϔϾI2C_EE_WaitEepromStandbyState() DŽ1./*2.* ˖I2C_EE_WaitEepromStandbyState3.* 䗄˖Wait for EEPROM Standby state4.*䕧 ˖5.*䕧 ˖6.*䖨 ˖7.*䇗⫼˖8.*/9.void I2C_EE_WaitEepromStandbyState(void)10.{11.vu16SR1_Tmp=0;12.13.do14.{15./*Send START condition*/16.I2C_GenerateSTART(I2C1,ENABLE);17./*Read I2C1SR1register*/18.SR1_Tmp=I2C_ReadRegister(I2C1,I2C_Register_SR1);19./*Send EEPROM address for write*/20.I2C_Send7bitAddress(I2C1,EEPROM_ADDRESS,I2C_Direction_Transmitter);21.}while(!(I2C_ReadRegister(I2C1,I2C_Register_SR1)&0x0002));22.23./*Clear AF flag*/24.I2C_ClearFlag(I2C1,I2C_FLAG_AF);25./*STOP condition*/26.I2C_GenerateSTOP(I2C1,ENABLE);//Added by Najoua27/08/200827.}䖭 ⫼њEEPROM ˈ 䚼 ⱘ 䯈 ϡӮ Џ ⱘ䇋∖ ㄨⱘ⡍ DŽ ҹ䖭Ͼ ⦃ 䗕䍋 䆃 ˈ㢹Ẕ⌟ EEPROMⱘ ㄨˈ 䇈 EEPROM 㒣 Ϟϔℹⱘ ˈ䖯 Standby⢊ ˈ ҹ䖯㸠ϟϔℹⱘ њDŽI2C_Test()䖭Ͼ ˈ ϔϟ 䇗⫼ⱘ䇏EEPROM I2C_EE_BufferRead()DŽ1./*2.* ˖I2C_EE_BufferRead3.* 䗄˖ҢEEPROM䞠䴶䇏 ϔ DŽ4.*䕧 ˖-pBuffer ҢEEPROM䇏 ⱘ ⱘ㓧 䩜DŽ5.*-WriteAddr ⱘEEPROMⱘ DŽ6.*-NumByteToWrite㽕ҢEEPROM䇏 ⱘ 㡖 DŽ7.*䕧 ˖8.*䖨 ˖9.*䇗⫼˖ 䚼䇗⫼10.*/11.void I2C_EE_BufferRead(u8*pBuffer,u8ReadAddr,u16NumByteToRead)12.{13.//*((u8*)0x4001080c)|=0x80;14.while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));//Added by Najoua27/08/200815.16.17./*Send START condition*/18.I2C_GenerateSTART(I2C1,ENABLE);19.//*((u8*)0x4001080c)&=~0x80;20.21./*Test on EV5and clear it*/22.while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));23.24./*Send EEPROM address for write*/25.I2C_Send7bitAddress(I2C1,EEPROM_ADDRESS,I2C_Direction_Transmitter);26.27./*Test on EV6and clear it*/28.while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));29.30./*Clear EV6by setting again the PE bit*/31.I2C_Cmd(I2C1,ENABLE);32.33./*Send the EEPROM's internal address to write to*/34.I2C_SendData(I2C1,ReadAddr);35.36./*Test on EV8and clear it*/37.while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));38.39./*Send STRAT condition a second time*/40.I2C_GenerateSTART(I2C1,ENABLE);41.42./*Test on EV5and clear it*/43.while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));44.45./*Send EEPROM address for read*/46.I2C_Send7bitAddress(I2C1,EEPROM_ADDRESS,I2C_Direction_Receiver);47.48./*Test on EV6and clear it*/49.while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));50.51./*While there is data to be read*/52.while(NumByteToRead)53.{54.if(NumByteToRead==1)55.{56./*Disable Acknowledgement*/57.I2C_AcknowledgeConfig(I2C1,DISABLE);58.59./*Send STOP Condition*/60.I2C_GenerateSTOP(I2C1,ENABLE);61.}62.63./*Test on EV7and clear it*/64.if(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED))65.{66./*Read a byte from the EEPROM*/67.*pBuffer=I2C_ReceiveData(I2C1);68.69./*Point to the next location where the byte read will be saved*/70.pBuffer++;71.72./*Decrement the read bytes counter*/73.NumByteToRead--;74.}75.}76.77./*Enable Acknowledgement to be ready for another reception*/78.I2C_AcknowledgeConfig(I2C1,ENABLE);79.}䖭Ͼ䇏EEPROM Ϣ ⱘ㉏Ԑˈг ⫼I2C_CheckEvent() ⹂ 䗮䆃ℷ 䖯㸠ⱘˈ㽕⊼ ϔϟⱘ 䇏 䙉 I2Cⱘ ˈЏ 䗕 stm32㽕 ϸ䍋 I2C䆃 㛑 ゟ䗮䆃DŽˈ 㒧ϔϟ stm32 ԩ ゟϢEEPROMⱘ䗮䆃DŽ1ǃ䜡㕂I/Oッ ˈ⹂ 䜡㕂I2Cⱘ ˈՓ㛑GPIO I2C 䩳DŽ2ǃ ˖Ẕ⌟SDA ぎ䯆˗-> I2C 䆂 䍋 䆃 ˗-> 7ԡ ӊ ˗->㽕 ⱘ 佪 ˗->⫼义 㡖 ˗↣Ͼ П 㽕Ẕ⌟Āџӊā⹂ DŽ Ẕ⌟EEPROM 䖯 standby⢊ DŽ3ǃ䇏˖Ẕ⌟SDA ぎ䯆˗-> I2C 䆂 䍋 䆃 ˗-> 7ԡ ӊ ˄Ӿ ˅˗-> 㽕䇏 ⱘ 佪 ˗->䞡 䍋 䆃 ˗-> 7ԡ ӊ 䇏 ˗-> ˗㉏Ԑ ˈ↣Ͼ П 㽕Ẕ⌟Āџӊā⹂ DŽ偠⦄䈵->䞢☿STM32 կ⬉(DC5V)ˈ ϞJLINKˈ ϞІ 㒓(ϸ 䛑 ↡ⱘѸ 㒓)ˈ 䍙㑻㒜ッˈ䜡㕂䍙㑻㒜ッЎ115200 8-N-1ˈ 㓪䆥 ⱘ ϟ䕑 ˈ ⳟ 䍙㑻㒜ッ ϟ ˖ⱘ ˖䇏 ⱘ ˖ 偠㒧 ˈ䇏 ⱘ Ϣ ⱘϔ㟈ˈ 偠 ʽ偠䆆㾷 ↩ˈ䞢☿⼱ д ^_^DŽ。
I2C读写EEPROM程序
sda=1;
delay();
scl=1;
delay();
sda=0;
delay();
}
void stop(void)
{
sda=0;
delay();
scl=1;
delay();
sda=1;
delay();
}
void ack(void)
stop(); */
uchar k;
k=read_byte(7);
k=k%10;
P1=smg_du[k];
k++;
write_byte(7,k);
while(1);
}
void write_byte(uchar add,uchar dat)
{
init();
disp[7]=time_data[4]/16;
}
void display(void)
{
uchar i;
for(i=0;i<8;i++)
{
P1=smg_du[disp[i]];
P2=smg_we[i];
delay_50us(20);
}
}
void main(void)
}
void main()
{
/* init();
start();
iicwr_byte(0xa0);
ack();
iicwr_byte(10);
ack();
iicwr_byte(0x55);
ack();
stop();
delay1();
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
51单片机第二十二课IIC总线的使用EEPROM芯片的读写
所属类别:课程代码发布日期:2011-03-05 点击量:341 #include<reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit sda=P2^1;
sbit scl=P2^0;
unsigned char code smg_du[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e, 0x79,0x71,0x00};
unsigned char code smg_we[]={0x08,0x18,0x28,0x38,0x48,0x58,0x68,0x78};
void start(void);
void stop(void);
void ack(void);
void noack(void);
void iicwr_byte(uchar dat);
uchar iicre_byte(void);
void delay (void);
void init(void);
void delay1(void);
void write_byte(uchar add,uchar dat);
uchar read_byte(uchar add);
///////////////////////////////////
void delay1(void)
{
uint a=30000;
while(a--);
}
void delay (void)
{
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();
}
void start(void)
{
sda=1;
delay();
scl=1;
delay();
sda=0;
delay();
}
void stop(void)
{
sda=0;
delay();
scl=1;
delay();
sda=1;
delay();
}
void ack(void)
{
uchar i;
scl=1;
delay();
while((sda==1)&&(i<200))i++; scl=0;
delay();
}
void noack(void)
{
sda=1;
delay();
scl=1;
delay();
scl=0;
delay();
}
void init(void)
{
sda=1;
scl=1;
}
void iicwr_byte(uchar dat) {
uchar i;
scl=0;
for(i=0;i<8;i++)
{
if(dat&0x80)
{
sda=1;
}
else
{
sda=0;
}
dat=dat<<1;
delay();
scl=1;
delay();
scl=0;
delay();
}
sda=1;
delay();
}
uchar iicre_byte(void) {
uchar i;
uchar dat;
scl=0;
delay();
sda=1;
delay();
for(i=0;i<8;i++)
{
scl=1;
delay();
dat=dat<<1;
if(sda)
{
dat++;//
}
scl=0;
delay();
}
return dat;
}
void main()
{
/* init();
start();
iicwr_byte(0xa0); ack();
iicwr_byte(10); ack();
iicwr_byte(0x55); ack();
stop();
delay1();
////////////////////
////////////////////
init();
start();
iicwr_byte(0xa0); ack();
iicwr_byte(10); ack();
start();
iicwr_byte(0xa1); ack();
P0=iicre_byte(); noack();
stop(); */
uchar k;
k=read_byte(7); k=k%10;
P1=smg_du[k]; k++;
write_byte(7,k);
while(1);
}
void write_byte(uchar add,uchar dat) {
init();
start();
iicwr_byte(0xa0);
ack();
iicwr_byte(add);
ack();
iicwr_byte(dat);
ack();
stop();
}
uchar read_byte(uchar add)
{
uchar a;
init();
start();
iicwr_byte(0xa0);
ack();
iicwr_byte(add);
ack();
start();
iicwr_byte(0xa1);
ack();
a=iicre_byte();
noack();
stop();
return a;
}。