【蓝桥杯——物联网设计与开发】拓展模块3 - 温度传感器模块

news2024/12/26 19:26:53

目录

一、温度传感器模块

(1)资源介绍

        🔅原理图

        🔅STS30-DIS-B

        🌙引脚分配

        🌙通信

        🌙时钟拉伸(Clock Stretching)

        🌙单次触发模式

        🌙温度数据转换

(2)STM32CubeMX 软件配置

(3)代码编写

(4)实验现象

二、温度采集接口函数封装

三、踩坑日记

(1)引脚配置问题

(2)底层驱动延时问题

(3)ALERT引脚


一、温度传感器模块

(1)资源介绍

        🔅原理图

        蓝桥杯物联网竞赛实训平台提供了一个拓展接口 CN2,所有拓展模块均可直接安装在 Lora 终端上使用;

图1        拓展接口

        温度传感器模块电路原理图如下所示:

图2        温度传感器模块电路原理图

        通过两张电路图连接可知,引脚资源配置情况为:

表1 引脚资源配置情况
TemperatureMCU
SCLPB6
SDAPB7
ALEPB0

        🔅STS30-DIS-B

        (以下资料来源于STS30-DIS-B数据手册)

        STS3x-DIS是盛思锐最新的高精度数字温度传感器。它依赖于业界成熟的CMOSens®技术,与其前身相比,提供更高的智能,可靠性和更高的精度规格。其功能包括增强的信号处理,两个独特的用户可选择的I2C地址和高达1 MHz的通信速度。DFN封装的占地面积为2.5 x 2.5 mm2,同时保持0.9 mm的高度。这允许将STS3x-DIS集成到各种各样的应用中。此外,2.15 V至5.5 V的宽电源电压范围保证了广泛应用的兼容性。总而言之,STS3x-DIS融合了盛思锐超过15年的数字传感器专业知识。

图3        STS30-DIS 功能框图
        🌙引脚分配
表2 STS30-DIS-B引脚分配
PinNameComments
1SDA串行数据;输入/输出
2ADDR

地址引脚;输入;连接到逻辑高或低,不要浮空

3ALERT指示警告状态;输出;如果不使用,必须保持浮空
4SCL串行时钟;输入/输出
5VDD电源电压;输入
6nRESET复位引脚,低电平有效;输入;如果不使用,建议保持浮空状态;可通过串联电阻R≥2kΩ与VDD连接
7R无电气功能;连接到VSS
8VSS接地
        🌙通信

        向传感器发送命令后,在传感器接收另一条命令之前,需要最小的等待时间为1ms

        所有STS30-DIS-B命令和数据都映射到16位地址空间。此外,数据和命令受到CRC校验和的保护。这提高了通信的可靠性。对传感器的16位命令已经包括3位CRC校验和。传感器发送和接收的数据总是经过一个8位的CRC校验。

  • 在写方向上,必须传输校验和因为STS30-DIS-B只接受后面跟着正确校验和的数据
  • 在读方向上,它留给主机来读取和处理校验和;
        🌙时钟拉伸Clock Stretching
  • 当没有时钟拉伸的命令发出时,如果没有数据存在,传感器响应一个带有不确认(NACK)的读报头;
  • 当发出带有时钟拉伸的命令时,传感器响应一个带有ACK的读报头,然后拉下SCL线。将SCL线拉下,直到测量完成。一旦测量完成,传感器释放SCL线并发送测量结果;
        🌙单次触发模式
图4        单次触发模式下的命令

由图4的流程图可知,单次触发模式的数据获取流程如下:

        1. 第一部分

图5        发送流程第一部分

🟠️伪代码如下:

I2C开始;
发送7位I2C地址+写命令位;
等待传感器发送ACK;
发送高8位命令;
等待传感器发送ACK;
发送低8位命令;
等待传感器发送ACK;
I2C结束;

        2. 第二部分

图6        发送流程第二部分

🟠️伪代码如下:

/* 时钟拉伸不使能 */
释放时钟线;(传感器测量中)
I2C开始;
发送7位I2C地址+读命令位;
等待传感器发送NACK;
I2C结束;
释放时钟线;(传感器测量中->传感器测量完成)
I2C开始;
发送7位I2C地址+读命令位;
等待传感器发送ACK;


/* 时钟拉伸使能 */
释放时钟线;(传感器测量中)
I2C开始;
发送7位I2C地址+读命令位;
等待传感器发送ACK;
(传感器将时钟线拉低)

        3. 第三部分

图7        发送流程第三部分

🟠️伪代码如下:

