【STM32 HAL库】IIC通信与CubeMX配置

news2024/11/13 9:24:21

【STM32 HAL库】IIC通信与CubeMX配置

  • 前言
  • 理论
    • IIC总线时序图
    • IIC写数据
    • IIC读数据
  • 轮询模式
    • CubeMX配置
    • 应用示例
      • AHT20初始化
      • 初始化函数
      • 读取说明
      • 读取函数
  • 中断模式
    • CubeMX配置
    • 状态机图
    • fsm.c
    • aht20.c
  • DMA模式
    • CubeMX配置
    • 代码

前言

本文为笔者学习 IIC 通信的总结,基于keysking的视频内容,如有错误,欢迎指正

理论

在这里插入图片描述

IIC总线时序图

在这里插入图片描述

IIC写数据

在这里插入图片描述

IIC读数据

在这里插入图片描述

通信流程(以AHT20为例)

  • STM32主机)发送 IIC 启动信号
  • STM32 发送 AHT20(从机)地址
  • AHT20 识别地址并发送 ACK 信号
  • AHT20 发送数据至 STM32(发送完1 字节后结束
  • STM32 发送 ACK 信号表示接收完成
  • STM32重复接收下一个字节
  • 直至AHT20数据发送完成,STM32 发送 IIC 结束信号

IIC vs 串口通信:

  • IIC为半双工,串口为全双工

  • IIC 可支持多设备通信: IIC通信为总线协议,总线上每个从机都有唯一的地址,主机IIC通信先发送从机地址,非目标从机会忽略数据

  • 同步通信: STM32 的晶振提供统一时钟源,为IIC总线上的从机提供统一时钟信号(尤其可为无晶振提供精确时钟信号的小型传感器提供精确的同步时钟信号

  • 轮询模式:CPU持续搬运数据,程序执行被阻塞

  • 中断模式:CPU只在搬运数据时介入,正常情况下不阻塞程序

  • DMA模式:DMA自动搬运数据,无需CPU介入,节省资源

轮询模式

以AHT20温湿度传感器为例

CubeMX配置

在这里插入图片描述

应用示例

AHT20初始化

在这里插入图片描述

初始化函数

#include "aht20.h"
#define AHT20_ADDRESS 0x70

void AHT20_Init() {
    uint8_t readBuffer;	//定义读缓冲器
    HAL_Delay(40);  // 上电后等待40ms
    HAL_I2C_Master_Receive(&hi2c1, AHT20_ADDRESS, &readBuffer, 1, HAL_MAX_DELAY);  // 读取AHT20 1字节状态字 判断AHT20当前状态

    if ((readBuffer & 0x08) == 0x00) {  // 检查状态字的 Bit[3] 是否为 1
        uint8_t sendBuffer[3] = {0xBE, 0x08, 0x00};  // 初始化命令(初始化指令+初始化参数
        HAL_I2C_Master_Transmit(&hi2c1, AHT20_ADDRESS, sendBuffer, 3, HAL_MAX_DELAY);  // 发送初始化命令
    }
}

ps:
1.AHT20 地址定义为 0x70,实际为 7 位地址,左移 1 位后补 1 位用于区分读/写操作(0 表示写,1 表示读)。
2.I²C 的发送与接收函数先发送从机地址,待从机应答后再发送"发送"或"接收"请求。因此,初始化函数中的接收操作是在发送 AHT20 地址后,接收其状态字。

读取说明


AHT20数据存放形式
除去IIC硬件地址外,一共6个字节的数据:1字节状态字,3.5字节湿度数据,3.5字节温度数据
在这里插入图片描述
信号转换
在这里插入图片描述

读取函数

AHT20读取温湿度数据函数

void AHT20_Read(float *Temperature, float *Humidity) {
    uint8_t sendBuffer[3] = { 0xAC, 0x33, 0x00 };	//发送缓冲区存放"触发测量"命令+参数
    uint8_t readBuffer[6];	//定义接收缓冲区(6个字节,6*8bits,分别对应状态、湿度数据1、湿度数据2、湿度和温度数据3、温度数据4、温度数据5.共6字节

    HAL_I2C_Master_Transmit(&hi2c1, AHT20_ADDRESS, sendBuffer, 3, HAL_MAX_DELAY);	//发送"触发测量"命令,AHT20开始测量
    HAL_Delay(75);//等待75ms待测量完成
    HAL_I2C_Master_Receive(&hi2c1, AHT20_ADDRESS, readBuffer, 6, HAL_MAX_DELAY);

	//判断状态字(readbuffer[0]的Bit[7]是否为0,也即状态字的第八位(最高位)是否为0)
    if ((readBuffer[0] & 0x80) == 0x00) {
        uint32_t data = 0;	//32位data用来存放20位的湿度数据和温度数据

        // 计算湿度(位运算,拼接数据)
        data = ((uint32_t)readBuffer[3] >> 4) + ((uint32_t)readBuffer[2] << 4) + ((uint32_t)readBuffer[1] << 12);
        *Humidity = data * 100.0f / (1 << 20);	//相对湿度转换

        // 计算温度(位运算拼接数据)
        data = (((uint32_t)readBuffer[3] & 0x0F) << 16) + ((uint32_t)readBuffer[4] << 8) + (uint32_t)readBuffer[5];
        *Temperature = data * 200.0f / (1 << 20) - 50;	//温度转换
    }
}

中断模式

基本原理同串口的中断模式发送
但,因为I2C通信协议的复杂性多步骤的工作流程使得状态机成为管理I2C中断与DMA模式的有效手段
仅依赖发送和接收完成的中断嵌套,没有标志位的参与,也难以完成逻辑处理,所以状态机是必须的

CubeMX配置

在这里插入图片描述

以AHT20温湿度传感器为例

状态机图

在这里插入图片描述
状态机标志位

// 0: 初始状态 发送测量命令 1: 正在发送测量命令 2: 测量命令发送完成 等待75毫秒后读取AHT20数据 3: 读取中 4: 读取完成 解析并展示数据然后恢复到初始状态
uint8_t aht20State = 0;		//定义并初始化aht20初始状态为初始状态

fsm.c

void fsm(void)
{
	switch(aht20State)
		case 0:		//向aht20发送测量命令,并切换状态为发送中
			aht20_measure();
			aht20State = 1;
			break;
		case 1:		//发送中状态不执行任何操作,待发送完成后在中断回调函数中切换状态
			break;
		case 2:		//发送完成状态下,延时75ms后发送"获取aht20温湿度数据",开始接收aht20的温湿度数据,并切换状态为读取中
			HAL_Delay(75);
			aht20_get();
			aht20State = 3;
			break;
		case 3:		//读取中状态不执行任何操作,待读取完成后在中断回调函数中切换状态
			break;			
		case 4:		//读取完成状态时,进行aht20的温湿度数据解析,并发送给上位机。延时1s后切换状态为初始状态
			AHT20_Analysis(&temperature, &humidity);
			sprintf(message, "温度: %.1f ℃, 湿度: %.1f %%\r\n", temperature, humidity);
			HAL_UART_Transmit(&huart2, (uint8_t*)message, strlen(message), HAL_MAX_DELAY);

			HAL_Delay(1000);
			aht20State = 0;
			break;		
}

void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c) {
    if (hi2c == &hi2c1) {
        aht20State = 2;		//在发送完成中断中实现状态切换
    }
}

void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c) {
    if (hi2c == &hi2c1) {
        aht20State = 4;		//在接收完成中断中实现状态切换
    }
}

