STM32 软件模拟I2C 操作时序图

m24c02芯片手册可以查看时序图

起始和停止信号

写一个字节:

主发送起始-》 CPU 芯片内部的I2C 控制器(片上外设主设备)-》发送起始信号-》发送设备地址-》EEPROM(从设备)返回回应信号-》主发字节起始地址-》从回应-》主发数据-》从回应-》主发送停止。

        EEPROM256个字节,需要字节地址进行指定,这个字节地址是一个字节。

为什么STM32 软件模拟I2C需要delay延迟:

因为:EEPROM感知SCL时间有最低要求Tchcl,手册中规定Tchcl需要4us。

当前通讯速率100k,一个周期1/100k = 1/100ms = 10us,一个高电平和一个低电平整合是一个周期。

soft_i2c.h文件

#ifndef __SOFT_I2C_H__
#define __SOFT_I2C_H__#include "stm32f10x.h"
#include "delay.h"#define SCL_HIGH (GPIOB->ODR |= GPIO_ODR_ODR10)
#define SCL_LOW (GPIOB->ODR &= ~ GPIO_ODR_ODR10)#define SDA_HIGH (GPIOB->ODR |= GPIO_ODR_ODR11)
#define SDA_LOW (GPIOB->ODR &= ~GPIO_ODR_ODR11)#define SDA_READ (GPIOB->IDR & GPIO_IDR_IDR11)// 1. 为了方便代码编写 我们创建一个枚举类型
typedef enum{ACK,NOACK
} ACK_RESULT;void I2C_Init(void);void I2C_Start(void);void I2C_SendByte(uint8_t byte);uint8_t I2C_ReceiveByte(void);ACK_RESULT I2C_Wait4ACK(void);void I2C_Stop(void);// acknowledge
void I2C_ACK(void);void I2C_NOACK(void);#endif /* __SOFT_I2C_H__ */

soft_i2c.c文件

#include "soft_i2c.h"// 软件的I2C初始化 其实是对GPIO的初始化
void I2C_Init(void){// 1. 放时钟 PB组RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;// new * 上电之后 应该默认是高阻态 表示空闲// GPIOB->ODR |= GPIO_ODR_ODR10;// GPIOB->ODR |= GPIO_ODR_ODR11;SCL_HIGH;SDA_HIGH;// 2. PB10 PB11 通用开漏模式 输出速度无脑最高GPIOB->CRH |= GPIO_CRH_MODE10;GPIOB->CRH &= ~ GPIO_CRH_CNF10_1;GPIOB->CRH |= GPIO_CRH_CNF10_0;GPIOB->CRH |= GPIO_CRH_MODE11;GPIOB->CRH &= ~ GPIO_CRH_CNF11_1;GPIOB->CRH |= GPIO_CRH_CNF11_0;
}// 1. 在I2C开始通讯前
// SDA 和 SCL 两个线 应该是什么状态?// 约定!每一个函数后 都必须维护好状态
// 除了 STOP  SCL必须为低  SDA必须为高
void I2C_Start(void){// 0. 先确保 两根线都是高电平SDA_HIGH;SCL_HIGH;// 1. 做个延时 防止王八(E2PROM)反应不过来Delay_us(5);SDA_LOW;Delay_us(5);// 2.为了防止误采样 必须要保证 结束时的SCL处于低电平SCL_LOW;    // 1.防止误采样 始终占用时钟线SDA_HIGH;   // 保证SDA是高电平 这样别的设备可以占用// 3. 保证时钟线为低电平的时间足够长 也是为了照顾王八。Delay_us(5);
}void I2C_Stop(void){// 1. 已经约定好了 其他函数必须以SDA_HIGH结束 SDA_LOW;SCL_HIGH;Delay_us(5);SDA_HIGH;Delay_us(5);
}void I2C_SendByte(uint8_t byte){// 1. 函数第一次进来的时候 初始状态for (uint8_t i = 0; i < 8; i++){// 1. 0x80 是 1000 0000掩码,相当于取出8个bit中的最高位if(byte & 0x80){// 要发一个逻辑1SDA_HIGH;}else {SDA_LOW;}// 2. 时钟拉高,让E2Prom采样SCL_HIGH;Delay_us(5);// 3. 时钟拉低 并留足时间,SDA_HIGH是为了让函数执行完后,能够保持约定的状态。SCL_LOW;SDA_HIGH;Delay_us(5);// 4. 数组左移1位 准备发送下一个bitbyte = byte << 1;}// 5. 确保每一个函数执行完后,都是SDA为HIGH SCL为LOW的状态。
}ACK_RESULT I2C_Wait4ACK(void){ACK_RESULT ack = NOACK;// 0. 给出第9个节拍 并给足从设备反应 ACK 的时间SCL_HIGH;Delay_us(5);// 1. 读取SDA的值 判断到底有没有ACKif(SDA_READ){ack = NOACK;}else{ack = ACK;}// 2. 后摇 给足时钟的低电平时间。SCL_LOW;Delay_us(5);// 3. 返回ACK状态return ack;
}uint8_t I2C_ReceiveByte(void){// 0. 先准备一个容器 去装8个bituint8_t byte =  0;// 1. 循环8次for (uint8_t i = 0; i < 8; i++){// 2. 先把时钟拉高 保持一定时间 让EEPROM发bitSCL_HIGH;Delay_us(5);// 3. 左移写前面 让它先空左移一次byte <<= 1;// 4. 读取SDA状态,如果是1就置1。if(SDA_READ){byte |= 1;}// 5. 维持一段时间时钟低电平 让EEPROM换数据SCL_LOW;Delay_us(5);}// 6. 最后的状态: SCL还是低,SDA被EEPROM自动释放 那就是高了。return byte;
}// 0. 现在是STM32负责响应
void I2C_ACK(void){// 1. 在时钟线拉高之前 将SDA拉低 并让信号维持一段时间,确保EEPROM反应过来SDA_LOW;SCL_HIGH;Delay_us(5);// 2. 时钟线拉低之后 再将SDA释放 否则的话可能会导致 EEPROM误采样。SCL_LOW;SDA_HIGH;Delay_us(5);
}void I2C_NOACK(void){// 1. 因为约定好了SDA一定是高电平 所以 不用鸟SDASCL_HIGH;Delay_us(5);SCL_LOW;Delay_us(5);
}

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

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