接收高8位温度数据;
发送ACK;
接收低8位温度数据;
发送ACK;
接收CRC校验和;
发送NACK;
I2C结束;
        🌙温度数据转换

T\left [ ^{\circ}C \right ]=-45+175\cdot \frac{S_{T}}{2^{16}-1}

T\left [ ^{\circ}F \right ]=-49+315\cdot \frac{S_{T}}{2^{16}-1}

(2)STM32CubeMX 软件配置


🔅“工程建立、时钟树配置、Debug 串行线配置、代码生成配置” 在下文中有讲解,这里不再赘述❗️

【蓝桥杯——物联网设计与开发】基础模块1- GPIO输出icon-default.png?t=O83Ahttps://blog.csdn.net/m0_63116406/article/details/135604705?spm=1001.2014.3001.5502

1️⃣点击引脚 PB6 → 选择 GPIO_Output 模式(此处默认为推挽输出);

     点击引脚 PB7 → 选择 GPIO_Output 模式(此处配置为开漏输出);

图8        引脚配置



2️⃣初始化 OLED;(配置步骤在下文中有讲解,这里不再赘述);

【蓝桥杯——物联网设计与开发】基础模块6 - OLED_蓝桥杯物联网oled-CSDN博客


3️⃣生成代码即可;

(3)代码编写

🟢️main 函数

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */
uint8_t H_VALUE, L_VALUE, CRC_VALUE;    // 高8位数据、低8位数据、CRC校验数据
float temp;                            // 温度数据
uint16_t ui_dat_temp;                    // 显示数据
uint8_t puc_oled[17];                    // OLED显示存储区
/* USER CODE END PV */
/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_I2C3_Init();
  /* USER CODE BEGIN 2 */
	OLED_Init();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* 第一部分 */
	I2CStart2();
	I2CSendByte2(0x94);
	I2CWaitAck2();
	I2CSendByte2(0x24);
	I2CWaitAck2();
	I2CSendByte2(0x0B);
	I2CWaitAck2();
	I2CStop2();
	/* 第二部分 */
	HAL_Delay(2);
	I2CStart2();
	I2CSendByte2(0x95);
	I2CWaitAck2();
	I2CStop2();
	HAL_Delay(2);
	I2CStart2();
	I2CSendByte2(0x95);
	I2CWaitAck2();
    /* 第三部分 */
	H_VALUE = I2CReceiveByte2();
	I2CSendAck2();
	L_VALUE = I2CReceiveByte2();
	I2CSendAck2();
	CRC_VALUE = I2CReceiveByte2();
	I2CSendNotAck2();
	I2CStop2();
	if(CRC_VALUE)
	{
		;
	}
	temp = ((H_VALUE << 8) | L_VALUE) * 175.0 / 65535 - 45;
    ui_dat_temp = (uint16_t)(Temp_Read() * 10);
	sprintf((char*)puc_oled, "   Temperature  ");
	OLED_ShowString(0, puc_oled);
	sprintf((char*)puc_oled, "      %.1f  ", ui_dat_temp / 10.0);
	OLED_ShowString(2, puc_oled);
    HAL_Delay(500);    //延时一会儿
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

(4)实验现象

        能够实时测量环境温度。


二、温度采集接口函数封装

🟡️软件i2c.c

#include "i2c_2.h"

#define DELAY_TIME 20

//I2C总线内部延时函数
static void delay1(unsigned int n)
{
    uint32_t i;
    for ( i = 0; i < n; ++i);
}

//配置SDA引脚为输入模式
void SDA_Input_Mode2(void)
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	GPIO_InitStruct.Pin = SDA2;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
//配置SDA引脚为输出模式
void SDA_Output_Mode2(void)
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	GPIO_InitStruct.Pin = SDA2;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
//SDA引脚输出
void SDA_Output2(uint16_t val )
{
	if(val)
		GPIOB->BSRR |= SDA2;
	else
		GPIOB->BRR |= SDA2;
}
//SCL引脚输出
void SCL_Output2( uint16_t val )
{
	if(val)
		GPIOB->BSRR |= SCL2;
	else
		GPIOB->BRR |= SCL2;
}
//读取SDA引脚状态
uint8_t SDA_Input2(void)
{
	return HAL_GPIO_ReadPin(GPIOB, SDA2);
}

//I2C总线启动信号
void I2CStart2(void)
{
    SDA_Output2(1);
    delay1(DELAY_TIME);
    SCL_Output2(1);
    delay1(DELAY_TIME);
    SDA_Output2(0);
    delay1(DELAY_TIME);
    SCL_Output2(0);
    delay1(DELAY_TIME);
}

