STMF4 硬件IIC(天空星开发板)

                                        前言:笔记参考立创开发文档,连接放在最后

#IIC概念介绍

#IIC介绍

        IIC通信协议,一种常见的串行通信协议,英文全程是 Inter-Integrated Circuit  使用这种通信方式的模块,通常有SCL(Serial Clock Line)  和SDA(Serial Date)两个引脚  ,也就是当看到这两个引脚也就知道,使用的IIC通信。        

        IIC通信分为硬件IIC通信   软件IIC通信,本篇介绍硬件IIC通信 ,想要了解软件IIC的可以看另一篇文章,IIC通信SDA数据线 高电平电压范围在 2.5V~5.5V  低电平范围 0V~0.3V 

#软件IIC介绍

        软件IIC指的是,通过GPIO引脚模拟IIC通信的波形时序,也就是控制引脚的电平变化来传输数据还有时序信号,达到IIC通信的效果目的,软件IIC通信好处是,在MCU内部没有集成硬件IIC电路的时候,可以使用软件IIC通信,只要MCU支持GPIO就能使用软件IIC通信

        软件IIC的性能相对于硬件IIC较低,通常使用在低速通信还有简单通信的情况下去使用。

#硬件IIC介绍

        硬件IIC指的是芯片内部集成的IIC硬件外设,硬件IIC效率远高于软件IIC, STMF4VET6上带有3个硬件IIC,允许与外部IIC接口进行通信,STMF4的硬件IIC使用特定的引脚复位,来进行数据和时钟信号的传输。

       硬件IIC的通信时序波形,是通过硬件电路还有寄存器来实现的,这些电路还有寄存器负责生成时钟,还有数据线电平变化,使其符合IIC通信协议的要求,这个就是IIC通信的硬件控制流程,具体可以参考下图硬件IIC的框图。

                        

        硬件IIC框图里面,可以发现硬件IIC,也支持中断 还有 DMA输出传输数据。

#配置硬件IIC相关流程

#硬件IIC发送流程

        软件初始化:硬件IIC的通信时序,由内部的寄存器 控制器,来负责所以首先要配置IIC控制器的参数,需要设置 IIC速率  地址模式    设备地址

        START设置:发送起始信号到IIC总线,设置硬件IIC控制器开始位来启动发送过程,通过标志位SBSEND判断起始信号是否发送完毕,发送完毕标志位(SBSEND)会置一。

        清除SBSEND:当起始信号发送完成,SBSEND这个标志位会被硬件置1,10位地址模式,需要清除标志位才能进行下一步,7位地址模式,该标志位不能清除。

        清除ADDSEND:如果地址为10位模式,要发送 地址高位地址低位,发送完成ADD10SEND 和 ADDSEND 会由硬件置1,这个时候需要清除 ADD10SEND 和 ADDSEND 如果地址为 7位模式则只需要发送一次地址,并等待ADDSEND硬件置1后,清除ADDSEND标志位。

        传输数据:为了防止数据溢出,需要判断发送寄存器的数据是否为空,也就是查询TBE标志位的值,当发送数据寄存器为空的时候,TBE寄存器会被硬件置1,主机接受从机应答信号,此时发送数据成功,BTC标志位会被硬件置1

        设置STOP:当数据发送完成,这个时候要停止IIC通信,设置STOP也就是发送停止信号。

#硬件IIC接收流程

        硬件IIC,接收数据跟发送数据过程大致相同, 设置START   清除SBSEND  清除ADDEND  读取字节数据  清除ACKEN   设置STOP 。下面只介绍不同的部分。

        在此设置START:这里其实信号发送之前,硬件IIC必须是空闲状态才能发送,负责没有办法进行下一步。

        读取数据字节:RBNE标志位,当接收数据寄存器中,如果有数据,会将RBNE自动硬件置1,这个时候通过读取标志位信息,停止发送信息,防止数据溢出。取出寄存器里面的数据之后,通过使能ACK应答位,硬件会自动发送,这个时候从机才会继续发送数据。

#软件IIC实验

            硬件IIC通常来说不为常用,一般通过软件IIC进行通信,也就是通过控制GPIO引脚电平,模拟IIC通信时序,电平。

