当前位置: 首页 > article >正文

告别硬件IIC:STM32F103用软件模拟IIC读写AT24C02/04/16全攻略(含地址计算详解)

STM32软件模拟IIC驱动AT24C系列EEPROM实战指南1. 为什么选择软件模拟IIC在嵌入式开发中IIC总线因其简单的两线制SDA和SCL和灵活的多设备连接特性成为连接各类传感器的首选方案。然而STM32的硬件IIC模块在实际应用中常会遇到各种问题硬件IIC的局限性某些STM32型号如F1系列的硬件IIC存在稳定性问题特别是在高时钟频率下容易出现通信失败引脚冲突硬件IIC引脚固定当这些引脚被其他功能占用时无法灵活调整库函数复杂性HAL库的硬件IIC接口相对复杂调试困难相比之下软件模拟IIC具有以下优势引脚可任意配置可以使用任何GPIO引脚作为SDA和SCL线调试方便可以灵活添加调试信息逐步跟踪通信过程兼容性强同一套代码可以适配不同型号的STM32芯片// 软件IIC引脚配置示例 #define IIC_SCL_PIN GPIO_PIN_6 #define IIC_SCL_PORT GPIOB #define IIC_SDA_PIN GPIO_PIN_7 #define IIC_SDA_PORT GPIOB void IIC_Init(void) { GPIO_InitTypeDef GPIO_InitStruct {0}; // 使能GPIO时钟 __HAL_RCC_GPIOB_CLK_ENABLE(); // 配置SCL和SDA为开漏输出模式 GPIO_InitStruct.Pin IIC_SCL_PIN | IIC_SDA_PIN; GPIO_InitStruct.Mode GPIO_MODE_OUTPUT_OD; GPIO_InitStruct.Pull GPIO_PULLUP; GPIO_InitStruct.Speed GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOB, GPIO_InitStruct); // 初始状态拉高总线 HAL_GPIO_WritePin(IIC_SCL_PORT, IIC_SCL_PIN, GPIO_PIN_SET); HAL_GPIO_WritePin(IIC_SDA_PORT, IIC_SDA_PIN, GPIO_PIN_SET); }2. AT24C系列EEPROM关键特性解析AT24C系列是Microchip公司生产的串行EEPROM存储器具有以下共同特点工作电压宽1.8V至5.5V存储容量从1Kbit(AT24C01)到512Kbit(AT24C512)多种选择接口标准IIC接口支持400kHz高速模式耐久性可擦写100万次数据保存100年不同型号的主要区别在于存储容量和地址空间分配型号容量(Kbit)字节容量页大小设备地址位地址字节数AT24C0111288A2,A1,A01AT24C0222568A2,A1,A01AT24C04451216A2,A11AT24C088102416A21AT24C1616204816无1AT24C3232409632A2,A1,A02AT24C6464819232A2,A1,A02注意AT24C01-AT24C16使用单字节地址而AT24C32及以上型号需要使用双字节地址3. 设备地址计算与页写入策略3.1 设备地址计算AT24C系列设备的IIC地址由固定部分和可配置部分组成固定部分高4位固定为1010可配置部分低3位由芯片型号和硬件连接决定对于不同容量的芯片设备地址计算方式不同AT24C01/02A2,A1,A0引脚状态直接决定设备地址低3位设备地址格式1010 A2 A1 A0 R/W同一IIC总线上最多可挂8个设备AT24C04仅使用A2,A1引脚A0悬空设备地址格式1010 A2 A1 P0 R/WP0位用于页选择高地址位同一IIC总线上最多可挂4个设备AT24C16不使用A2,A1,A0引脚设备地址格式1010 P2 P1 P0 R/WP2,P1,P0用于页选择同一IIC总线上只能挂1个设备// AT24C16设备地址计算函数 uint8_t AT24C16_GetDeviceAddress(uint16_t memAddr) { uint8_t page memAddr / 256; // 每页256字节 return 0xA0 | ((page 1) 0x0E); // 1010 P2P1P0 0(写) }3.2 页写入策略AT24C系列支持页写入模式可以一次性写入一页数据显著提高写入效率页大小不同型号页大小不同AT24C01/02为8字节AT24C04及以上为16字节或更大跨页处理当写入数据跨越页边界时需要分多次写入void AT24C_WritePage(uint8_t devAddr, uint16_t memAddr, uint8_t *data, uint8_t len) { uint8_t pageSize 16; // AT24C16页大小 uint8_t offset memAddr % pageSize; uint8_t remain pageSize - offset; if(len remain) { // 单次写入不跨页 IIC_Start(); IIC_SendByte(devAddr); IIC_SendByte(memAddr 0xFF); for(uint8_t i0; ilen; i) { IIC_SendByte(data[i]); } IIC_Stop(); delay_ms(5); // 写入周期等待 } else { // 分两次写入跨页数据 AT24C_WritePage(devAddr, memAddr, data, remain); AT24C_WritePage(devAddr, memAddrremain, dataremain, len-remain); } }4. 完整驱动实现与优化技巧4.1 基础驱动函数实现完整的软件IIC驱动需要实现以下基本函数起始信号SCL高电平时SDA从高到低的跳变停止信号SCL高电平时SDA从低到高的跳变发送字节SCL低电平时改变SDASCL高电平时保持稳定接收字节SCL高电平时读取SDA状态等待应答发送完字节后检测从机应答// 产生IIC起始信号 void IIC_Start(void) { SDA_HIGH(); SCL_HIGH(); delay_us(4); SDA_LOW(); delay_us(4); SCL_LOW(); // 钳住总线准备发送数据 } // 产生IIC停止信号 void IIC_Stop(void) { SDA_LOW(); SCL_LOW(); delay_us(4); SCL_HIGH(); SDA_HIGH(); // 发送结束信号 delay_us(4); } // 等待应答信号 uint8_t IIC_Wait_Ack(void) { uint8_t timeout 0; SDA_INPUT(); // SDA设置为输入 SDA_HIGH(); delay_us(1); SCL_HIGH(); delay_us(1); while(SDA_READ()) { timeout; if(timeout 250) { IIC_Stop(); return 1; // 应答超时 } } SCL_LOW(); return 0; // 正常应答 }4.2 读写函数优化针对AT24C系列EEPROM的特点可以进行以下优化批量读写优化减少起始/停止信号的次数写入延迟处理AT24Cxx内部写入需要时间典型值5ms错误重试机制增加通信失败时的自动重试// 带错误重试的读取函数 uint8_t AT24C_ReadWithRetry(uint16_t addr, uint8_t *buf, uint16_t len, uint8_t retry) { while(retry--) { if(AT24C_Read(addr, buf, len) 0) { return 0; // 成功 } delay_ms(1); } return 1; // 失败 } // 带写入延迟的页写入函数 void AT24C_WriteWithDelay(uint8_t devAddr, uint16_t memAddr, uint8_t *data, uint8_t len) { uint8_t retry 3; while(retry--) { AT24C_WritePage(devAddr, memAddr, data, len); delay_ms(5); // 等待内部写入完成 // 验证写入是否正确 uint8_t verify[16]; AT24C_Read(devAddr, memAddr, verify, len); if(memcmp(data, verify, len) 0) { break; // 验证成功 } } }4.3 驱动使用示例下面是一个完整的使用示例演示如何初始化、写入和读取数据#include at24cxx.h #include stdio.h #define TEST_ADDR 0x100 #define TEST_SIZE 16 int main(void) { // 初始化硬件 HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_I2C_Init(); // 初始化AT24C16 AT24C_Init(); // 测试数据 uint8_t writeData[TEST_SIZE] {0}; uint8_t readData[TEST_SIZE] {0}; // 填充测试数据 for(uint8_t i0; iTEST_SIZE; i) { writeData[i] i; } // 写入数据 if(AT24C_Write(TEST_ADDR, writeData, TEST_SIZE)) { printf(Write failed!\r\n); while(1); } // 读取数据 if(AT24C_Read(TEST_ADDR, readData, TEST_SIZE)) { printf(Read failed!\r\n); while(1); } // 验证数据 if(memcmp(writeData, readData, TEST_SIZE) 0) { printf(Test passed!\r\n); } else { printf(Test failed!\r\n); } while(1); }5. 常见问题与调试技巧在实际开发中可能会遇到以下常见问题通信失败检查上拉电阻通常4.7kΩ确认SCL/SDA引脚配置正确降低通信速度测试写入后读取数据不正确确保写入后留有足够延迟5ms实现写入验证机制检查设备地址计算是否正确跨页写入数据丢失正确实现页边界检查分多次写入跨页数据调试建议使用逻辑分析仪捕获IIC波形在关键位置添加调试打印实现逐步调试的测试函数// 调试用函数打印IIC总线状态 void IIC_DebugBusState(void) { printf(SCL: %d, SDA: %d\r\n, HAL_GPIO_ReadPin(IIC_SCL_PORT, IIC_SCL_PIN), HAL_GPIO_ReadPin(IIC_SDA_PORT, IIC_SDA_PIN)); } // 逐步调试的测试函数 void IIC_StepTest(void) { printf(Testing IIC start condition...\r\n); IIC_Start(); IIC_DebugBusState(); delay_ms(100); printf(Testing IIC stop condition...\r\n); IIC_Stop(); IIC_DebugBusState(); delay_ms(100); printf(Testing byte transmission...\r\n); IIC_Start(); IIC_SendByte(0xA0); uint8_t ack IIC_Wait_Ack(); printf(ACK received: %d\r\n, ack); IIC_Stop(); }6. 性能优化与高级应用6.1 提高读写速度提高时钟频率在保证可靠性的前提下提高SCL频率减少延迟优化微秒级延迟函数批量操作使用页写入/读取减少通信开销// 优化后的微秒延迟函数 static inline void delay_us(uint32_t us) { uint32_t ticks us * (SystemCoreClock / 1000000) / 5; while(ticks--) { __NOP(); } } // 高速页读取函数 void AT24C_FastRead(uint16_t addr, uint8_t *buf, uint16_t len) { uint8_t devAddr AT24C16_GetDeviceAddress(addr); IIC_Start(); IIC_SendByte(devAddr); IIC_SendByte(addr 0xFF); IIC_Start(); // 重复起始条件 IIC_SendByte(devAddr | 0x01); // 读模式 for(uint16_t i0; ilen; i) { buf[i] IIC_ReadByte(i len-1); // 最后一个字节发送NACK } IIC_Stop(); }6.2 数据存储结构设计对于需要存储结构化数据的应用可以设计更高效的数据组织方式数据分块按功能或类型将数据存储在不同地址区域数据版本控制存储数据时包含版本信息冗余存储重要数据多份存储提高可靠性// 数据头结构 typedef struct { uint16_t magic; // 魔数标识 uint16_t version; // 数据版本 uint32_t crc; // CRC校验 uint32_t length; // 数据长度 } DataHeader; // 带校验的数据存储函数 uint8_t AT24C_WriteWithHeader(uint16_t addr, void *data, uint16_t len) { DataHeader header { .magic 0x55AA, .version 1, .crc Calculate_CRC(data, len), .length len }; // 写入头和数据 if(AT24C_Write(addr, (uint8_t*)header, sizeof(header))) return 1; if(AT24C_Write(addrsizeof(header), (uint8_t*)data, len)) return 1; return 0; } // 带校验的数据读取函数 uint8_t AT24C_ReadWithHeader(uint16_t addr, void *data, uint16_t maxLen) { DataHeader header; // 读取头 if(AT24C_Read(addr, (uint8_t*)header, sizeof(header))) return 1; // 验证头 if(header.magic ! 0x55AA || header.length maxLen) return 1; // 读取数据 if(AT24C_Read(addrsizeof(header), (uint8_t*)data, header.length)) return 1; // 验证CRC if(Calculate_CRC(data, header.length) ! header.crc) return 1; return 0; }6.3 多设备管理当系统中需要连接多个IIC设备时可以设计统一的管理接口typedef struct { uint8_t devAddr; // 设备地址 uint16_t pageSize; // 页大小 uint32_t capacity; // 总容量 uint8_t addrBytes; // 地址字节数 } IIC_Device; IIC_Device devices[] { {0xA0, 16, 2048, 1}, // AT24C16 {0x68, 1, 32, 1} // DS3231 RTC }; uint8_t IIC_DeviceRead(uint8_t devIndex, uint32_t addr, uint8_t *buf, uint16_t len) { IIC_Device *dev devices[devIndex]; IIC_Start(); IIC_SendByte(dev-devAddr); if(dev-addrBytes 2) { IIC_SendByte(addr 8); // 高地址字节 } IIC_SendByte(addr 0xFF); // 低地址字节 IIC_Start(); // 重复起始条件 IIC_SendByte(dev-devAddr | 0x01); // 读模式 for(uint16_t i0; ilen; i) { buf[i] IIC_ReadByte(i len-1); // 最后一个字节发送NACK } IIC_Stop(); return 0; }

