STM32之HAL开发——I2C读写EEPROM

I2C功能框图(F1系列)

在这里插入图片描述
STM32 的 I2C 外设可用作通讯的主机及从机,支持 100Kbit/s 和 400Kbit/s 的速率,支持 7 位、 10
位设备地址,支持 DMA 数据传输,并具有数据校验功能,I2C 外设还支持 SMBus2.0 协议。

I2C 初始化结构体详解

typedef struct {
uint32_t ClockSpeed; /*!< 设置 SCL 时钟频率,此值要低于 40 0000*/
uint32_t DutyCycle; /* 指定时钟占空比,可选 low/high = 2:1 及 16:9 模式 */
uint32_t OwnAddress1; /* 指定自身的 I2C 设备地址 1,可以是 7-bit 或者 10-,→bit*/
uint32_t AddressingMode; /* 指定地址的长度模式,可以是 7bit 模式或者 10bit 模式 */
uint32_t DualAddressMode; /* 设置双地址模式 */
uint32_t OwnAddress2; /* 指定自身的 I2C 设备地址 2,只能是 7-bit */
uint32_t GeneralCallMode; /* 指定广播呼叫模式 */
uint32_t NoStretchMode; /* 指定禁止时钟延长模式 */
} I2C_InitTypeDef;

(1) ClockSpeed
本成员设置的是 I2C 的传输速率,在调用初始化函数时,函数会根据我们输入的数值写入到 I2C的时钟控制寄存器 CCR。
(2) DutyCycle
本成员设置的是 I2C 的 SCL 线时钟的占空比。该配置有两个选择,分别为低电平时间比高电平时间为 2: 1 (I2C_DUTYCYCLE_2) 和 16: 9 (I2C_DUTYCYCLE_16_9)。其实这两个模式的比例差别并不大,一般要求都不会如此严格,这里随便选就可以了。
(3) OwnAddress1
本成员配置的是 STM32 的 I2C 设备自身地址 1,每个连接到 I2C 总线上的设备都要有一个自己的地址,作为主机也不例外。地址可设置为 7 位或 10 位 (受下面 (3) AddressingMode 成员决定),只要该地址是 I2C 总线上唯一的即可。STM32 的 I2C 外设可同时使用两个地址,即同时对两个地址作出响应,这个结构成员 OwnAddress1 配置的是默认的、 OAR1 寄存器存储的地址,若需要设置第二个地址寄存器 OAR2,可使用 DualAddressMode 成员使能,然后设置 OwnAddress2 成员即可, OAR2 不支持 10 位地址。
(4) AddressingMode
本成员选择 I2C 的寻址模式是 7 位还是 10 位地址。这需要根据实际连接到 I2C 总线上设备的地址进行选择,这个成员的配置也影响到 OwnAddress1 成员,只有这里设置成 10 位模式时, OwnAddress1 才支持 10 位地址。
(5) DualAddressMode
本成员配置的是 STM32 的 I2C 设备自己的地址,每个连接到 I2C 总线上的设备都要有一个自己的地址,作为主机也不例外。地址可设置为 7 位或 10 位 (受下面 I2C_dual_addressing_mode 成员决定),只要该地址是 I2C 总线上唯一的即可。
STM32 的 I2C 外设可同时使用两个地址,即同时对两个地址作出响应,这个结构成员I2C_OwnAddress1 配置的是默认的、 OAR1 寄存器存储的地址,若需要设置第二个地址寄存器OAR2,可使用 I2C_OwnAddress2Config 函数来配置, OAR2 不支持 10 位地址。
(6) OwnAddress2
本成员配置的是 STM32 的 I2C 设备自身地址 2,每个连接到 I2C 总线上的设备都要有一个自己的地址,作为主机也不例外。地址可设置为 7 位,只要该地址是 I2C 总线上唯一的即可。
(7) GeneralCallMode
本成员是关于 I2C 从模式时的广播呼叫模式设置。
(8) NoStretchMode
本成员是关于 I2C 禁止时钟延长模式设置,用于在从模式下禁止时钟延长。它在主模式下必须保持关闭。配置完这些结构体成员值,调用库函数 HAL_I2C_Init 即可把结构体的配置写入到寄存器中。