相关文章

2024年软件测试面试题(800道)【附带答案】持续更新...

新的一年又到了立flag的时候&#xff0c;今年你的目标是拿下大厂offer&#xff1f;还是多少万年薪&#xff1f;其实这些都离不开日积月累的过程。 为此我特意整理出一份&#xff08;超详细笔记/面试题&#xff09;它几乎涵盖了所有的测试开发技术栈&#xff0c;非常珍贵&#…

jdk1.7 发送post请求

所需依赖为 引入依赖为 import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.methods.PostMethod;特别说明 tmpString为json对象 System.out.println("tmpString " tmpString);// 处理发送https 错误问题SSLContext context …

鸿蒙音乐播放器(超详细)

基于API9的音乐播放器&#xff0c;可播放&#xff0c;暂停&#xff0c;上&#xff0c;下一首歌曲切换等功能 文章目录 1.效果展示 2.首页 3.播放页 注&#xff1a;需要使用模拟器或真机调试运行 一、效果展示 1.首页样式&#xff1a; 2.播放样式&#xff1a; 二、首页功能代码…

基于SQL数据库的酒店管理系统

一、数据库设计 1&#xff0e;需求分析 客房的预定&#xff1a;可以通过网络进行预定&#xff0c;预定修改&#xff0c;取消预订。 客房管理&#xff1a;预定管理、客房查询、设置房态、开房、换房、续住、退房等管理。 员工管理: 员工修改信息、人员调配。 账务管理&…

绿色智能:AI机器学习在环境保护中的深度应用与实践案例

&#x1f9d1; 博主简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟&#xff0c;欢迎关注。提供嵌入式方向…

2.vue常用指令

2.vue常用指令 目录 1. vue的基础语法结构2. 插值语法3. vue常用指令 3.1 v-html语法结构3.2 v-text3.3 v-bind 绑定动态属性3.4 v-on 添加事件 语法格式3.4.1事件绑定3.4.2 获取event对象3.4.3 动态事件缩写3.4.5 事件绑定的修饰符 3.5 v-if v-else-if v-else5.6 v-show5.7 …

《Solana 中文开发教程》学习笔记(Part 1~4)

Part 1 &#xff1a;Solana介绍 2017年11月&#xff0c;Anatoly Yakovenko发表了一篇白皮书&#xff0c;介绍了“Proof of History”这一技术 Part 2 &#xff1a;Solana介绍 Account 在Solana中&#xff0c;"Everythin is an Account" 类似Linux世界里面把所有的…

基于触觉感知的目标识别技术在智能机器人抓取中的应用综述

引言在智能机器人抓取任务中&#xff0c;目标识别是一个核心问题。机器人不仅需要识别物体&#xff0c;还需根据物体的形状、纹理、硬度等信息来规划抓取策略。传统的目标识别方法通常依赖于视觉信息&#xff0c;但在许多复杂环境中&#xff0c;单一视觉信息往往不能提供足够的…

huggingface 中模型如何查找和使用?

