使用CUBE_MX使用I2C通信,实现对EEPROM的读写

一、使用CUBE_MX配置

1.配置I2C

2.配置USART1

3.重中之重(在KEIL5打开串口使用的库)

二、KEIL5配置

#include "main.h"
#include "i2c.h"
#include "gpio.h"
#include "usart.h"#include <stdio.h>void SystemClock_Config(void);
void I2C_EE_BufferWrite(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite);
uint32_t I2C_EE_PageWrite(uint8_t* pBuffer, uint8_t WriteAddr, uint8_t NumByteToWrite);#define  DATA_Size			256
#define  EEP_Firstpage      0x00
#define  EEPROM_ADDRESS     0xA0
//一个I2C从设备有两个地址,一个是写操作地址,另一个是读操作地址。例如,开发板上的EEPROM芯片24C02的写操作地址是0xA0,读操作地址是0xA1,也就是在写操作地址上加1。//在I2C的HAL库驱动中,传递从设备地址参数时,只需要设置写操作地址,函数内部会根据读写操作类型,自动使用写操作地址或读操作地址。但是在软件模拟I2C接口通信时,必须明确使用相应的地址。#define I2Cx_TIMEOUT_MAX                300
/* Maximum number of trials for HAL_I2C_IsDeviceReady() function */
#define EEPROM_MAX_TRIALS               300uint8_t I2C_pData[DATA_Size];
uint8_t I2c_Buf_Write[DATA_Size];
uint8_t I2c_Buf_Read[DATA_Size];int main(void)
{HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_I2C1_Init();MX_USART1_UART_Init();for (int i=0; i<DATA_Size; i++ ) //填充要发送的数据{   I2C_pData[i] =i;}//作为主设备向某个地址的从设备发送一定长度的数据HAL_StatusTypeDef status = HAL_OK;printf("通过I2C,由I2C_pData向EEPROM发送数据\r\n");
/*status=HAL_I2C_Mem_Write(&hi2c1, EEPROM_ADDRESS , EEP_Firstpage , I2C_MEMADD_SIZE_8BIT, (uint8_t*)(I2C_pData), DATA_Size, 100);	if(status == HAL_OK ){printf("通过I2C,由I2C_pData向EEPROM发送数据\r\n");status = HAL_OK;}
*/	//由于EEPROM每页只有八个字节,写入不定长的数据需要调用这个函数I2C_EE_BufferWrite( (uint8_t*)I2C_pData,EEP_Firstpage,DATA_Size);//读取写入EEPROM的数据//向某个从设备的指定存储地址开始读取一定长度的数据//将EEPROM读出数据顺序保持到I2c_Buf_Read中status= HAL_I2C_Mem_Read(&hi2c1,EEPROM_ADDRESS,EEP_Firstpage,I2C_MEMADD_SIZE_8BIT,I2c_Buf_Read,DATA_Size,1000);if(status == HAL_OK ){printf("通过I2C,读取EEPROM中的数据,并且保存到I2c_Buf_Read\r\n");status = HAL_OK;}for (int i=0; i<DATA_Size; i++ ) {   printf("数据是 0x%02X  \r\n",I2c_Buf_Read[i]);} while (1){}}/*** @brief System Clock Configuration* @retval None*/
void SystemClock_Config(void)
{RCC_OscInitTypeDef RCC_OscInitStruct = {0};RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;RCC_OscInitStruct.HSIState = RCC_HSI_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK){Error_Handler();}
}/* USER CODE BEGIN 4 *//* AT24C01/02每页有8个字节 */
//#define EEPROM_PAGESIZE    8
#define EEPROM_PAGESIZE 	   8/*** @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   在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(&hi2c1, EEPROM_ADDRESS,WriteAddr, I2C_MEMADD_SIZE_8BIT, (uint8_t*)(pBuffer),NumByteToWrite, 100);while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY){}/* Check if the EEPROM is ready for a new operation */while (HAL_I2C_IsDeviceReady(&hi2c1, EEPROM_ADDRESS, EEPROM_MAX_TRIALS, I2Cx_TIMEOUT_MAX) == HAL_TIMEOUT);/* Wait for the end of the transfer */while (HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY){}return status;
}//重定向c库函数printf到串口DEBUG_USART,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{/* 发送一个字节数据到串口DEBUG_USART */HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 1000);	return (ch);
}///重定向c库函数scanf到串口DEBUG_USART,重写向后可使用scanf、getchar等函数
int fgetc(FILE *f)
{int ch;HAL_UART_Receive(&huart1, (uint8_t *)&ch, 1, 1000);	return (ch);
}/* USER CODE END 4 *//*** @brief  This function is executed in case of error occurrence.* @retval None*/
void Error_Handler(void)
{/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */
}#ifdef  USE_FULL_ASSERT
/*** @brief  Reports the name of the source file and the source line number*         where the assert_param error has occurred.* @param  file: pointer to the source file name* @param  line: assert_param error line source number* @retval None*/
void assert_failed(uint8_t *file, uint32_t line)
{/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【他山之石】优化 JavaScript 的乐趣与价值(上)

前言 这是前几天偶然看到的一篇硬核推文。作者一口气分了 12 个主题探讨了 JavaScript 在优化时应该注意的要点&#xff0c;读后深受启发。由于篇幅较长&#xff0c;分两篇发表。本篇为上篇。 文章目录 Optimizing Javascript for fun and for profit0. Avoid work1. Avoid str…

苍穹外卖Day01-2

导入接口文档 yApi接口管理平台http://api.doc.jiyou-tech.com/ 创建项目 导入接口文件 导入结果界面 Swagger 介绍 使用Swagger你只需要按照它的规范去定义接口及接口相关的信息&#xff0c;就可以做到生成接口文档&#xff0c;以及在线接口调试页面。 官网&#xff1a;ht…

redis群集三种模式:主从复制、哨兵、集群

redis群集有三种模式 redis群集有三种模式&#xff0c;分别是主从同步/复制、哨兵模式、Cluster&#xff0c;下面会讲解一下三种模式的工作方式&#xff0c;以及如何搭建cluster群集 ●主从复制&#xff1a;主从复制是高可用Redis的基础&#xff0c;哨兵和集群都是在主从复制…

【运行】错误分析error: stray ‘\302’ 和 error: stray ‘\240’

您遇到的编译错误主要是由于代码中出现了不受支持的字符&#xff0c;例如 UTF-8 编码下的不可见字符。这通常是由于在代码中使用了特定的空格或格式化字符。 错误分析 error: stray ‘\302’ 和 error: stray ‘\240’ 提示您在文件中发现了无法识别的字符&#xff0c;通常是因…

常耀斌:AI赋能企业数字化转型(清华社发行)

新书地址&#xff1a; 清华出版社&#xff1a;清华大学出版社-图书详情-《AI赋能企业数字化转型》 京东&#xff1a;《AI赋能企业数字化转型 常耀斌 清华大学出版社 9787302669081》【摘要 书评 试读】- 京东图书 内容简介&#xff1a; 在数字经济时代&#xff0c;企业发…

VMware Tools系列三:图解安装完成VMware Tools测试

一、 VMware Tools测试安装是否成功 1. 菜单项检查 VMware Tools 是否已安装&#xff1a; 在 VMware Workstation 中&#xff0c;查看虚拟机的菜单栏&#xff0c;通常在“虚拟机”菜单下会有“重新安装 VMware Tools”的选项&#xff0c;说明 VMware Tools 已经安装。如图所示…

网络设备登录——《路由与交换技术》实验报告

目录 一、实验目的 二、实验设备和环境 三、实验记录 1.通过 Console 登录 步骤1:连接配置电缆。 步骤2:启动PC,运行超级终端。 步骤3:进入Console 配置界面 2.通过 Telnet 登录 步骤1:通过 Console 接口配置 Telnet 用户。 步骤2:配置 super 口令 步骤3:配置登录欢迎…

动手学深度学习(pytorch)学习记录31-批量规范化(batch normalization)[学习记录]

目录 批量规范化&#xff08;batch normalization&#xff09;从头开始实现一个具有张量的批量规范化层简明实现 批量规范化&#xff08;batch normalization&#xff09; 可持续加速深层网络的的收敛速度。再结合残差块&#xff0c;批量规范化使得研究人员可以训练100层以上的…

Java项目实战II基于Java+Spring Boot+MySQL的校园社团信息管理系统(源码+数据库+文档)

目录 一、前言 二、技术介绍 三、系统实现 四、论文参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 在当今高校…

回归预测|2024年2月最新优化算法角蜥优化HLOA|基于角蜥优化BP神经网络数据回归Matlab程序HLOA-BP【优化效果好】

回归预测|2024年2月最新优化算法角蜥优化HLOA|基于角蜥优化BP神经网络数据回归Matlab程序HLOA-BP【优化效果好】 文章目录 一、基本原理1. 角蜥优化算法&#xff08;HLOA&#xff09;简介2. BP 神经网络&#xff08;BP Neural Network&#xff09;简介3. HLOA-BP 回归预测流程总…

Qt开发技巧(四)“tr“使用,时间类使用,Qt容器取值,类对象的删除,QPainter画家类,QString的转换,用好 QVariant类型

继续讲一些Qt技巧操作 1.非必要不用"tr" 如果程序运行场景确定是某一固定语言&#xff0c;就不需要用tr,"tr"之主要针对多语种翻译的&#xff0c;因为tr的本意是包含英文&#xff0c;然后翻译到其他语言比如中文&#xff0c;不要滥用tr&#xff0c;如果没有…

[Python数据可视化]Plotly Express: 地图数据可视化的魅力

在数据分析和可视化的世界中&#xff0c;地图数据可视化是一个强大而直观的工具&#xff0c;它可以帮助我们更好地理解和解释地理数据。Python 的 Plotly Express 库提供了一个简单而强大的方式来创建各种地图。本文将通过一个简单的示例&#xff0c;展示如何使用 Plotly Expre…

FastAdmin CMS 操作手册

FastAdmin CMS 操作手册 概述&#xff1a; 安装&#xff1a; 配置&#xff1a; 模板&#xff1a; 模板目录&#xff1a; 标签&#xff1a; 全局&#xff1a; 文章&#xff1a; 专题&#xff1a; 栏目&#xff1a; 公共参数&#xff1a; 单页&#xff1a; 特殊标签&#xff1a;…

macOS平台TextRank环境配置

1.安装python 2.安装numpy: pip3 install numpy 3.安装networkx: pip3 install networkx 4.安装math2: pip3 install math2 math2安装成功

npm安装时候报错certificate has expired

打开了一个很久没用的电脑&#xff0c;npm和node都装好了&#xff0c;安装包的时候一直报错 request to https://registry.npm.taobao.org/create-react-app failed, reason: certificate has expired而且先报错rollbackFailedOptional 然而npm没什么问题&#xff0c;是ssl过…

TSRPC+Cocos

TSRPC文档: https://tsrpc.cn/docs/get-started/api.html 创建 先创建一个默认的会话项目&#xff0c;找一个文件夹在控制台运行以下代码&#xff1a; npx create-tsrpc-applatest first-api --presets browser # 或者 yarn create tsrpc-app first-api --presets browser运…

【C++语言】C/C++内存管理

一、C/C内存分布 我们先来看一看C/C中有哪些区域&#xff0c;为什么C/C中区分这些区域呢&#xff1f;&#xff1f;不同的数据有不同的存储需求&#xff0c;各个区域满足不同的需求。我们有临时用的数据&#xff0c;该数据是存储在栈帧区域的&#xff1b;在一些数据结构中&#…

『功能项目』回调函数处理死亡【54】

我们打开上一篇53伤害数字UI显示的项目&#xff0c; 本章要做的事情是使用回调函数处理怪物Boss01死亡后增加主角经验值的功能&#xff0c;以及生成一个七秒的升级特效 首先增加一个技能特效重命名为PlayerUpGradeEffect 修改脚本&#xff1a;BossCtrl.cs 修改脚本&#xff1a…

【Linux系统编程】信号的保存与处理

目录 一&#xff0c;信号的保存 1-1&#xff0c;core与Term终止信号 1-2&#xff0c;进程退出与信号的关系 1-3&#xff0c;信号在内核中的表示 1-4&#xff0c;信号操作函数 二&#xff0c;信号的处理 2-1&#xff0c;信号被处理的时期 2-2&#xff0c;内核实现信号的…

zip-password-finder

1.zip-password-finder 对于传统ZIP文件密码的破解&#xff0c;采用密码匹配的方式进行实现&#xff0c;该github库的地址是&#xff1a; GitHub - agourlay/zip-password-finder: Find the password of protected ZIP files.Find the password of protected ZIP files. Cont…