aht20.c

将AHT20的逻辑代码拆分为最基本的功能模块,以便状态机在各个状态下执行相应任务

void aht20_measure() {
    static uint8_t sendBuffer[3] = { 0xAC, 0x33, 0x00 };
    HAL_I2C_Master_Transmit_IT(&hi2c1, AHT20_ADDRESS, sendBuffer, 3);
}

void aht20_get() {
    HAL_I2C_Master_Receive_IT(&hi2c1, AHT20_ADDRESS, readBuffer, 6);
}

void aht20_analysis(float *Temperature, float *Humidity) {
    if ((readBuffer[0] & 0x80) == 0x00) {
        uint32_t data = 0;
        data = ((uint32_t)readBuffer[3] >> 4) + ((uint32_t)readBuffer[2] << 4) + ((uint32_t)readBuffer[1] << 12);
        *Humidity = data * 100.0f / (1 << 20);

        data = (((uint32_t)readBuffer[3] & 0x0F) << 16) + ((uint32_t)readBuffer[4] << 8) + (uint32_t)readBuffer[5];
        *Temperature = data * 200.0f / (1 << 20) - 50;
    }
}

DMA模式

CubeMX配置

在这里插入图片描述
在这里插入图片描述

代码

只需将上述I2C中断模式收发的函数改为DMA模式收发即可
也即 IT —> DMA

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

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