相关文章:

告别硬件IIC:STM32F103用软件模拟IIC读写AT24C02/04/16全攻略(含地址计算详解)

STM32软件模拟IIC驱动AT24C系列EEPROM实战指南 1. 为什么选择软件模拟IIC? 在嵌入式开发中,IIC总线因其简单的两线制(SDA和SCL)和灵活的多设备连接特性,成为连接各类传感器的首选方案。然而,STM32的硬件IIC…...

Phi-4-mini-flash-reasoning多场景:从单题求解到批量PRD分析的扩展路径

Phi-4-mini-flash-reasoning多场景:从单题求解到批量PRD分析的扩展路径 1. 轻量级推理模型的核心价值 Phi-4-mini-flash-reasoning是一款专为结构化思维任务设计的轻量级文本推理模型。与通用大模型不同,它在数学推导、逻辑分析和长文本推理等场景展现…...

06华夏之光永存:电磁弹射+一次性火箭航天入轨方案【第六篇:电磁弹射核心电池组参数与供配电优化方案】

华夏之光永存:电磁弹射一次性火箭航天入轨方案【第六篇:电磁弹射核心电池组参数与供配电优化方案】核心备注:本文为该系列第六篇核心电池组供配电篇,系列共计10篇保姆式开源落地白皮书,全文基于大功率储能电化学、电力…...