Tips:
什么是I2C时钟延展(SCLStretching)?在I2C的主从通信过程中,总线上的SCL时钟总是由主机来产生和控制的,但如果从机跟不上主机的速率,I2C协议规定从机是可以通过将SCL时钟线拉低来暂停一个传输的,直到从机释放掉SCL线,传输继续进行。

I2C读写EEPROM

I2C初始化代码

static void I2C_Mode_Config(void)
{I2C_Handle.Instance             = I2Cx;I2C_Handle.Init.AddressingMode  = I2C_ADDRESSINGMODE_7BIT;I2C_Handle.Init.ClockSpeed      = 400000;I2C_Handle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;I2C_Handle.Init.DutyCycle       = I2C_DUTYCYCLE_2;I2C_Handle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;I2C_Handle.Init.NoStretchMode   = I2C_NOSTRETCH_DISABLE;I2C_Handle.Init.OwnAddress1     = I2C_OWN_ADDRESS7 ;I2C_Handle.Init.OwnAddress2     = 0; /* Init the I2C */HAL_I2C_Init(&I2C_Handle);	
//  HAL_I2CEx_AnalogFilter_Config(&I2C_Handle, ENABLE);    开启过滤器过滤噪声
}
void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c)
{  GPIO_InitTypeDef  GPIO_InitStruct;/*##-1- Enable peripherals and GPIO Clocks #################################*//* Enable GPIO TX/RX clock */I2Cx_SCL_GPIO_CLK_ENABLE();I2Cx_SDA_GPIO_CLK_ENABLE();/* Enable I2C1 clock */I2Cx_CLK_ENABLE(); /*##-2- Configure peripheral GPIO ##########################################*/  /* I2C TX GPIO pin configuration  */GPIO_InitStruct.Pin       = I2Cx_SCL_PIN;GPIO_InitStruct.Mode      = GPIO_MODE_AF_OD;GPIO_InitStruct.Pull      = GPIO_NOPULL;GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(I2Cx_SCL_GPIO_PORT, &GPIO_InitStruct);/* I2C RX GPIO pin configuration  */GPIO_InitStruct.Pin = I2Cx_SDA_PIN;   HAL_GPIO_Init(I2Cx_SDA_GPIO_PORT, &GPIO_InitStruct);/* Force the I2C peripheral clock reset */  __HAL_RCC_I2C1_FORCE_RESET();/* Release the I2C peripheral clock reset */  __HAL_RCC_I2C1_RELEASE_RESET();
}

注意:在HAL库中,在HAL_I2C_Init(&I2C_Handle);这个函数内会自动调用HAL_I2C_MspInit,这也是HAL库提供给用户的配置I2C的GPIO函数。

I2C写EEPROM函数