相关文章

评价类——熵权法(Entropy Weight Method, EWM),完全客观评价

目录 一、 熵权法赋权代码说明1.1 介绍 二、 手把手教你运行代码2.1 数据示例2.2 可直接运行代码2.3 shangquanfa_eg_Sheet1.csv数据可视化2.4 代码运行过程截屏2.5 代码运行结果截屏2.6 对熵权法的结果分析 三、 提供的代码如何修改&#xff1f;四、 为什么确定极小化指标&…

算法:计算二叉树的最大深度(Java实现)

思路 定义问题&#xff1a; 最大深度&#xff08;或称为最大层数&#xff09;是从根节点到最远叶子节点的路径上的节点数。我们需要找到这个最长路径的节点数。 递归的基本思路&#xff1a; 对于每个节点&#xff0c;我们需要计算其左子树的最大深度和右子树的最大深度。节点的…

54.【C语言】 字符函数和字符串函数(strncpy,strncat,strncmp函数)

和strcpy,strcat,strcmp函数对应的是strncpy,strncat,strncmp函数 8.strncpy函数 *简单使用 cplusplus的介绍 点我跳转 翻译: 函数 strncpy char * strncpy ( char * destination, const char * source, size_t num ); 从字符串中复制一些字符 复制源(source)字符串的前num个…

Redis详细解析

Redis 什么是Redis?关系型与非关系型数据库Redis可以做什么Redis入门安装在Windows系统上安装在Linux系统上安装 Redis在Linux系统上启动运行如何设置redis-server后台运行与关闭如何设置redis客户端登录时需要验证密码**设置允许远程连接redis服务**Redis数据类型Redis常用命…

魔方财务迁移指南

本文将详细介绍如何将魔方财务系统迁移到新的服务器&#xff0c;确保您能够顺利地迁移数据和系统文件。 迁移前的准备 在开始迁移之前&#xff0c;请确保新服务器满足以下配置要求&#xff1a; 操作系统&#xff1a;CentOS/Debian/Ubuntu硬件配置&#xff1a;至少2H2G&#…

RP2040 C SDK ADC功能使用

RP2040 C SDK ADC功能使用 &#x1f33f;RP2040 ADC功能说明文档&#xff1a;https://www.raspberrypi.com/documentation/pico-sdk/hardware.html#hardware_adc &#x1f4d7;RP2040 ADC介绍 SAR ADC500 kS/s (Using an independent 48MHz clock)12 bit (RP2040 8.7 ENOB, R…

建筑资质与劳务资质的区别

在建筑行业&#xff0c;资质就像是企业的“身份证”&#xff0c;它证明了企业具备承接相应工程的能力和条件。对于刚入行的小白来说&#xff0c;可能会对建筑资质和劳务资质的区别感到困惑。别担心&#xff0c;今天我们就来聊聊这两者之间的不同。 什么是建筑资质&#xff1f; …

git push : RPC failed; HTTP 400 curl 22 The requested URL returned error: 400

git push 出现RPC failed; HTTP 400 curl 22 The requested URL returned error: 400 问题 git push Enumerating objects: 11, done. Counting objects: 100% (11/11), done. Delta compression using up to 8 threads Compressing objects: 100% (10/10), done. error: RPC …

分布式训练:(Pytorch)

分布式训练是将机器学习模型的训练过程分散到多个计算节点或设备上&#xff0c;以提高训练速度和效率&#xff0c;尤其是在处理大规模数据和模型时。分布式训练主要分为数据并行和模型并行两种主要策略&#xff1a; 1. 数据并行 (Data Parallelism) 数据并行是最常见的分布式…

数据结构之树的常用术语

