STM32F10x_硬件I2C读写EEPROM(标准外设库版本)

发布者:SparklingEyes最新更新时间:2021-01-14 来源: eefocus关键字:STM32F10x  硬件I2C  读写EEPROM  标准外设库版本 手机看文章 扫描二维码
随时随地手机看文章

Ⅰ、写在前面

上一篇文章是“STM32F10x_模拟I2C读写EEPROM”,讲述使用IO口模拟I2C总线通信,对http://yunpan.cn/c6b8d4mCTPpCj  访问密码

 

STM32F107VC_硬件I2C读写EEPROM(标准外设库版本)实例源代码工程:

http://yunpan.cn/c6b8HGnAGG4Mf  访问密码

 

I2C  EEPROM(AT24xx)资料:

https://yunpan.cn/c667rIDPgvwTf  访问密码 1099

 

STM32F1资料:

https://yunpan.cn/crBUdUGdYKam2  访问密码 ca90

 

Ⅲ、硬件I2C配置

硬件I2C的配置其实很简单,RCC时钟、GPIO、I2C配置等。笔者以F1标准外设库(同时也建议初学者使用官方的标准外设库)为基础建立的工程,主要以库的方式来讲述(若您的F1芯片与提供工程不一样,可微信回复“修改型号”)。


1.RCC时钟源

该函数位于bsp.c文件下面;

RCC是很多初学者,甚至已经工作的朋友容易遗漏的地方,有很多朋友觉得它使用的外设不正常,很大部分是没有配置RCC导致的。

 

重点注意:

A.外设RCC时钟的配置要在其外设初始化的前面;

 

B.匹配对应时钟。

比如:RCC_APB2外设不要配置在RCC_APB1时钟里面

【如:RCC_APB1PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);这样能编译通过,但这是错误的代码】

 

2. I2C引脚配置

 

该函数位于i2c_ee.c文件下面;

1.使用硬件I2C:GPIO_Mode_AF_OD复用开漏模式

2.由于使用硬件I2C,不像使用模拟I2C使用IO操作,所以这里引脚定义的比较“死”GPIO_Pin_6 | GPIO_Pin_7。


如果你使用I2C2或者引脚映射,这里的引脚也要跟着改变。

 

3. I2C配置

该函数位于i2c_ee.c文件下面;

 

这个函数才是本文的重点:

1.I2C模式:I2C_Mode = I2C_Mode_I2C;

硬件有多种模式:

I2C_Mode_I2C: I2C模式

I2C_Mode_SMBusDevice: SMBus设备(丛机)模式

I2C_Mode_SMBusHost: 主机模式

 

2.I2C占空比:I2C_DutyCycle = I2C_DutyCycle_2;

这个参数在快速I2C模式下有效,也就是速度大于100KHz。

I2C_DutyCycle_2:2比1占空比

I2C_DutyCycle_16_9:16比9占空比

感兴趣的朋友可以把时钟配置高于100KHz(如:400KHz),用示波器测一下SCL引脚,可以看得出来占空比不一样。

 

3.I2C设备地址:I2C_OwnAddress1 = EEPROM_DEV_ADDR;

这个参数是第一个设备(从机)的地址,EEPROM_DEV_ADDR是我们自己宏定义的设备地址。

 

4.I2C应答:I2C_Ack = I2C_Ack_Enable;

这个参数的含义请结合上一篇文章“I2C协议”来理解。

 

5.地址位数:I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;

这个参数就是设备地址位数,需要和后面函数“I2C_Send7bitAddress”一致。

 

6.I2C速度:I2C_ClockSpeed = I2C_SPEED;

这个参数很好理解,I2C_SPEED是我们宏定义的值“100000”,也就是100KHz的意思。

 

Ⅳ、硬件I2C读写EEPROM配置

上一篇文章简单提及了一下EEPROM单字节的读写,提供了多字节读写实例,但没有具体描述多字节的具体操作。

下面将详细描述一下单字节读写和多字节读写的操作。请下载“I2C EEPROM资料”和“实例工程”作为参考。

 

