秉火429笔记之十六 I2C--操作EEPROM

发布者:xinyi9008最新更新时间:2019-09-12 来源: eefocus关键字:秉火  I2C  操作EEPROM 手机看文章 扫描二维码
随时随地手机看文章

1. I2C 概述

参考该链接,不在赘述:https://blog.csdn.net/XieWinter/article/details/91903678


介于ST I2C接口相对不好用,在此直接采用模拟I2C方式操作设备


2. 硬件设计

特征:兼容400KHZ,百万次写入,详见数据手册


EEPROM的7位设备地址是:,A0/A1/A2均为0, 0x50


EEPROM芯片中还有一个WP引脚,具有写保护功能,当该引脚电平为高时,禁止写入数据,当引脚为低电平时,可写入数据,直接接地,则禁用写保护功能。


EEPROM操作图

字节写

 页写

当前地址读

随机读

顺序读

3. 代码实现

模拟I2C源码链接:https://download.csdn.net/download/xiewinter/11258552


/******************************************************************************

                  Copyright(c) 2018-2020 Xanthium All rights reserved.

 ******************************************************************************

  文 件 名   : bsp_i2c_gpio.h

  版 本 号   : 初稿

  作    者   : Xanthium

  生成日期   : 2019年6月25日

  最近修改   :

  功能描述   : I2C模拟总线驱动模块H文件

  函数列表   :

  修改历史   :

  1.日    期   : 2019年6月25日

    作    者   : Xanthium

    修改内容   : 创建文件

******************************************************************************/

 

#ifndef __BSP_I2C_GPIO_H__

#define __BSP_I2C_GPIO_H__

 

#ifdef __cplusplus

extern "C" {

#endif

 

#include "stm32f4xx.h"

 

#define I2C_WR 0 /* 写控制bit */

#define I2C_RD 1 /* 读控制bit */

 

void bsp_InitI2C(void);

void i2c_Start(void);

void i2c_Stop(void);

void i2c_SendByte(uint8_t _ucByte);

uint8_t i2c_ReadByte(void);

uint8_t i2c_WaitAck(void);

void i2c_Ack(void);

void i2c_NAck(void);

uint8_t i2c_CheckDevice(uint8_t _Address);

 

#ifdef __cplusplus

}

#endif

 

 

#endif // end of __BSP_I2C_GPIO_H__

/* --------------  部分代码---------完整代码见个人资源库*/

/*

i2c总线GPIO:

  PB6/I2C1_SCL

  PB7/I2C1_SDA

*/

 

/* 定义I2C总线连接的GPIO端口, 用户只需要修改下面4行代码即可任意改变SCL和SDA的引脚 */

 

#define RCC_I2C_PORT RCC_AHB1Periph_GPIOB /* GPIO端口时钟 */

 

#define PORT_I2C_SCL GPIOB /* GPIO端口 */

#define PIN_I2C_SCL GPIO_Pin_6 /* GPIO引脚 */

 

#define PORT_I2C_SDA GPIOB /* GPIO端口 */

#define PIN_I2C_SDA GPIO_Pin_7 /* GPIO引脚 */

 

#define I2C_SCL_PIN GPIO_Pin_6 /* 连接到SCL时钟线的GPIO */

#define I2C_SDA_PIN GPIO_Pin_7 /* 连接到SDA数据线的GPIO */

 

/* 定义读写SCL和SDA的宏 */

#define I2C_SCL_1()  GPIO_SetBits(PORT_I2C_SCL,I2C_SCL_PIN) /* SCL = 1 */

#define I2C_SCL_0()  GPIO_ResetBits(PORT_I2C_SCL,I2C_SCL_PIN) /* SCL = 0 */

 

#define I2C_SDA_1()  GPIO_SetBits(PORT_I2C_SDA,I2C_SDA_PIN) /* SDA = 1 */

#define I2C_SDA_0()  GPIO_ResetBits(PORT_I2C_SDA,I2C_SDA_PIN) /* SDA = 0 */

 

#define I2C_SDA_READ()  (GPIO_ReadInputDataBit(PORT_I2C_SDA,I2C_SDA_PIN)) /* 读SDA口线状态 */

#define I2C_SCL_READ()  (GPIO_ReadInputDataBit(PORT_I2C_SCL,I2C_SCL_PIN)) /* 读SCL口线状态 */

 

/*

*********************************************************************************************************

* 函 数 名: bsp_InitI2C

* 功能说明: 配置I2C总线的GPIO,采用模拟IO的方式实现

* 形    参:  无

* 返 回 值: 无

*********************************************************************************************************

*/