完整网页截图终极指南:如何一键保存超长网页的完美副本

完整网页截图终极指南:如何一键保存超长网页的完美副本 【免费下载链接】full-page-screen-capture-chrome-extension One-click full page screen captures in Google Chrome 项目地址: https://gitcode.com/gh_mirrors/fu/full-page-screen-capture-chrome-exte…...

网络受限环境下的OOTDiffusion虚拟试衣AI完整部署实战指南

网络受限环境下的OOTDiffusion虚拟试衣AI完整部署实战指南 【免费下载链接】OOTDiffusion [AAAI 2025] Official implementation of "OOTDiffusion: Outfitting Fusion based Latent Diffusion for Controllable Virtual Try-on" 项目地址: https://gitcode.com/Gi…...

五大免费大语言模型(LLM)课程推荐与学习指南

1. 大语言模型(LLMs)学习资源概览过去两年,大语言模型(LLMs)的发展速度令人咋舌。从最初的文本补全到现在的多模态交互,这些模型正在重塑我们与数字世界的互动方式。作为一名长期跟踪AI技术发展的从业者&am…...

机器学习中矩阵类型与应用实践指南

1. 矩阵类型在机器学习线性代数中的核心价值第一次接触机器学习时,我被各种矩阵运算绕得头晕眼花,直到发现不同类型的矩阵其实对应着特定的数学特性和应用场景。就像木匠需要了解不同木材的特性才能打造好家具,理解矩阵类型能让我们更高效地构…...