在对EEPROM(AT24Cxx)读写操作之前需要理解两个参数(可见源代码i2c_ee.h文件):

A.“数据字”地址长度:也就是存数据的地址有多少位。具体分类(见数据手册)如下:

 8位: AT24C01、AT24C02

16位: AT24C04、AT24C08、AT24C16、AT24C32、AT24C64、AT24C128、AT24C256、AT24C512

 

B.页长度:在进行连续写的时候,最长可写一页,写完这一页之后需要指定下一页地址才行,否则会在上一页循环写。具体分类(见数据手册)如下:

  8字节: AT24C01、AT24C02

 16字节: AT24C04、AT24C08、AT24C16

 32字节: AT24C32、AT24C64

 64字节: AT24C128、AT24C256

128字节: AT24C512

 

1. 单字节写

时序图:

截图来自“AT24C128C数据手册”,单字节写主要分5个步骤:

1.开始

2.设备地址/写

3.数据地址

4.写一字节数据

5.停止

 

源程序:

在操作硬件I2之前需要检测I2C是否处于“忙”状态。数据地址根据长度不同而写入的不同。

 

 

2. 单字节读(随机)

时序图:

截图来自“AT24C128C数据手册”,单字节读(也是随机读)主要分7个步骤:

1.开始

2.设备地址/写

3.数据地址

4.重新开始

5.设备地址/读

6.读一字节数据

7.停止

 

源程序:

这里就提醒一点,单字节读和多字节读的应答位,由于不连续读,这里产生非应答。

 

3. 页写

时序图:

截图来自“AT24C128C数据手册”,页写和单字节写的区别在于“连续写”。

注意:这里页写的意思是在指向地址的页写数据,也就是EEPROM内部“地址指针”指向的地址所在页。每次写之前我们都要将“地址指针”指向一个地址(见下面源程序),写的过程中,一旦写到最后一个字节,将会回到该页首地址继续写下去,因此,写完该页,我们需要重新将“地址指针”指向下一页首地址。

【芯片页的大小根据芯片不同而不同,见本章开头描述】

 

源程序:

写最后一字节独立出来是有原因的:防止HardFault_Handler。

 

 

4. 多字节写

源程序:

“多字节写”是基于“页写”的基础上写的,从上面页写的描述(写到该页最后一字节会回到该页首地址)可以知道多字节写是要考虑很多情况的,否则会破坏其他数据。

上面源程序截取了简单的一部分:开始写的地址刚好位于该页首地址这种情况。在页首地址开始写数据情况下,要判断需要写的数据的大小是否有多页。

 

【上面这种情况是比较简单的一种,还有其他情况,我不在这里讲述,希望初学的你多去理解一下,这也是参考ST官方的思路,而且有利于你们编程的思想】

 

5. 多字节读

时序图:

截图来自“AT24C128C数据手册”,多字节读需要注意应答。

 

在多字节读到最后一位数据之前,必须产生应答位,而最后一位产生非应答位。请结合下面源程序理解。

 

源程序:

和单字节读比:前面第1步到第5步都是一样的,重点请看第6步,这里产生的应答需要注意。

 

Ⅴ、ST官方I2C读写问题

说到ST的I2C这个问题,网上有很多人说也存在严重的I2C问题,我个人倒不觉得存在太大问题(或许是我研究的还不够)。

我从开始至今,使用ST芯片I2C也做过几个项目(控制EEPROM、时钟芯片、温度传感器、触摸芯片),项目中也使用多个中断,我至今还没有发现它的问题。我只知道ST提供的标准外设库例程有些地方不严谨或不规范,我也从没使用ST官方的例程(当然,我自己写的例程很多思路是参考ST的)。

 

我个人观点:有问题比不可怕,可怕的是不知道如何去解决问题。由于我没有真正的发现I2C硬件真实存在的问题,可以参考一下官方提到是资料,可以下载(第二节)我整理的STM32F1资料 “STM32F10xxCDE勘误手册V14(英文)2015-11”查看。

 