//I2C总线停止信号
void I2CStop2(void)
{
    SCL_Output2(0);
    delay1(DELAY_TIME);
    SDA_Output2(0);
    delay1(DELAY_TIME);
    SCL_Output2(1);
    delay1(DELAY_TIME);
    SDA_Output2(1);
    delay1(DELAY_TIME);

}

//等待应答
unsigned char I2CWaitAck2(void)
{
    unsigned short cErrTime = 5;
    SDA_Input_Mode2();
    delay1(DELAY_TIME);
    SCL_Output2(1);
    delay1(DELAY_TIME);
    while(SDA_Input2())
    {
        cErrTime--;
        delay1(DELAY_TIME);
        if (0 == cErrTime)
        {
            SDA_Output_Mode2();
            I2CStop2();
            return ERROR;
        }
    }
    SCL_Output2(0);
    SDA_Output_Mode2();
    delay1(DELAY_TIME);
    return SUCCESS;
}

//发送应答
void I2CSendAck2(void)
{
    SDA_Output2(0);
    delay1(DELAY_TIME);
    delay1(DELAY_TIME);
    SCL_Output2(1);
    delay1(DELAY_TIME);
    SCL_Output2(0);
    delay1(DELAY_TIME);

}

//发送非应答
void I2CSendNotAck2(void)
{
    SDA_Output2(1);
    delay1(DELAY_TIME);
    delay1(DELAY_TIME);
    SCL_Output2(1);
    delay1(DELAY_TIME);
    SCL_Output2(0);
    delay1(DELAY_TIME);

}

//发送一个字节数据
void I2CSendByte2(unsigned char cSendByte)
{
    unsigned char  i = 8;
    while (i--)
    {
        SCL_Output2(0);
        delay1(DELAY_TIME);
        SDA_Output2(cSendByte & 0x80);
        delay1(DELAY_TIME);
        cSendByte += cSendByte;
        delay1(DELAY_TIME);
        SCL_Output2(1);
        delay1(DELAY_TIME);
    }
    SCL_Output2(0);
    delay1(DELAY_TIME);
}

//接收一个字节数据
unsigned char I2CReceiveByte2(void)
{
    unsigned char i = 8;
    unsigned char cR_Byte = 0;
    SDA_Input_Mode2();
    while (i--)
    {
        cR_Byte += cR_Byte;
        SCL_Output2(0);
        delay1(DELAY_TIME);
        delay1(DELAY_TIME);
        SCL_Output2(1);
        delay1(DELAY_TIME);
        cR_Byte |=  SDA_Input2();
    }
    SCL_Output2(0);
    delay1(DELAY_TIME);
    SDA_Output_Mode2();
    return cR_Byte;
}

🟡️软件i2c.h

#ifndef __I2C_2_H
#define __I2C_2_H

#include "main.h"
//I2C总线引脚定义
#define SCL2	GPIO_PIN_6
#define SDA2	GPIO_PIN_7

//接口函数
void I2CStart2(void);
void I2CStop2(void);
unsigned char I2CWaitAck2(void);
void I2CSendAck2(void);
void I2CSendNotAck2(void);
void I2CSendByte2(unsigned char cSendByte);
unsigned char I2CReceiveByte2(void);

#endif

🟡️温度采集函数

/* 温度采集函数,中等可重复性+不使能时钟拉伸 */
float Temp_Read(void)
{
	uint8_t H_VALUE, L_VALUE, CRC_VALUE;
	float temp;
	I2CStart2();
	I2CSendByte2(0x94);
	I2CWaitAck2();
	I2CSendByte2(0x24);
	I2CWaitAck2();
	I2CSendByte2(0x0B);
	I2CWaitAck2();
	I2CStop2();
	HAL_Delay(2);
	
	I2CStart2();
	I2CSendByte2(0x95);
	I2CWaitAck2();
	I2CStop2();
	HAL_Delay(2);
	
	I2CStart2();
	I2CSendByte2(0x95);
	I2CWaitAck2();
	H_VALUE = I2CReceiveByte2();
	I2CSendAck2();
	L_VALUE = I2CReceiveByte2();
	I2CSendAck2();
	CRC_VALUE = I2CReceiveByte2();
	I2CSendNotAck2();
	I2CStop2();
	if(CRC_VALUE)
	{
		;
	}
	temp = ((H_VALUE << 8) | L_VALUE) * 175.0 / 65535 - 45;
	return temp;
}

🔴温度采集接口函数调用实例

/* 采集任务函数 */
void Task_Colt(void)
{
    /* 200ms进入一次 */
	if(cnt_colt < 200)	return;
	cnt_colt = 0;
    /* 温度采集与转换 */
	ui_dat_temp = (uint16_t)(Temp_Read() * 10);
}