二叉树的常用术语 前言 由于数组在插入、删除上的缺点和链表在查询上的缺点&#xff0c;出现了树的数据结构&#xff0c;可以在增删改查中弥补数组和链表的缺陷。 常用数据 节点&#xff1a;每个节点根节点&#xff1a;最上层的节点&#xff0c;Root节点父节点&#xff1a;相…

基于SSM的宿舍管理系统的设计与实现 (含源码+sql+视频导入教程)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 基于SSM的宿舍管理系统拥有两种角色&#xff0c;分别为管理员和宿管&#xff0c;具体功能如下&#xff1a; 管理员&#xff1a;学生管理、班级管理、宿舍管理、卫生管理、访客管理、用户…

SOT23封装1A电流LDO具有使能功能的 1A、低 IQ、高精度、低压降稳压器系列TLV757P

前言 SOT23-5封装的外形和丝印 该LDO适合PCB空间较小的场合使用&#xff0c;多数SOT23封装的 LDO输出电流不超过0.5A。建议使用时输入串联二极管1N4001,PCB布局需要考虑散热&#xff0c;参考文末PCB布局。 1 特性 • 采用 SOT-23 (DYD) 封装&#xff0c;具有 60.3C/W RθJA •…

双指针算法专题(2)

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a; 优选算法专题 想要了解双指针算法的介绍&#xff0c;可以去看下面的博客&#xff1a;双指针算法的介绍 目录 611.有效三角形的个数 LCR 1…

【天池比赛】【零基础入门金融风控 Task2赛题理解】实战进行中……20240915更新至2.3.4.3 查看训练集测试集中特征属性只有一值的特征

2.3 代码示例 2.3.1 导入数据分析及可视化过程需要的库 import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns import datetime import warnings warnings.filterwarnings(ignore) 2.3.2 读取文件 #读取数据时相对路径载入报错时…

【Redis】之Geo

概述 Geo就是Geolocation的简写形式&#xff0c;代表地理坐标。在Redis中&#xff0c;构造了能够存储地址坐标信息的一种数据结构&#xff0c;帮助我们根据经纬度来检索数据。 命令行操作方法 GEOADD 可以用来添加一个或者多个地理坐标。 GEODIST 返回一个key中两个成员之…

AgentTuning:提升大型语言模型的通用Agent能力

人工智能咨询培训老师叶梓 转载标明出处 大模型被用作现实中复杂任务的Agent时&#xff0c;它们的表现往往不如商业模型&#xff0c;如ChatGPT和GPT-4。这些任务要求LLMs作为中央控制器&#xff0c;负责规划、记忆和工具利用&#xff0c;这就需要精巧的提示方法和鲁棒性强的LL…

华为的仓颉和ArkTS这两门语言有什么区别

先贴下官网&#xff1a; ArkTs官网 仓颉官网 ArkTS的官网介绍说&#xff0c;ArkTS是TypeScript的进一步强化版本&#xff0c;简单来说就是包含了TS的风格&#xff0c;但是做了一些改进。 了解TypeScript的朋友都应该知道&#xff0c;其实TypeScript就是JavaScript的改进版本&…

基于springboot 自习室预订系统 前后端分离

基于springboot 自习室预订系统 前后端分离 目 录 摘 要 I Abstract II 第1章 前 言 2 1.1 研究背景 3 1.2 研究现状 3 1.3 系统开发目标 3 第2章 系统开发环境 5 2.1 java技术 5 2.2 Mysql数据库 6 2.3 B/S结构 7 2.4 springboot框架 7 2.5 ECLIPSE 开发环境 7 …

Redis的配置与优化

目录 一、关系数据库与非关系型数据库 1.1、关系型数据库 1.2、非关系型数据库 1.3、关系型数据库和非关系型数据库区别 数据存储方式不同 扩展方式不同 对事务性的支持不同 1.4、非关系型数据库产生背景 二、Redis简介 2.1、Redis优点 2.2、Redis为什么这么快 三、…

CefSharp_Vue交互(Element UI)_WinFormWeb应用---设置应用透明度(含示例代码)

一、界面预览 1.1 设置透明(整个页面透明80%示例) 限制输入值:10-100(数字太小会不好看见) 1.2 vue标题栏 //注册类与js调用 (async function(