1.官方标准外设库例程介绍

标准库例程关于I2C读写EEPROM0的例程很多都一样或类似(F1、F2、F4等),感兴趣的可以下载查看。但是,都存在不规范的地方。

 

2.标准库I2C例程介绍

我大概说一下这个标准库I2C例程中读写相关函数吧。

位置位于STM32F10x_StdPeriph_Lib_V3.5.0UtilitiesSTM32_EVALCommon:

stm32_eval_i2c_ee.c

 

A.sEE_ReadBuffer读函数

A1.同样注释,不同语句,写地址之后的标志处理;(见265行处)

这个地方其实是处理一下标志位,我也测试过,使用两种语句都可以通过的。只是提出来以下是,我个人举得更应该使用“I2C_EVENT_MASTER_BYTE_TRANSMITTED”(在我的例程中也是使用这个)。

 

A2.读数据之前,发送停止条件;(见316行处)

这个地方经过我反复测试,没有测试通过(也就是在读之前发送停止条件)。 我个人觉得这是程序上的一个BUG.

 

B.sEE_WriteBuffer写函数

写页函数暂时还没有发现什么问题,但在综合的写函数(多字节写)中发现了一个问题(如下图),这个地方的count永远都不可能等于0,而这里加了一个判断条件。

 

Ⅵ、说明

EEPROM的读写操作按照I2C标准协议通信,请参看数据手册,有助于提高对I2C的理解。

以上总结仅供参考,若有不对之处,敬请谅解。


关键字:STM32F10x  硬件I2C  读写EEPROM  标准外设库版本 引用地址:STM32F10x_硬件I2C读写EEPROM(标准外设库版本)

上一篇:STM32F10x_模拟I2C读写EEPROM
下一篇:STM32F1_外部SRAM作为运行内存

推荐阅读最新更新时间:2024-11-04 10:02