三、踩坑日记

(1)引脚配置问题

  1. 推荐使用软件模拟I2C(硬件I2C,在4ti测试出来有问题);
  2. PB7(SDA)配置为开漏输出、速度快;PB6(SCL)配置为推挽输出,速度快;

(2)底层驱动延时问题

        🔅注意编写底层驱动时存在两次HAL_Delay(2),释放时钟线作用,根据芯片手册说明,此处需要≥1ms;

(3)ALERT引脚

        🔅报警引脚Alert一般用于连接MCU的中断引脚。引脚的输出取决于可编程限制的温度读数值。当满足报警条件时,引脚拉高;

        🔅根据手册说明,不使用时必须保持浮空。

       

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

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

相关文章

如何在任何地方随时使用本地Jupyter Notebook无需公网IP

文章目录 1.前言2.Jupyter Notebook的安装2.1 Jupyter Notebook下载安装2.2 Jupyter Notebook的配置2.3 Cpolar下载安装 3.Cpolar端口设置3.1 Cpolar云端设置3.2.Cpolar本地设置 4.公网访问测试5.结语 1.前言 今天就来给大家安利一套神器组合&#xff1a;通过Windows系统本地部…

长沙景区数据分析项目实现

一、设计题目 长沙景区数据分析项目 二、设计目的 通过本项目让学生独立完成数据统计、数据可视化、数据分析的过程&#xff0c;并提高学生解决问题的能力。 三、设计要求 读取‘长沙景区信息.xlsx’文件&#xff08;读取Excel文件的方法为pandas.read_excel()&#xff0c…

Kafka可视化工具 Offset Explorer (以前叫Kafka Tool)

数据的存储是基于 主题&#xff08;Topic&#xff09; 和 分区&#xff08;Partition&#xff09; 的 Kafka是一个高可靠性的分布式消息系统&#xff0c;广泛应用于大规模数据处理和实时, 为了更方便地管理和监控Kafka集群&#xff0c;开发人员和运维人员经常需要使用可视化工具…

PHP后执行php.exe -v命令报错并给出解决方案

文章目录 一、执行php.exe -v命令报错解决方案 一、执行php.exe -v命令报错 -PHP Warning: ‘C:\windows\SYSTEM32\VCRUNTIME140.dll’ 14.38 is not compatible with this PHP build linked with 14.41 in Unknown on line 0 解决方案 当使用PHP8.4.1时遇到VCRUNTIME140.dll…

详解MySQL在Windows上的安装

目录 查看电脑上是否安装了MySQL 下载安装MySQL 打开MySQL官网&#xff0c;找到DOWNLOADS 然后往下翻&#xff0c;找到MySQL Community(GPL) Downloads>> 然后找到MySQL Community Server 然后下载&#xff0c;选择No thanks,just start my download. 然后双击进行…

Excel粘贴复制不完整的原因以及解决方法

在数据处理和分析的过程中&#xff0c;Excel无疑是不可或缺的工具。然而&#xff0c;在使用Excel进行复制粘贴操作时&#xff0c;有时会遇到粘贴不完整的情况&#xff0c;这可能会让人感到困惑和烦恼。本文将深入探讨Excel粘贴复制不完整的原因、提供解决方案&#xff0c;并给出…

嵌入式轻量级开源操作系统:HeliOS的使用

嵌入式轻量级开源操作系统:HeliOS的使用 &#x1f4cd;项目地址&#xff1a;https://github.com/heliosproj/HeliOS HeliOS项目是一个社区交付的开源项目&#xff0c;用于构建和维护HeliOS嵌入式操作系统&#xff08;OS&#xff09;。HeliOS是一个功能齐全的操作系统&#xff0…

Linux复习3——管理文件系统2

修改文件权限命令 chmod 功能&#xff1a; chmod 命令主要用于修改文件或者目录的权限 只有文件所有者和超级用户可以修改文件或目录的权限 (1)使用数字表示法修改权限 所谓数字表示法是指将读取(r)、写入(w)和执行(x)分别以4、2、1来表示&#xff0c;没有授予的部分就表示…

ECharts散点图-气泡图,附视频讲解与代码下载

引言&#xff1a; ECharts散点图是一种常见的数据可视化图表类型&#xff0c;它通过在二维坐标系或其它坐标系中绘制散乱的点来展示数据之间的关系。本文将详细介绍如何使用ECharts库实现一个散点图&#xff0c;包括图表效果预览、视频讲解及代码下载&#xff0c;让你轻松掌握…

嵌入式驱动开发详解21(网络驱动开发)

