STM32作为主机I2C,读写24C02 EEPROM
1、 时钟和数据的传输:开始和停止条件,数据在SCL的高电平期间有效,在SCL的低电平期间改变。
2、 开始条件:在SCL高电平期间,SDA产生一个下降沿
3、 停止条件:在SCL高电平期间,SDA产生一个上升沿
4、 应答:成功接收到数据(地址和数据),产生一个应答位(在第9个时钟周期,将SDA拉低)
下面是源程序:原理上说,下面程序再移植时,只要将数据类型变化,可以应用到任何处理器
AT24c02.h
#ifndef __24CXX_H
#define __24CXX_H
#include "i2c.h"
/***************************************************************
- 说明:以下参数是AT24Cxx的寻址空间,C0x ,X 表示XK 如C01表示1K
- 127表示2^7 1Kbit/8=128Byte 128字节
- 255表示2^8 2Kbit/8=256Byte 256字节
- 512表示2^9 4Kbit/8=512Byte 512字节
-
***************************************************************/
#define AT24C01 127
#define AT24C02 255
#define AT24C04 511
#define AT24C08 1023
#define AT24C16 2047
#define AT24C32 4095
#define AT24C64 8191
#define AT24C128 16383
#define AT24C256 32767
/**************************************************************
--板子使用的是24c02,所以定义EE_TYPE为AT24C02
**************************************************************/
#define EE_TYPE AT24C02
/**************************************************************
--EEPROM的操作函数
--24CXX驱动函数
**************************************************************/
u8 AT24CXX_ReadOneByte(u16 ReadAddr); //指定地址读取一个字节
void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite); //指定地址写入一个字节
void AT24CXX_WriteLenByte(u16 WriteAddr,u32 DataToWrite,u8 Len);//指定地址开始写入指定长度的数据
u32 AT24CXX_ReadLenByte(u16 ReadAddr,u8 Len); //指定地址开始读取指定长度数据
void AT24CXX_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite); //从指定地址开始写入指定长度的数据
void AT24CXX_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead); //从指定地址开始读出指定长度的数据
u8 AT24CXX_Check(void); //检查器件
void AT24CXX_Init(void); //初始化IIC
#endif
-----------------------------------------------------------------------------------------------------------------------------------------
AT24c02.c
#include "at24cxx.h"
#include "delay.h"
/***************************************************************************
- 功能描述:STM32f103 EEPORM初始化函数
- 隶属模块:STM32 EEPROM操作
- 函数属性:外部,使用户使用
- 参数说明:无
- 返回说明:无
- 函数功能:实现I2C的初始化。
***************************************************************************/
void AT24CXX_Init(void)
{
IIC_Init();
}
/***************************************************************************
- 功能描述:STM32f103 任意读取EEPORM一个字节的函数
- 隶属模块:STM32 EEPROM操作
- 函数属性:外部,使用户使用
- 参数说明:ReadAddr为所读取EEPROM字节的地址
- 返回说明:无
- 函数功能:返回所要读取的地址的数据
- 函数说明:要任意读取EEPROM地址中的一个字节的步骤为:
(1)发送开始START信号
(2)发送器件器件地址,最后一位为0
(3)从机检测到主机发送的地址与自己的地址相同时发送一个应答信号ACK,而主机等待ACK
(4)发送待操作的字节地址
(5)等待一个ACK
(6)重新发送START起始信号
(7)发送7位器件地址,最后一位为1,表示读EEPROM。
(8)等待ACK,读取一个字节。
(9)I2C停止,返回读取的数据。
这里注意AT24C0x系列的地址有两字节和一字节之分,这里把两种情况都包含了
***************************************************************************/
u8 AT24CXX_ReadOneByte(u16 ReadAddr)
{
u8 temp=0;
IIC_Start();
if(EE_TYPE>AT24C16)
{
IIC_Send_Byte(0XA0); //发送写命令
IIC_Wait_Ack();
IIC_Send_Byte(ReadAddr>>8);//发送高地址
IIC_Wait_Ack();
}
else
IIC_Send_Byte(0XA0+((ReadAddr/256)<<1)); //发送器件地址0XA0,写数据
IIC_Wait_Ack();
IIC_Send_Byte(ReadAddr%256); //发送低地址
IIC_Wait_Ack();
IIC_Start();
IIC_Send_Byte(0XA1); //进入接收模式
IIC_Wait_Ack();
temp=IIC_Read_Byte(0);
IIC_Stop();//产生一个停止条件
return temp;
}
/***************************************************************************
- 功能描述:STM32f103 任意写EEPORM一个字节的函数
- 隶属模块:STM32 EEPROM操作
- 函数属性:外部,使用户使用
- 参数说明:WriteAddr :写入数据的目的地址 ,DataToWrite:要写入的数据
- 返回说明:无
- 函数功能:返回所要读取的地址的数据
- 函数说明:要任意读取EEPROM地址中的一个字节的步骤为:
(1)发送开始START信号
(2)发送器件器件地址,最后一位为0
(3)从机检测到主机发送的地址与自己的地址相同时发送一个应答信号ACK
(4)发送待操作的字节地址
(5)等待一个ACK
(6)发送字节数据
(7)等待一个ACK
(8)I2C停止,返回读取的数据。
***************************************************************************/
void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite)
{
IIC_Start();
if(EE_TYPE>AT24C16)
{
IIC_Send_Byte(0XA0); //发送写命令
IIC_Wait_Ack();
IIC_Send_Byte(WriteAddr>>8);//发送高地址
IIC_Wait_Ack();
}
else
{
IIC_Send_Byte(0XA0+((WriteAddr/256)<<1)); //发送器件地址0XA0,写数据
}
IIC_Wait_Ack();
IIC_Send_Byte(WriteAddr%256); //发送低地址
IIC_Wait_Ack();
IIC_Send_Byte(DataToWrite); //发送字节
IIC_Wait_Ack();
IIC_Stop();//产生一个停止条件
delay_ms(10);
}
/***************************************************************************
- 功能描述:STM32f103 任意写EEPORM指定地址开始写入长度为Len的数据
- 隶属模块:STM32 EEPROM操作
- 函数属性:外部,使用户使用
- 参数说明:WriteAddr :写入数据的目的地址 ,DataToWrite:数据数组首地址
Len:要写入数据的长度2,4
- 返回说明:无
- 函数功能:无
- 函数说明:就是调用len次 AT24CXX_WriteOneByte函数,该函数用于写入16bit或者32bit的数据.
***************************************************************************/
void AT24CXX_WriteLenByte(u16 WriteAddr,u32 DataToWrite,u8 Len)
{
u8 t;
for(t=0;t<len;t++)
{
AT24CXX_WriteOneByte(WriteAddr+t,(DataToWrite>>(8*t))&0xff);
}
}
/***************************************************************************
- 功能描述:STM32f103 任意写EEPORM指定地址开始读出长度为Len的数据
- 隶属模块:STM32 EEPROM操作
- 函数属性:外部,使用户使用
- 参数说明:ReadAddr :开始读出的地址
Len:要写入数据的长度2,4
- 返回说明:无
- 函数功能:无
- 函数说明:就是调用len次AT24CXX_ReadOneByte函数,该函数用于读出16bit或者32bit的数据.
***************************************************************************/
u32 AT24CXX_ReadLenByte(u16 ReadAddr,u8 Len)
{
u8 t;
u32 temp=0;
for(t=0;t<len;t++)
{
temp<<=8;
temp+=AT24CXX_ReadOneByte(ReadAddr+Len-t-1);
}
return temp;
}
/***************************************************************************
- 功能描述:STM32f103检查AT24CXX是否正常
- 隶属模块:STM32 EEPROM操作
- 函数属性:外部,使用户使用
- 参数说明:无
- 返回说明:返回1:检测失败 返回0:检测成功
- 函数功能:无
- 函数说明:这里用了24XX的最后一个地址(255)来存储标志字. 返回0表示正常、返回1错误
***************************************************************************/
u8 AT24CXX_Check(void)
{
u8 temp;
temp=AT24CXX_ReadOneByte(255);//避免每次开机都写AT24CXX
if(temp==0X55)
return 0;
else//排除第一次初始化的情况
{
AT24CXX_WriteOneByte(255,0X55);
temp=AT24CXX_ReadOneByte(255);
if(temp==0X55)
return 0;
}
return 1;
}
/***************************************************************************
- 功能描述:STM32f103在AT24CXX里面的指定地址开始读出指定个数的数据
- 隶属模块:STM32 EEPROM操作
- 函数属性:外部,使用户使用
- 参数说明:ReadAddr :开始读出的地址 对24c02为0~255
pBuffer :数据数组首地址
NumToRead:要读出数据的个数
- 返回说明:无
- 函数功能:无
***************************************************************************/
void AT24CXX_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead)
{
while(NumToRead)
{
*pBuffer++=AT24CXX_ReadOneByte(ReadAddr++);
NumToRead--;
}
}
/***************************************************************************
- 功能描述:STM32f103在AT24CXX里面的指定地址开始写入指定个数的数据
- 隶属模块:STM32 EEPROM操作
- 函数属性:外部,使用户使用
- 参数说明:ReadAddr :开始读出的地址 对24c02为0~255
pBuffer :数据数组首地址,所读到的数据存储在了pBuffer中
NumToRead:要读出数据的个数
- 返回说明:无
- 函数功能:无
***************************************************************************/
void AT24CXX_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite)
{
while(NumToWrite--)
{
AT24CXX_WriteOneByte(WriteAddr,*pBuffer);
WriteAddr++;
pBuffer++;
}
}
有了STM32 I2C的配置,以及AT24C02的驱动函数,我们就可以对AT24C02EEPROM 进行读写操作了,如果是其他的I2C器件,则只需写出其驱动就OK了。
为什么用STM32模拟呢,因为STM32的硬件I2C确实比较复杂。