STM32的硬件I2C实现及问题
虽然软件可实现I2C读取三轴传感器数据,但I2C作为一种重要的通信协议是一定要搞清楚问题所在的,SO继续研究之前的问题。(网上传言STM32硬件I2C有问题,但仍然有人实现出来) 再次启动程序,依旧是停在原来的位置 等待EV6,网上搜索相关问题好多人都停在了等待EV5上。分析EV5等待问题,主机发送起始信号,没能接受从设备发送的应答, 或者可能都没有发送。此问题应该是接线或IIC初始化代码的问题。 而我此时停在等待EV6,说明已检测到该设备。换句话说从设备已经知道了主设备的存在。却在主设备发送设备地址之后,接受不到从设备的应答信号,自己分析有两种可能,一是设备地址错误,从设备接受到不是自身的设备而地址自然不会应答。
[单片机]
STM32的<font color='red'>硬件</font><font color='red'>I2C</font>实现及问题
STM32的I2C通讯配置(硬件实现)——学习笔记(6-2)
文章内容根据野火学习教程进行整理,仅仅是学习记录。 开发板: 野火STM32F429-挑战者V2 官方固件库版本: STM32F4xx_DSP_StdPeriph_Lib_V1.8.0 这里以与EEPROM进行通讯的代码作为例子。 一、看电路图 1、要得知那些信息 从电路图上主要是要知道3点关键信息 I2C设备挂载在I2C1、I2C2、I2C3的哪一个总线上 SDA、SCL接的是哪两个GPIO I2C设备地址(有的是可以选择的,比如这个EEPROM) 2、挂在哪个I2C总线以及哪个GPIO 从电路图上可以看出: 挂载在I2C1上的 SDA接的是PB7引脚 SCL接的是PB6引脚 这个一般硬件工程师都会在电路
[单片机]
STM32的<font color='red'>I2C</font>通讯配置(<font color='red'>硬件</font>实现)——学习笔记(6-2)
STM32CubeMX学习教程之十:硬件I2C读写AT24C02
网上有流传已久一种说法,就是STM的I2C有bug,不好用。确实很多人在实际应用中都遇到了各种问题,所以绝大部分人都是在用软件模拟IIC。 有了STM32CubeMX,我们可以尝试使用硬件I2C了,官方的优化总不会有错了吧?(其实还是有个小bug,不过可以改过来的)。本文的目标就是使用STM32CubeMX的硬件I2C对麒麟座板载的AT24C02 EEPROM进行完整的读写操作。 软件版本: STM32CubeMX V4.25.0 System Workbench V2.4 固件库版本: STM32Cube FW_F1 V1.6.1 固件库版本: STM32Cube FW_F1 V1.6.1 硬件
[单片机]
STM32CubeMX学习教程之十:<font color='red'>硬件</font><font color='red'>I2C</font><font color='red'>读写</font>AT24C02
浅谈STM32F10X芯片SysTick系统时钟定时器
1、介绍 实现Cortex-M3系统定时器SysTick的配置,需要具备以下知识:Cortex-M3系统定时器默认频率是HCLK的8分频(如下图所示),因此需要会RCC时钟的配置;然后配置SysTick系统定时器;编写SysTick中断处理函数。 系统时钟及系统定时器时钟(详见手册) 2、寄存器描述 SysTick控制及状态寄存器STK_CTRL SysTick重装载数值寄存器STK_LOAD SysTick当前数值寄存器STK_VAL SysTick校准数值寄存器STK_CALIB 与SysTick相关的固件库函数有以下几个: 配置SysTick系统时钟:SysTick_CLKSourceConf
[单片机]
PIC单片机读内部EEPROM读写操作子程序
//***************************************************************************** //***************************************************************************** // pic16f917 //***************************************************************************** unsigned char read_eeprom(unsigned char); void write_eeprom(uns
[单片机]
STM32F10x 学习笔记3(CRC计算单元)
STM32F 系列的单片机内部带了CRC32 计算单元。这个内置CRC模块的方法使用非常简单。其操作如下图所示。 图 1 CRC计算单元框图 归纳起来有如下几步操作: 1. 开启CRC单元的时钟。RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE) 2. 复位CRC模块(设置CRC_CR=0x01),这个操作把CRC余数初始化为0xFFFFFFFF 3. 把要计算的数据按逐个地写入CRC_DR寄存器 4. 写完所有的数据字后,从CRC_DR寄存器读出计算的结果 STM32F10x StdPeriph Driver 中提供了几个函数。 CRC_ResetDR(void)
[单片机]
<font color='red'>STM32F10x</font> 学习笔记3(CRC计算单元)
单片机EEPROM读写数据流程解析
EEPROM 写数据流程 第一步,首先是 I2C 的起始信号,接着跟上首字节,也就是我们前边讲的 I2C 的器件地址,并且在读写方向上选择“写”操作。 第二步,发送数据的存储地址。24C02 一共 256 个字节的存储空间,地址从 0x00~0xFF,我们想把数据存储在哪个位置,此刻写的就是哪个地址。 第三步,发送要存储的数据第一个字节、第二个字节??注意在写数据的过程中,EEPROM 每个字节都会回应一个“应答位 0”,来告诉我们写 EEPROM 数据成功,如果没有回应答位,说明写入不成功。 在写数据的过程中,每成功写入一个字节,EEPROM 存储空间的地址就会自动加 1,当加到 0xFF 后,再写一个字节,地址会溢
[单片机]
单片机<font color='red'>EEPROM</font><font color='red'>读写</font>数据流程解析
STM学习笔记--STM32F10X中断
CM3支持256个中断,16个内核中断+240个外部中断,并具有256级可编程中断 STM32支持76个中断,16个内核中断+60个外部中断,16个可编程优先级 16个内核中断:每个中断占用地址为0X0000_0004 60个可屏蔽中断:其中0,1,2,3,4表示中断编号IRQ Channels在STM32F10x_lib.h程序中体现 16个中断优先级 先看看嵌套中断向量控制器的定义STM32F10X_map.h /*------------------------ Nested Vectored Interrupt Controller --------------*/
[单片机]
STM学习笔记--<font color='red'>STM32F10X</font>中断
小广播
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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