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

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

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

  • 前言
  • 理论
    • IIC总线时序图
    • IIC写数据
    • IIC读数据
  • 应用
    • CubeMX配置
    • 应用示例
      • AHT20初始化
      • 初始化函数
      • 读取说明
      • 读取函数

前言

本文为笔者学习 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总线上的从机提供统一时钟信号(尤其可为无晶振提供精确时钟信号的小型传感器提供精确的同步时钟信号

应用

以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;	//温度转换
    }
}


http://www.kler.cn/a/304443.html

相关文章:

  • windows运行ffmpeg的脚本报错:av_ts2str、av_ts2timestr、av_err2str => E0029 C4576
  • Spark 中 RDD 的诞生:原理、操作与分区规则
  • 学习记录:js算法(九十):N皇后
  • 网站访问在TCP/IP四层模型中的流程
  • 基于SSM(Spring + Spring MVC + MyBatis)框架的咖啡馆管理系统
  • 改进系列(3):基于ResNet网络与CBAM模块融合实现的生活垃圾分类
  • InfiniBand (IB) 和 RDMA over Converged Ethernet (RoCE)
  • S32G EB tresos AutoCore下载和激活方法
  • GSEP 7级T2真题 [202312]纸牌游戏
  • [pytorch] 训练节省显存的技巧
  • Kizuna AI——AI驱动虚拟偶像,AI分析观众的反应和互动,应用娱乐、直播和广告行业
  • Linux(RedHat或CentOS)下如何开启telnet服务
  • 【时时三省】(C语言基础)指针进阶 例题7
  • SQLITE3数据库实现信息的增删改查
  • ensp—路由过滤、路由引入、路由策略
  • 【基础知识复习 - 随机练习题】
  • 1935. 公交换乘(transfer)
  • 常用环境部署(二十)——docker部署OpenProject
  • 基于华为云服务器的网页部署
  • 【Android】使用和风天气API获取天气数据吧!(天气预报系列之一)
  • ARCGIS PRO DSK MapTool
  • 使用Azure Devops Pipeline将Docker应用部署到你的Raspberry Pi上
  • 【Hadoop|MapReduce篇】Hadoop序列化概述
  • LabVIEW FIFO详解
  • 分享六款小众宝藏软件,建议收藏!
  • golang os.Eixt的介绍和使用