机器学习k折交叉验证:k值选择与性能评估指南

1. 机器学习中的k折交叉验证配置指南在机器学习实践中,评估模型性能是项目流程中的关键环节。k折交叉验证(k-Fold Cross-Validation)作为最常用的评估技术之一,其核心思想是将数据集划分为k个大小相似的互斥子集,每次用…...

MCP 2026多租户隔离配置全链路解析,从vCPU亲和性到TLS 1.3租户证书绑定,覆盖7层隔离面

更多请点击: https://intelliparadigm.com 第一章:MCP 2026多租户隔离架构全景概览 MCP 2026(Multi-Tenant Control Plane 2026)是新一代云原生控制平面标准,专为超大规模混合云环境设计。其核心设计理念是“零信任边…...

【2026年AI DevOps分水岭】:Docker AI Toolkit全新Agent编排框架上线,支持AutoGen/MetaGPT原生集成——现在不装,下周CI/CD流水线将自动拒绝旧版镜像

更多请点击: https://intelliparadigm.com 第一章:Docker AI Toolkit 2026 最新版功能 Docker AI Toolkit 2026 是面向 AI 工程化部署的下一代容器化工具链,深度集成模型编译、量化推理、分布式训练监控与合规性审计能力。相比 2025 版本&a…...

全网最全的医药数据库挖掘教学专栏,只需要399元,不断更新,欢迎订阅!