#宏定义 IIC引脚  调用函数

       使用宏定义,去写代码,这种函数是能够提升程序的执行速度,因为宏定义是预处理指令,在程序执行前,开始执行的,如果是将函数在次封装在调用,这种程序执行速度是比不上,宏定义函数,宏定义常量的。

#define RCU_SCL          RCC_AHB1Periph_GPIOB
#define PORT_SCL         GPIOB
#define GPIO_SCL         GPIO_Pin_6#define RCU_SDA          RCC_AHB1Periph_GPIOB
#define PORT_SDA         GPIOB
#define GPIO_SDA         GPIO_Pin_7#define SDA_IN()  {SHT20_MODE_SET( GPIO_Mode_IN  );}  //SDA输入模式
#define SDA_OUT() {SHT20_MODE_SET( GPIO_Mode_OUT );}  //SDA输出模式#define SCL(BIT)  GPIO_WriteBit(PORT_SCL, GPIO_SCL, BIT)
#define SDA(BIT)  GPIO_WriteBit(PORT_SDA, GPIO_SDA, BIT)
#define SDA_GET() GPIO_ReadInputDataBit(PORT_SDA, GPIO_SDA)
void SHT20_GPIO_INIT(void)
{GPIO_InitTypeDef  GPIO_InitStructure;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_SCL;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;GPIO_Init(PORT_SCL, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_SDA;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;GPIO_Init(PORT_SDA, &GPIO_InitStructure);
}

        这里使用了宏定义常量 重定义了函数,同时初始化了 GPIO 引脚 用它作为 IIC通信数据线。

#配置IIC通信时序

void IIC_Start(void)
{SDA_OUT();SCL(0);SDA(1);SCL(1);delay_us(5);SDA(0);delay_us(5);SCL(0);delay_us(5);}
void IIC_Stop(void)
{SDA_OUT();SCL(0);SDA(0);SCL(1);delay_us(5);SDA(1);delay_us(5);}
void IIC_Send_Ack(uint8_t ack)
{SDA_OUT();SCL(0);SDA(0);delay_us(5);if(!ack) SDA(0);else         SDA(1);SCL(1);delay_us(5);SCL(0);SDA(1);
}
uint8_t IIC_Wait_Ack(void)
{char ack = 0;unsigned char ack_flag = 10;SDA_IN();SDA(1);delay_us(5);SCL(1);delay_us(5);while( (SDA_GET()==1) && ( ack_flag ) ){ack_flag--;delay_us(5);}if( ack_flag <= 0 ){IIC_Stop();return 1;}else{SCL(0);SDA_OUT();}return ack;
}
void IIC_Write(uint8_t data)
{int i = 0;SDA_OUT();SCL(0);//拉低时钟开始数据传输for( i = 0; i < 8; i++ ){SDA( (data & 0x80) >> 7 );delay_us(2);data<<=1;delay_us(6); SCL(1);delay_us(4);SCL(0);delay_us(4);}
}

uint8_t IIC_Read(void)
{unsigned char i,receive=0;SDA_IN();//SDA设置为输入for(i=0;i<8;i++ ){SCL(0);delay_us(5);SCL(1);delay_us(5);receive<<=1;if( SDA_GET() ){        receive|=1;   }delay_us(5); }                return receive;
}

        上面配置了IIC通信时序,接下来,根据温度湿度公式,计算实际温度还是湿度定义函数输出即可。

#配置温度湿度函数

float SHT20_Read(uint8_t regaddr)
{        unsigned char data_H = 0;unsigned char data_L = 0;float temp = 0;IIC_Start();IIC_Write(0x80|0);if( IIC_Wait_Ack() == 1 ) printf("error -1\r\n");IIC_Write(regaddr);if( IIC_Wait_Ack() == 1 ) printf("error -2\r\n");do{delay_us(10);IIC_Start();IIC_Write(0x80|1);}while( IIC_Wait_Ack() == 1 );delay_us(20);data_H = IIC_Read();IIC_Send_Ack(0);data_L = IIC_Read();IIC_Send_Ack(1);IIC_Stop();if( regaddr == 0xf3 ){temp = ((data_H<<8)|data_L) / 65536.0 * 175.72 - 46.85;}if( regaddr == 0xf5 ){temp = ((data_H<<8)|data_L) / 65536.0 * 125.0 - 6;}return temp;}
int main(void)
{    board_init();uart1_init(115200U);//引脚初始化SHT20_GPIO_INIT();//等待传感器上电初始化完成delay_ms(20);while(1){//采集温度printf("temp = %.2f\r\n", SHT20_Read(0xf3) );//采集湿度printf("humi = %.2f\r\n", SHT20_Read(0xf5) );printf("\r\n");delay_ms(500);}
}

 ⁠​‬​‍​‍‬​‍‌‍⁠​​‬‌‬​‬​‍‌​‬​⁠‍‌‌​​‍​​​​​‬​‌⁠​                  【立创·天空星STM32F407VET6】入门手册 - 飞书云文档 (feishu.cn)

                                     欢迎指正,希望对你,有所帮助!!!

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

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

相关文章

pytest使用报错(以及解决pytest所谓的“抑制print输出”)

1. 测试类的类名问题 #codingutf-8import pytestclass TestClass1:def setup(self) -> None:print(setup)def test_01(self) -> None:print(test_01111111111111111111111)def test_02(self) -> None:print(test_02)以上述代码为例&#xff0c;如果类名是Test开头&am…

Chair Footrest Protective Cover

Chair Footrest Protective Cover 万能通用型椅子脚垫保护套凳子耐磨硅胶加厚垫桌椅脚垫防滑静音套

【代码随想录算法训练Day60】卡码网107.寻找存在的路径

Day60 图论第五天 卡码网107.寻找存在的路径 #include <iostream> #include <vector> using namespace std;int n; // 节点数量 vector<int> father vector<int> (101, 0); // 按照节点大小定义数组大小// 并查集初始化 void init() {for (int i 1…

windows10/11 不小心删除卓越性能模式后再次开启卓越性能模式,显示无法创建新的电源方案 指定的电源方案、子组或设置不存在。

出现这个问题可能是因为系统中缺少必要的电源计划或权限不足。可以按照以下步骤尝试解决&#xff1a; 检查权限&#xff1a;确保你以管理员身份运行命令提示符或PowerShell。 恢复默认电源计划&#xff1a; 打开命令提示符&#xff08;以管理员身份运行&#xff09;&#xff0…

Docker逃逸CVE-2019-5736、procfs云安全漏洞复现,全文5k字,超详细解析!

Docker容器挂载procfs 逃逸 procfs是展示系统进程状态的虚拟文件系统&#xff0c;包含敏感信息。直接将其挂载到不受控的容器内&#xff0c;特别是容器默认拥有root权限且未启用用户隔离时&#xff0c;将极大地增加安全风险。因此&#xff0c;需谨慎处理&#xff0c;确保容器环…

java多线程之ThreadLocal详解

ThreadLocal 一、ThreadLocal概述二、ThreadLocal解决并发时的线程不安全问题三、ThreadLocal的工作原理 一、ThreadLocal概述 ThreadLocal 是一个线程变量工具类。主要用于将私有线程和该线程存放的副本对象做一个映射&#xff0c;各个线程之间的变量互不干扰&#xff0c;例如…

我使用HarmonyOs Next开发了b站的首页

1.实现效果展示&#xff1a; 2.图标准备 我使用的是iconfont图标&#xff0c;下面为项目中所使用到的图标 3. 代码 &#xff08;1&#xff09;Index.ets&#xff1a; import {InfoTop} from ../component/InfoTop import {InfoCenter} from ../component/InfoCenter import…

Mxnet转Onnx 踩坑记录

0. 前言 使用将MXNET模型转换为ONNX的过程中有很多算子不兼容&#xff0c;在此对那些不兼容的算子替换。在此之前需要安装mxnet分支v1.x版本作为mx2onnx的工具&#xff0c;git地址如下&#xff1a; mxnet/python/mxnet/onnx at v1.x apache/mxnet GitHub 同时还参考了如下…

【postgresql】 基础知识学习

PostgreSQL是一个高度可扩展的开源对象关系型数据库管理系统&#xff08;ORDBMS&#xff09;&#xff0c;它以其强大的功能、灵活性和可靠性而闻名。 官网地址&#xff1a;https://www.postgresql.org/ 中文社区&#xff1a;文档目录/Document Index: 世界上功能最强大的开源…

PHP期末复习题

一、选择题 1&#xff0e;在下面&#xff08; A &#xff09;文件夹里面能找到Apache服务器的配置文件。 A&#xff0e;conf B&#xff0e; bin C&#xff0e;error D&#xff0e; data 2&#xff0e;取余数运算符的符号是&#xff08; B &#xff09;。 A. &a…

python 高级技巧 0706

python 33个高级用法技巧 列表推导式 简化了基于现有列表创建新列表的过程。 squares [x**2 for x in range(10)] print(squares)[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]字典推导式 用简洁的方式创建字典。 square_dict {x: x**2 for x in range(10)} print(square_dict){0…

数据结构1:C++实现边长数组

数组作为线性表的一种&#xff0c;具有内存连续这一特点&#xff0c;可以通过下标访问元素&#xff0c;并且下标访问的时间复杂的是O(1)&#xff0c;在数组的末尾插入和删除元素的时间复杂度同样是O(1)&#xff0c;我们使用C实现一个简单的边长数组。 数据结构定义 class Arr…

web零碎知识2

不知道我的这个axios的包导进去没。 找一下关键词&#xff1a; http请求协议&#xff1a;就是进行交互式的格式 需要定义好 这个式一发一收短连接 而且没有记忆 这个分为三个部分 第一个式请求行&#xff0c;第二个就是请求头 第三个就是请求体 以get方式进行请求的失手请求…

Vatee万腾平台:智慧生活的无限可能

在科技日新月异的今天&#xff0c;我们的生活正被各种智能技术悄然改变。从智能家居到智慧城市&#xff0c;从个人健康管理到企业数字化转型&#xff0c;科技的力量正以前所未有的速度渗透到我们生活的每一个角落。而在这场智能革命的浪潮中&#xff0c;Vatee万腾平台以其卓越的…

JavaWeb学习------Servlet

目录 request用法response用法sessionServletContext对象 request用法 -常用方法 String uname request.getParameter(); String[] hobbys request.getParameter("hobby");if(hobby ! null && hobby.length > 0) {for ( String hobby : hobbys) {Syst…

Swagger php注解常用语法梳理

Swagger php注解常用语法梳理 快速编写你的 RESTFUL API 接口文档工具&#xff0c;通过注释定义接口和模型&#xff0c;可以和代码文件放置一起&#xff0c;也可以单独文件存放。 Swagger 优势 通过代码注解定义文档&#xff0c;更容易保持代码文档的一致性模型复用&#xff0…

K8S集群应用国产信创适配实战经验总结

1.信创适配背景 信创国产化是在当前全球化和科技快速发展的背景下提出的。随着信息技术的快速发展&#xff0c;国内对科技产品和服务的需求日益增长&#xff0c;同时&#xff0c;国际局势的动荡和贸易环境的变化也凸显了自主可控和国产化的重要性。此外&#xff0c;国内政策对数…

C++(Qt)-GIS开发-QGraphicsView显示瓦片地图简单示例

C(Qt)-GIS开发-QGraphicsView显示瓦片地图简单示例 文章目录 C(Qt)-GIS开发-QGraphicsView显示瓦片地图简单示例1、概述2、实现效果3、主要代码4、源码地址 更多精彩内容&#x1f449;个人内容分类汇总 &#x1f448;&#x1f449;GIS开发 &#x1f448; 1、概述 支持多线程加…

【十三】图解 Spring 核心数据结构:BeanDefinition 其二

图解 Spring 核心数据结构&#xff1a;BeanDefinition 其二 概述 前面写过一篇相关文章作为开篇介绍了一下BeanDefinition&#xff0c;本篇将深入细节来向读者展示BeanDefinition的设计&#xff0c;让我们一起来揭开日常开发中使用的bean的神秘面纱&#xff0c;深入细节透彻理解…

什么是设计模式以及常见的例子(如单例、工厂、观察者等)

设计模式&#xff08;Design Pattern&#xff09;是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式的主要目的是为了可重用代码、让代码更容易被他人理解、提高代码的可靠性。设计模式一般包含模式名称、问题、目的、解决方案、效果等基本要…