文章目录 前言以太网框架ENET 接口简介MAC接口MII \ RMII 接口MDIO 接口RJ45 接口 PHY芯片以太网驱动驱动挂载wifi模块挂载后续 前言 linux驱动主要是字符设备驱动、块设备驱动还有网络设备驱动、字符设备驱动在本专栏前面已经详细将解了&#xff0c;网络设备驱动本文会做简要…

论文解读 | EMNLP2024 一种用于大语言模型版本更新的学习率路径切换训练范式

点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入&#xff01; 点击 阅读原文 观看作者讲解回放&#xff01; 作者简介 王志豪&#xff0c;厦门大学博士生 刘诗雨&#xff0c;厦门大学硕士生 内容简介 新数据的不断涌现使版本更新成为大型语言模型&#xff08;LLMs&#xff…

FFmpeg 的常用API

FFmpeg 的常用API 附录&#xff1a;FFmpeg库介绍 库介绍libavcodec音视频编解码核心库编码 (avcodec_send_frame, avcodec_receive_packet)。解码 (avcodec_send_packet, avcodec_receive_frame)。libavformat提供了音视频流的解析和封装功能&#xff0c;多种多媒体封装格式&…

trap命令

信号 linux信号是由一个整数构成的异步消息&#xff0c;可以由某个进程发给其他的进程&#xff0c;也可以在用户按下特定键发生某种异常事件时&#xff0c;由系统发给某个进程 信号列表 kill -l trap -l 在使用信号名时&#xff0c;需要省略SIG前缀 trap trap命令用于指定…

Visual Studio 使用 GitHub Copilot 与 IntelliCode 辅助编码 【AI辅助开发系列】

&#x1f380;&#x1f380;&#x1f380;【AI辅助编程系列】&#x1f380;&#x1f380;&#x1f380; Visual Studio 使用 GitHub Copilot 与 IntelliCode 辅助编码Visual Studio 安装和管理 GitHub CopilotVisual Studio 使用 GitHub Copilot 扩展Visual Studio 使用 GitHu…

Llama 3 模型系列解析(一)

目录 1. 引言 1.1 Llama 3 的简介 1.2 性能评估 1.3 开源计划 1.4 多模态扩展 ps 1. 缩放法则 2. 超额训练&#xff08;Over-training&#xff09; 3. 计算训练预算 4. 如何逐步估算和确定最优模型&#xff1f; 2. 概述 2.1 Llama 3 语言模型开发两个主要阶段 2.2…

【多时段】含sop的配电网重构【含分布式电源】【已更新视频讲解】

1 主要内容 之前分享了很多配电网重构的程序&#xff0c;每个程序针对场景限定性比较大&#xff0c;程序初学者修改起来难度较大&#xff0c;本次分享一个基础程序&#xff0c;针对含sop的配电网重构模型&#xff0c;含风电和光伏&#xff0c;优化了33节点网络电压合理性&…

使用 Elastic AI Assistant 简化威胁情报报告

作者&#xff1a;来自 Tommy Bumford 了解 SRE 不断扩展的角色以及所需的新技能&#xff1a;成本管理和 AI。 通过 AI 驱动的报告为分析师提供支持 在不断发展的网络安全领域&#xff0c;威胁分析师不断被新的威胁情报 (threat intelligence - TI) 数据淹没。挑战不仅在于理解…

64.基于SpringBoot + Vue实现的前后端分离-新闻资讯系统(项目 + 论文)

项目介绍 传统信息的管理大部分依赖于管理人员的手工登记与管理&#xff0c;然而&#xff0c;随着近些年信息技术的迅猛发展&#xff0c;让许多比较老套的信息管理模式进行了更新迭代&#xff0c;文章信息因为其管理内容繁杂&#xff0c;管理数量繁多导致手工进行处理不能满足广…

word无法创建工作文件,检查临时环境变量。

word无法创建工作文件&#xff0c;检查临时环境变量。 word preview版本&#xff0c;关联打开文件出现报错。word无法创建工作文件&#xff0c;检查临时环境变量。 打开注册表&#xff0c;删除键 Word Preview: HKCR\CLSID{84F66100-FF7C-4fb4-B0C0-02CD7FB668FE} PowerPoint …

人工智能ACA(七)——计算机视觉基础

一、自然语言处理基本介绍 1. 自然语言处理的定义 1-1 自然语言 人类使用的在社会生活中自然形成的语言 1-2 自然语言处理 目标是让计算机能够理解、解析、生成和处理人类的自然语言 包含自然语言理解和自然语言生成两部分组成 2. 自然语言处理的发展趋势 3.自然语言处理…