当前的医药数据科学和R语言领域,网络上和书籍市面上一大堆资料,表面看起来琳琅满目,价格从几十元的书籍到动辄几千元一次的线下培训班都有。但绝大多数培训或书籍都受限于时间和篇幅,浅尝辄止,很多仅仅是基础入门&…...

VS Code插件生态失控危机(MCP时代成本暴雷预警):从日均$23.6运维损耗到零预算优化的完整路径

更多请点击: https://intelliparadigm.com 第一章:VS Code插件生态失控危机的本质诊断 VS Code 插件生态的爆发式增长已悄然演变为一场系统性风险——表面繁荣之下,是权限泛滥、依赖污染、更新失序与兼容性黑洞的叠加。其本质并非工具冗余&a…...

终极指南:用BthPS3驱动让PS3控制器在Windows上重获新生

终极指南:用BthPS3驱动让PS3控制器在Windows上重获新生 【免费下载链接】BthPS3 Windows kernel-mode Bluetooth Profile & Filter Drivers for PS3 peripherals 项目地址: https://gitcode.com/gh_mirrors/bt/BthPS3 还记得那些年,你满怀期待…...

DeepXDE技术架构深度解析:多后端科学机器学习框架的设计哲学与实践指南

DeepXDE技术架构深度解析:多后端科学机器学习框架的设计哲学与实践指南 【免费下载链接】deepxde A library for scientific machine learning and physics-informed learning 项目地址: https://gitcode.com/gh_mirrors/de/deepxde DeepXDE是一款面向科学机…...

探索OpenCore Legacy Patcher:让2008-2017年老款Mac重获新生的终极方案

探索OpenCore Legacy Patcher:让2008-2017年老款Mac重获新生的终极方案 【免费下载链接】OpenCore-Legacy-Patcher Experience macOS just like before 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 在苹果生态系统中&#xf…...

Cursor Pro免费激活解决方案:三步解锁AI编程完整功能

Cursor Pro免费激活解决方案:三步解锁AI编程完整功能 【免费下载链接】cursor-free-vip [Support 0.45](Multi Language 多语言)自动注册 Cursor Ai ,自动重置机器ID , 免费升级使用Pro 功能: Youve reached your tria…...

5分钟掌握:百度网盘直链解析工具完全手册

5分钟掌握:百度网盘直链解析工具完全手册 【免费下载链接】baidu-wangpan-parse 获取百度网盘分享文件的下载地址 项目地址: https://gitcode.com/gh_mirrors/ba/baidu-wangpan-parse 还在为百度网盘那蜗牛般的下载速度而抓狂吗?😫 每…...

Plex媒体库如何自动获取YouTube视频元数据:插件配置与命名规范详解

1. 项目概述:为你的本地YouTube视频库注入灵魂 如果你和我一样,是个喜欢把YouTube上喜欢的频道、系列视频下载到本地,然后用Plex搭建个人媒体库的“松鼠党”,那你一定遇到过这个痛点:辛辛苦苦下载下来的视频&#xff…...

Java的CompletableFuture链式调用与异常处理

Java异步编程利器:CompletableFuture链式调用与异常处理 在现代Java开发中,异步编程已成为提升系统性能的关键手段。CompletableFuture作为Java 8引入的异步编程工具,通过链式调用和灵活的异常处理机制,显著简化了多线程任务编排…...

Squad:构建持久化AI智能体团队,革新软件开发协作模式