在 Models - Hugging Face模型中找使用方法 https://hf-mirror.com/ 一&#xff1a;如何找到统一使用方法 对于文字处理AutoTokenizer是一样的&#xff0c;模型名可能不一样。具体操作如下&#xff1a; 1. 先在模型下面找到你需要的模型点开 2. 点开最右边的Use in Transfor…

AgentLego:组装大模型智能体“乐高”

1 AgentLego 1.1 AgentLego 是什么 AgentLego 是一个提供了多种开源工具 API 的多模态工具包&#xff0c;旨在像是乐高积木一样&#xff0c;让用户可以快速简便地拓展自定义工具&#xff0c;从而组装出自己的智能体。通过 AgentLego 算法库&#xff0c;不仅可以直接使用多种工…

w071基于springboot的图书进销存管理系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以查看文章末尾⬇️联系方式获取&#xff0c;记得注明来意哦~&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0…

手撕单例的 5 种写法!

单例模式是一种常见的设计模式&#xff0c;它确保一个类只有一个实例&#xff0c;并提供一个全局访问点来获取该实例。当然&#xff0c;它也是面试中的常客&#xff0c;尤其是某手面试中经常要求应聘者手撕&#xff0c;所以今天咱们就来盘盘它。 单例模式的实现方式有很多&…

制作Windows11个人iso镜像的方法

一、前期准备 1.光盘刻录软件AnyBurn 2.对应Windows11版本的iso基础镜像&#xff08;一定要对应&#xff0c;不然封装的iso镜像无法使用&#xff09; Windows11最新版本24H2的iso镜像下载地址下载 Windows 11 此前版本下载地址官方网站不再提供&#xff0c;需要自行搜索下载 笔…

timesnet+timemixer时间序列预测模型

1.timesnet 原论文源码&#xff1a;https://github.com/thuml/Time-Series-Library?tabreadme-ov-file 时间序列分析被广泛应用于众多领域中&#xff0c;如天气预报中预测气象要素的未来变化、数据质控时填补缺失值、工业生产中监控设备状态、医疗诊断时分析心跳曲线等。 不…

Linux 35.6 + JetPack v5.1.4之RTP实时视频Python框架

Linux 35.6 JetPack v5.1.4之RTP实时视频Python框架 1. 源由2. 思路3. 方法论3.1 扩展思考 - 慎谋而后定3.2 扩展思考 - 拒绝拖延或犹豫3.3 扩展思考 - 哲学思考3.4 逻辑实操 - 方法论 4 准备5. 分析5.1 gst-launch-1.05.1.1 xvimagesink5.1.2 nv3dsink5.1.3 nv3dsink sync05…

异或和公式

前缀异或和公式 前缀异或和的概念与前缀和类似&#xff0c;但它使用的是异或&#xff08;XOR&#xff09;操作而不是加法。异或操作有一些独特的性质&#xff0c;使得前缀异或和在处理某些问题时非常有用。下面是前缀异或和的推导原理&#xff1a; • 异或操作的性质&#xf…

【Unity】 HTFramework框架(五十三)使用 Addressables 可寻址系统

更新日期&#xff1a;2024年7月25日。 Github源码&#xff1a;[点我获取源码] Gitee源码&#xff1a;[点我获取源码] 索引 Addressables 可寻址系统使用 Addressables 可寻址系统一、导入 Addressables二、切换到 Addressables 加载模式三、切换资源加载助手四、加载资源五、注…

Spring Cache简单使用

Spring Cache是一个框架&#xff0c;实现了基于注解的缓存功能。只需要简单地加一个注解&#xff0c;就能实现缓存功能 Spring Cache提供了一层抽象&#xff0c;底层可以切换不同的缓存实现&#xff0c;例如&#xff1a; 1.EHCahce 2.Chffeine 3.Redis 需要导入的maven坐标 …

Delphi Web前端开发教程(9):基于TMS WEB Core框架

3、REST Servers服务端(后端)框架 REST服务端特点&#xff1a; – 为远程资源提供一个REST API接口。也可以为其他网络内容提供服务&#xff1b; – 包括在Delphi Enterprise & Architect企业版和架构师版中的RAD服务器、DataSnap、WebBroker&#xff1b; – 开源框架&a…

vue+mars3d点击图层展示炫酷的popup弹窗

展示效果 目录 一&#xff1a;叠加数据图层到地图上&#xff0c;此时需要使用bindPopup绑定popup 二、封装自定义的popup&#xff0c;样式可以自行调整 一&#xff1a;叠加数据图层到地图上&#xff0c;此时需要使用bindPopup绑定popup 这里我根据数据不同&#xff0c;展示的…