/*该函数会自动判断是否超页,如超页自动换页*/
/*** @brief   将缓冲区中的数据写到I2C EEPROM中* @param   *		@arg pBuffer:缓冲区指针*		@arg WriteAddr:写地址*     @arg NumByteToWrite:写的字节数* @retval  无*/
void I2C_EE_BufferWrite(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite)
{uint8_t NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0;Addr = WriteAddr % EEPROM_PAGESIZE;count = EEPROM_PAGESIZE - Addr;NumOfPage =  NumByteToWrite / EEPROM_PAGESIZE;NumOfSingle = NumByteToWrite % EEPROM_PAGESIZE;/* If WriteAddr is I2C_PageSize aligned  */if(Addr == 0) {/* If NumByteToWrite < I2C_PageSize */if(NumOfPage == 0) {I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);}/* If NumByteToWrite > I2C_PageSize */else  {while(NumOfPage--){I2C_EE_PageWrite(pBuffer, WriteAddr, EEPROM_PAGESIZE); WriteAddr +=  EEPROM_PAGESIZE;pBuffer += EEPROM_PAGESIZE;}if(NumOfSingle!=0){I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);}}}/* If WriteAddr is not I2C_PageSize aligned  */else {/* If NumByteToWrite < I2C_PageSize */if(NumOfPage== 0) {I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle);}/* If NumByteToWrite > I2C_PageSize */else{NumByteToWrite -= count;NumOfPage =  NumByteToWrite / EEPROM_PAGESIZE;NumOfSingle = NumByteToWrite % EEPROM_PAGESIZE;	if(count != 0){  I2C_EE_PageWrite(pBuffer, WriteAddr, count);WriteAddr += count;pBuffer += count;} while(NumOfPage--){I2C_EE_PageWrite(pBuffer, WriteAddr, EEPROM_PAGESIZE);WriteAddr +=  EEPROM_PAGESIZE;pBuffer += EEPROM_PAGESIZE;  }if(NumOfSingle != 0){I2C_EE_PageWrite(pBuffer, WriteAddr, NumOfSingle); }}}  
}/*** @brief   写一个字节到I2C EEPROM中* @param   *		@arg pBuffer:缓冲区指针*		@arg WriteAddr:写地址 * @retval  无*/
uint32_t I2C_EE_ByteWrite(uint8_t* pBuffer, uint8_t WriteAddr)
{HAL_StatusTypeDef status = HAL_OK;status = HAL_I2C_Mem_Write(&I2C_Handle, EEPROM_ADDRESS, (uint16_t)WriteAddr, I2C_MEMADD_SIZE_8BIT, pBuffer, 1, 100); /* Check the communication status */if(status != HAL_OK){/* Execute user timeout callback *///I2Cx_Error(Addr);}while (HAL_I2C_GetState(&I2C_Handle) != HAL_I2C_STATE_READY){}/* Check if the EEPROM is ready for a new operation */while (HAL_I2C_IsDeviceReady(&I2C_Handle, EEPROM_ADDRESS, EEPROM_MAX_TRIALS, I2Cx_TIMEOUT_MAX) == HAL_TIMEOUT);/* Wait for the end of the transfer */while (HAL_I2C_GetState(&I2C_Handle) != HAL_I2C_STATE_READY){}return status;
}/*** @brief   在EEPROM的一个写循环中可以写多个字节,但一次写入的字节数*          不能超过EEPROM页的大小,AT24C02每页有8个字节* @param   *		@arg pBuffer:缓冲区指针*		@arg WriteAddr:写地址*     @arg NumByteToWrite:写的字节数* @retval  无*/
uint32_t I2C_EE_PageWrite(uint8_t* pBuffer, uint8_t WriteAddr, uint8_t NumByteToWrite)
{HAL_StatusTypeDef status = HAL_OK;/* Write EEPROM_PAGESIZE */status=HAL_I2C_Mem_Write(&I2C_Handle, EEPROM_ADDRESS,WriteAddr, I2C_MEMADD_SIZE_8BIT, (uint8_t*)(pBuffer),NumByteToWrite, 100);while (HAL_I2C_GetState(&I2C_Handle) != HAL_I2C_STATE_READY){}/* Check if the EEPROM is ready for a new operation */while (HAL_I2C_IsDeviceReady(&I2C_Handle, EEPROM_ADDRESS, EEPROM_MAX_TRIALS, I2Cx_TIMEOUT_MAX) == HAL_TIMEOUT);/* Wait for the end of the transfer */while (HAL_I2C_GetState(&I2C_Handle) != HAL_I2C_STATE_READY){}return status;
}/*** @brief   从EEPROM里面读取一块数据 * @param   *		@arg pBuffer:存放从EEPROM读取的数据的缓冲区指针*		@arg WriteAddr:接收数据的EEPROM的地址*     @arg NumByteToWrite:要从EEPROM读取的字节数* @retval  无*/
uint32_t I2C_EE_BufferRead(uint8_t* pBuffer, uint8_t ReadAddr, uint16_t NumByteToRead)
{HAL_StatusTypeDef status = HAL_OK;status=HAL_I2C_Mem_Read(&I2C_Handle,EEPROM_ADDRESS,ReadAddr, I2C_MEMADD_SIZE_8BIT, (uint8_t *)pBuffer, NumByteToRead,1000);return status;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/779879.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

3D产品可视化SaaS

“我们正在走向衰退吗&#xff1f;” “我们已经陷入衰退了吗&#xff1f;” “我们正在步入衰退。” 过去几个月占据头条的问题和陈述引发了关于市场对每个行业影响的讨论和激烈辩论。 特别是对于科技行业来说&#xff0c;过去几周一直很动荡&#xff0c;围绕费用、增长和裁…

Webpack生成企业站静态页面 - ajax请求

一些项目因需求不同&#xff0c;如需SEO或小项目&#xff0c;使用angular、react或vue就大材小用了。可以通过webpack、gulp这些构建工具&#xff0c;也能快速完成html页面开发&#xff0c;并且也能使用less/sass/styus等样式预编译功能&#xff0c;以及将js、html分模块、分组…

RabbitMQ高级笔记

视频链接&#xff1a;【黑马程序员RabbitMQ入门到实战教程】 文章目录 1.发送者的可靠性1.1.生产者重试机制1.2.生产者确认机制1.3.实现生产者确认1.3.1.开启生产者确认1.3.2.定义ReturnCallback1.3.3.定义ConfirmCallback 2.MQ的可靠性2.1.数据持久化2.1.1.交换机持久化2.1.2.…

小米汽车SU7发布,售价21.59万起,订单总额破1亿

文 | 大力财经 小米召开新车发布会&#xff0c;正式发布小米 SU7。该车定位中大型纯电轿车&#xff0c;有 SU7、SU7 Pro、SU7 Max 三个版本&#xff0c;车身尺寸 4997/1963/1455mm&#xff0c;轴距 3000mm。售价 21.59-29.99 万。 新车发布后&#xff0c;市场反应热烈&#x…

Topaz Gigapixel AI for Mac 图像放大软件

Topaz Gigapixel AI for Mac是一款专为Mac用户设计的智能图像放大软件。它采用了人工智能技术&#xff0c;特别是深度学习算法&#xff0c;以提高图像的分辨率和质量&#xff0c;使得图像在放大后仍能保持清晰的细节。这款软件的特点在于其能够将低分辨率的图片放大至高分辨率&…

openPLC_Editor C语言编程 在mp157 arm板上调用io等使用记录

1.编程界面比较简单&#xff0c;具备PLC开发编程的四种编程方式。梯形图语言LD &#xff0c;指令表语言IL&#xff0c;结构化文本语言ST&#xff0c;功能模块图语言FBD。 2.官方使用手册。学习资料实在是太少&#xff0c;目前都是自己比较费劲的研究。 3.2 Creating Your First…

QT6实现音频输出方法

一.QT6音频调用及与QT5的区别 1.音频输入 QAudioSource代替QAudioInput类 QAudioSource类提供了一个接口&#xff0c;用于从音频输入设备接收音频数据。 Header: #include <QAudioSource> qmake: QT multimedia 2.音频输出 QAudioSink代替QAudioOutput类 QAudioSi…

【数据挖掘】实验5:数据预处理(2)

验5&#xff1a;数据预处理&#xff08;2&#xff09; 一&#xff1a;实验目的与要求 1&#xff1a;熟悉和掌握数据预处理&#xff0c;学习数据清洗、数据集成、数据变换、数据规约、R语言中主要数据预处理函数。 二&#xff1a;实验知识点总结 1&#xff1a;数据集成是将多个…

Topaz Video AI for mac 视频增强软件

Topaz Video AI for Mac是一款专为Mac用户设计的视频增强软件&#xff0c;它利用先进的人工智能技术和机器学习算法&#xff0c;为用户提供卓越的视频编辑和增强体验。 软件下载&#xff1a;Topaz Video AI for mac v4.2.2激活版 这款软件能够快速提高视频的清晰度、色彩饱和度…

激发数据潜力:企业数据中台的策略性构建与优化_光点科技

在信息时代&#xff0c;数据是企业价值链中不可或缺的一环。构建一个策略性的企业数据中台不仅能够整合分散的数据资源&#xff0c;还能提高决策效率和业务敏捷性。本文聚焦于如何策略性地构建和优化数据中台&#xff0c;以便企业能够最大化地利用数据资源&#xff0c;推动企业…

独立游戏《星尘异变》UE5 C++程序开发日志3——UEC++特供的数据类型

本篇日志将介绍FString&#xff0c;FText、FName的用法和相互转换&#xff0c;以及容器TMap&#xff0c;TArray的增删查改 一、字符串相关数据类型&#xff1a;FString、FText、FName FString是最接近std::string的类型&#xff0c;字符串本身可以看做一个存储char型的动态数…

【Django学习笔记(二)】CSS语言介绍

CSS语言介绍 前言正文1、CSS 快速了解2、CSS 应用方式2.1 在标签上应用2.2 在head标签中写style标签2.3 写到文件中 3、问题探讨&#xff1a;用Flask框架开发不方便4、选择器4.1 ID选择器4.2 类选择器4.3 标签选择器4.4 属性选择器4.5 后代选择器4.6 注意事项 5、样式5.1 高度和…

【RISC-V】如何使用release的risc-v gnu toolchain

riscv64-elf-ubuntu-22.04-gcc-nightly-2024.03.01-nightly.tar.gz 首先去release页面中获取相应的压缩包 将压缩包解压到想解压的位置&#xff0c;这里我选择了 mv Downloads/riscv64-elf-ubuntu-22.04-gcc-nightly-2024.03.01-nightly.tar.gz riscv64-tool-chain/然后解压…

python 字典练习

# 字典练习1 import time def main():month_income{1月: 8000, 2月: 8200, 3月: 7900, 4月: 6900, 5月: 8900, 6月: 12000, 7月: 8900, 8月: 6000,9月: 8900, 10月: 9200, 11月: 6200, 12月: 7000}year_income0for k,v in month_income.items():print(月份→,k,工资→,v)time.s…

中国香港男歌手张国荣 明星网页成品 html人物明星网页设计制作 明星前端网页开发 网页期末设计制作作业成品

中国香港男歌手张国荣 7页面 人物明星主题 带设计说明 jquery图片轮播特效 滚动文字 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns"http://ww…

【c++】类和对象(五)赋值运算符重载

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;c笔记仓 朋友们大家好&#xff0c;本篇文章带大家认识赋值运算符重载&#xff0c;const成员&#xff0c;取地址及const取地址操作符重载等内容 目录 1.赋值运算符重载1.1运算符重载1.1.1特性&#…

刷题之动态规划

前言 大家好&#xff0c;我是jiantaoyab&#xff0c;开始刷动态规划的题目了&#xff0c;要特别注意初始化的时候给什么值。 动态规划5个步骤 状态表示 &#xff1a;dp数组中每一个下标对应值的含义是什么->dp[i]表示什么状态转移方程&#xff1a; dp[i] 等于什么1 和 2 是…

软考101-上午题-【信息安全】-网络安全

一、网络安全 1-1、安全协议 SSL(Secure Socket Layer&#xff0c;安全套接层)是 Netscape 于 1994年开发的传输层安全协议&#xff0c;用于实现 Web 安全通信。1996 年发布的 SSL3.0 协议草案已经成为一个事实上的Web 安全标准。 端口号是43。 SSL HTTP HTTPS TLS(Transpo…

XXE漏洞知识及ctfshow例题

XXE漏洞相关知识 XXE全称为XML Enternal Entity Injection 中文叫xml外部实体注入 什么是xml 简单了解XML&#xff1a; &#xff08;xml和html的区别可以简易的理解成&#xff1a;xml是用来储存数据和传输数据的而html是用来将数据展现出来&#xff09; XML 指可扩展标记语…

vue3封装Element导航菜单

1. 导航外层布局 AsideView.vue <template><el-menu:default-active"defaultActive"class"my-menu":collapse"isCollapse":collapse-transition"false"open"handleOpen"close"handleClose"><menu…