void bsp_InitI2C(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

 

RCC_AHB1PeriphClockCmd(RCC_I2C_PORT, ENABLE); /* 打开GPIO时钟 */

 

 

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; /* 开漏输出模式 */

 

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;

    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;

GPIO_InitStructure.GPIO_Pin = PIN_I2C_SCL;

GPIO_Init(PORT_I2C_SCL, &GPIO_InitStructure);

 

GPIO_InitStructure.GPIO_Pin = PIN_I2C_SDA;

GPIO_Init(PORT_I2C_SDA, &GPIO_InitStructure);

 

/* 给一个停止信号, 复位I2C总线上的所有设备到待机模式 */

i2c_Stop();

}

 

/*

*********************************************************************************************************

* 函 数 名: i2c_Start

* 功能说明: CPU发起I2C总线启动信号

* 形    参:  无

* 返 回 值: 无

*********************************************************************************************************

*/

void i2c_Start(void)

{

/* 当SCL高电平时,SDA出现一个下跳沿表示I2C总线启动信号 */

I2C_SDA_1();

I2C_SCL_1();

i2c_Delay();

I2C_SDA_0();

i2c_Delay();

I2C_SCL_0();

i2c_Delay();

}

 

/*

*********************************************************************************************************

* 函 数 名: i2c_Start

* 功能说明: CPU发起I2C总线停止信号

* 形    参:  无

* 返 回 值: 无

*********************************************************************************************************

*/

void i2c_Stop(void)

{

/* 当SCL高电平时,SDA出现一个上跳沿表示I2C总线停止信号 */

I2C_SDA_0();

I2C_SCL_1();

i2c_Delay();

I2C_SDA_1();

i2c_Delay();

}

 

// ....

/******************************************************************************

                  Copyright(c) 2018-2020 Xanthium All rights reserved.

 ******************************************************************************

  文 件 名   : bsp_eeprom_24xx.h

  版 本 号   : 初稿

  作    者   : Xanthium

  生成日期   : 2019年6月25日

  最近修改   :

  功能描述   : 串行EEPROM 24xx02驱动模块H文件

  函数列表   :

  修改历史   :

  1.日    期   : 2019年6月25日

    作    者   : Xanthium

    修改内容   : 创建文件

******************************************************************************/

 

#ifndef __BSP_EEPROM_24XX_H__

#define __BSP_EEPROM_24XX_H__

 

#ifdef __cplusplus

extern "C" {

#endif

 

#include

 

 

#define AT24C02

//#define AT24C128

 

#ifdef AT24C02

#define EE_MODEL_NAME "AT24C02"

#define EE_DEV_ADDR 0xA0 /* 设备地址 */

#define EE_PAGE_SIZE 8 /* 页面大小(字节) */

#define EE_SIZE 256 /* 总容量(字节) */

#define EE_ADDR_BYTES 1 /* 地址字节个数 */

#endif

 

#ifdef AT24C128

#define EE_MODEL_NAME "AT24C128"

#define EE_DEV_ADDR 0xA0 /* 设备地址 */

#define EE_PAGE_SIZE 64 /* 页面大小(字节) */

#define EE_SIZE (16*1024) /* 总容量(字节) */

#define EE_ADDR_BYTES 2 /* 地址字节个数 */

#endif

 

uint8_t bsp_ee_CheckOk(void);

uint8_t bsp_ee_ReadBytes(uint8_t *_pReadBuf, uint16_t _usAddress, uint16_t _usSize);

uint8_t bsp_ee_WriteBytes(uint8_t *_pWriteBuf, uint16_t _usAddress, uint16_t _usSize);

 

#ifdef __cplusplus

}

#endif

 

#endif // end of __BSP_EEPROM_24XX_H_

关键字:秉火  I2C  操作EEPROM 引用地址:秉火429笔记之十六 I2C--操作EEPROM

上一篇:秉火429笔记之十八 ETH--以太网
下一篇:秉火429笔记之五控制RGB彩灯

推荐阅读最新更新时间:2024-11-09 20:08