1. 项目概述:当AI开发团队成为你的代码库“原住民”如果你和我一样,经常在深夜对着一个全新的项目目录发呆,心里盘算着“前端用什么框架?后端API怎么设计?测试用例怎么写?”,然后开始在各种文档…...

政府引导基金数据(2001-2023年)

01、数据介绍自2001年以来,我国政府引导基金在推动经济增长、促进产业升级方面发挥了重要作用。政府引导基金的投资领域十分广泛,涵盖了高新技术产业、战略性新兴产业、现代服务业等多个领域。通过引导社会资本投向这些领域,政府引导基金有效…...

5分钟快速上手:用WebToEpub将网页小说一键转为电子书永久保存

5分钟快速上手:用WebToEpub将网页小说一键转为电子书永久保存 【免费下载链接】WebToEpub A simple Chrome (and Firefox) Extension that converts Web Novels (and other web pages) into an EPUB. 项目地址: https://gitcode.com/gh_mirrors/we/WebToEpub …...

中国高铁航线数据库CRAD(2003-2022年)

01、数据介绍中国高铁航线数据库CRAD(Chinese High-speed Rail and Airline Database)是一个专门收集和管理航空公司和高铁公司交通航线信息的数据仓库。它详细记录了中国各省、市、县所开通的列车站和飞机场的情况,如铁路线路、车站和列车等…...

MusicPlayer2:你的Windows音乐管家,三步打造专属音乐空间

MusicPlayer2:你的Windows音乐管家,三步打造专属音乐空间 【免费下载链接】MusicPlayer2 MusicPlayer2是一款功能强大的本地音乐播放软件,旨在为用户提供最佳的本地音乐播放体验。它支持歌词显示、歌词卡拉OK样式显示、歌词在线下载、歌词编辑…...

TMSpeech终极指南:5分钟配置Windows本地实时语音转文字工具

TMSpeech终极指南:5分钟配置Windows本地实时语音转文字工具 【免费下载链接】TMSpeech 腾讯会议摸鱼工具 项目地址: https://gitcode.com/gh_mirrors/tm/TMSpeech 你是否厌倦了需要联网才能使用的语音转文字工具?担心会议内容被上传到云端泄露隐私…...

c++如何获取目录下的文件数量(不包括子文件夹)_iterator计数【实战】

最直接可靠的方法是使用 std::filesystem::directory_iterator(C17 起),它仅遍历当前目录一层、自动跳过 . 和 ..,配合 is_regular_file() 可精准统计普通文件数,且跨平台、无需手动处理路径细节或系统 API 差异。用 s…...

降ai率软件哪个好用?测评30多个降ai工具后,选出5个降ai利器!

一、前言:2026 年毕业必须通过aigc检测 2026年各高校对学术论文的AIGC疑似度的审查全面变严,均发布了具体AIGC检测报告和数值要求,211和985高校规定本科论文AI率要低于20%,硕士要求 AI 率不高于15%。普通高校一般要求AI率控制在 …...

AI检测率怎么降低?2026年5款知名降AI率工具评测,结果出乎意外!

一、前言:2026 年毕业必须通过aigc检测 2026年各高校对学术论文的AIGC疑似度的审查全面变严,均发布了具体AIGC检测报告和数值要求,211和985高校规定本科论文AI率要低于20%,硕士要求 AI 率不高于15%。普通高校一般要求AI率控制在 …...

ncmppGui:终极免费NCM音乐解密工具完整指南

ncmppGui:终极免费NCM音乐解密工具完整指南 【免费下载链接】ncmppGui 一个使用C编写的极速ncm转换GUI工具 项目地址: https://gitcode.com/gh_mirrors/nc/ncmppGui 你是否曾经在网易云音乐下载了心爱的歌曲,却发现只能在特定客户端播放&#xff…...

风控实时特征总拖慢 RT?滑动窗口、实时计数、聚合更新到底该怎么做(可落地版)

风控实时特征总拖慢 RT?滑动窗口、实时计数、聚合更新到底该怎么做(可落地版) 这篇不讲“实时特征很重要”这种空话,直接按真实项目来拆:入口请求长什么样、特征怎么算、Redis 怎么存、规则怎么取、更新怎么异步、故障…...