1.10.4_I2C_I2C控制器编程_框架_P
下图是I2C Transmitter模式下的流程图。 下图是I2C Receiver模式下的流程图。
[单片机]
1.10.4_I2C_I2C控制器编程_框架_P
STM32CubeMX学习教程之十一:硬件I2C读取SHT20温湿度
上一篇教程我们使用I2C进行了EEPROM的读写操作,实际上I2C上面挂的所有器件我们都可以操作。 本文的目标就是使用STM32CubeMX的硬件I2C读取麒麟座连接在I2C2上的SHT20芯片温湿度信息。 软件版本: STM32CubeMX V4.25.0 System Workbench V2.4 固件库版本: STM32Cube FW_F1 V1.6.1 硬件:OneNet 麒麟座V2.3 在STM32CubeMX中新建项目,选择正确的MCU型号(或者旧项目另存一下也可以)。 首先设置RCC和SYS,如下图 然后根据板子实际情况设置时钟(麒麟座外部晶振是12M,ST
[单片机]
STM32CubeMX学习教程之十一:硬件<font color='red'>I2C</font>读取SHT20温湿度
STM32F10x_硬件I2C读写EEPROM(标准外设库版本)
Ⅰ、写在前面 上一篇文章是“STM32F10x_模拟I2C读写EEPROM”,讲述使用IO口模拟I2C总线通信,对 EEPROM(AT24Xxx) 进行读写操作的过程。 上一篇文章主要内容:I2C协议、模拟I2C底层驱动、EEPROM(AT24Xxx)单字节读写操作。 本文主要内容: STM32硬件I2C详细配置、EEPROM(AT24Xxx)多字节读写操作、ST官方I2C存在问题。 实例实验效果: 1、多字节读写:任意地址(66), 写入任意长度(129)、读取并打印出来 2、单字节读写:任意地址(0),写入1字节数据、 读取并打印出来 实验说明: 1.多字节读写 实验为什么是从66地址写? 为什么是写入12
[单片机]
STM32F10x_硬件<font color='red'>I2C</font>读写<font color='red'>EEPROM</font>(标准外设库版本)
STM32 HAL I2C库读指定寄存器的数据
Support for repeated start in STM32 HAL I2C library Q: I am working with a slave I2C device (Kionix KX022 acccelerometer) which uses a repeated start mechanism to send data requested by the master (STM32F405), e.g. to read two bytes of data (from register N and register N+1) the following sequence Master Slav
[单片机]
STM32 HAL <font color='red'>I2C</font>库读指定寄存器的数据
STM32F10x_硬件I2C读写EEPROM(标准外设库版本)
Ⅰ、写在前面 上一篇文章是“STM32F10x_模拟I2C读写EEPROM”,讲述使用IO口模拟I2C总线通信,对EEPROM(AT24Xxx)进行读写操作的过程。 上一篇文章主要内容:I2C协议、模拟I2C底层驱动、EEPROM(AT24Xxx)单字节读写操作。 本文主要内容:STM32硬件I2C详细配置、EEPROM(AT24Xxx)多字节读写操作、ST官方I2C存在问题。 实例实验效果: 1、多字节读写:任意地址(66), 写入任意长度(129)、读取并打印出来 2、单字节读写:任意地址(0),写入1字节数据、 读取并打印出来 实验说明: 1.多字节读写 实验为什么是从66地址写? 为什么是写入129字节? 答案:验
[单片机]
STM32F10x_硬件<font color='red'>I2C</font>读写<font color='red'>EEPROM</font>(标准外设库版本)
27.3.4.2内核下的I2C驱动(二)
用户态直接访问,使用内核提供的驱动程序 dev-interface 注意,不要直接使用read(),write()操作函数,直接使用i2c_smbus_write_word_data,i2c_smbus_read_word_data。官方文档给了说明,如下 驱动程序编译进内核才有效,I2c-dev.c依赖于那些配置项,查看makefile makemenuconfig,搜索CONFIG_I2C_CHARDEV 重启内核,编译新内核,之后下载到开发板 测试代码 #include stdio.h #include stdlib.h #include string.h #include sys/types.h
[单片机]
27.3.4.2内核下的<font color='red'>I2C</font>驱动(二)
PIC内部EEPROM读写操作
EPROM操作: 如果要读取一个字节, 用户首先必须向EEADRL寄存器写入地址,然后清除EEPGD控制位,以及EECON1的CFGS位, 然后再将RD位置高。需要的数据经过一次指令周期马上就出现在EEDATL里面了,下一个指令 就可以读取出来,当然为了稳定可以加noop。EEDATL寄存器将会保留该读取的值,直到下一次读取操作 或者是用户写入操作。 代码: EEADRL=DATA_EE_Address; nop(); EEPGD=0; CFGS=0; RD=1; nop(); nop(); result_byte=EEDATL; 如果要写入一个字节; 先设置地址EEADRL,并写入数据Byte的EEDATL,然后在遵循如下
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved