打印
[STM32L4]

STM32L476RG:低功耗应用的理想选择—一个基于HAL库的温湿度采集系统

[复制链接]
1011|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Pulitzer|  楼主 | 2025-1-17 07:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
STMicroelectronics的STM32L476RG是一款基于ARM Cortex-M4内核的微控制器,主频高达80MHz,并具有丰富的外设和较低的功耗特点,非常适合低功耗嵌入式应用。它配备了多达1MB的闪存和128KB的SRAM,支持多个外设接口如I2C、SPI、USART等,广泛应用于物联网、可穿戴设备、传感器网络等领域。
在本文中,我们将介绍如何使用STM32L476RG微控制器,通过I2C接口读取温湿度传感器的数据,并将其通过USART串口输出,适合用于低功耗的温湿度监测系统。我们将使用STM32的HAL库进行开发。
开发环境设置
  • 安装STM32CubeIDE
    STM32CubeIDE是STMicroelectronics官方提供的集成开发环境,支持STM32系列微控制器的开发。你可以从ST官网免费下载并安装。
  • 创建新项目
    启动STM32CubeIDE,选择“File” -> “New” -> “STM32 Project”,在设备选择中选择STM32L476RG作为目标微控制器。创建新项目时,确保选择了HAL库支持,并配置了适合的系统时钟。
  • 配置I2C和USART外设
    在STM32CubeMX的“Pinout & Configuration”中,配置I2C1用于与温湿度传感器通信,配置USART1用于输出数据。
  • 配置系统时钟
    在STM32CubeMX中配置时钟源,使得MCU工作在适当的频率。
  • 生成代码并打开STM32CubeIDE
    配置完外设和时钟后,点击“Project” -> “Generate Code”,生成代码并用STM32CubeIDE打开。

温湿度传感器:DHT22我们将使用DHT22传感器进行温湿度采集。DHT22是一款常见的数字温湿度传感器,输出通过单总线(Single-Wire)接口进行通信。为了使DHT22能够与STM32通过I2C接口进行通信,我们假设传感器的接口和协议已经适配。由于DHT22不原生支持I2C,因此在本例中,我们将模拟读取DHT22的简单数据来演示过程。
编写代码我们将使用STM32的HAL库来初始化I2C和USART接口,并编写代码来采集和输出温湿度数据。
主要代码
#include "main.h"

/* Private function prototypes */
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_I2C1_Init(void);
void DHT22_Read(void);
void USART_Printf(const char *str);

/* Global variables */
UART_HandleTypeDef huart1;
I2C_HandleTypeDef hi2c1;

int main(void)
{
    /* MCU初始化 */
    HAL_Init();

    /* 配置系统时钟 */
    SystemClock_Config();

    /* 初始化外设 */
    MX_GPIO_Init();
    MX_USART1_UART_Init();
    MX_I2C1_Init();

    /* 无限循环 */
    while (1)
    {
        /* 读取温湿度传感器数据 */
        DHT22_Read();

        /* 延时1秒 */
        HAL_Delay(1000);
    }
}

/* 温湿度传感器读取函数 */
void DHT22_Read(void)
{
    uint8_t data[5];

    // 模拟读取DHT22数据
    if (HAL_I2C_Master_Transmit(&hi2c1, (0x5C << 1), data, sizeof(data), HAL_MAX_DELAY) == HAL_OK)
    {
        // 模拟传感器返回的温湿度数据
        float temperature = (float)(data[0] << 8 | data[1]) / 10.0;
        float humidity = (float)(data[2] << 8 | data[3]) / 10.0;

        /* 格式化输出温湿度数据 */
        char msg[50];
        snprintf(msg, sizeof(msg), "Temperature: %.2f C, Humidity: %.2f %%\r\n", temperature, humidity);
        USART_Printf(msg);
    }
    else
    {
        USART_Printf("I2C communication error\r\n");
    }
}

/* 串口输出函数 */
void USART_Printf(const char *str)
{
    HAL_UART_Transmit(&huart1, (uint8_t *)str, strlen(str), HAL_MAX_DELAY);
}

/* 系统时钟配置函数 */
void SystemClock_Config(void)
{
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

    /* 配置HSE外部振荡器 */
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
    RCC_OscInitStruct.HSEState = RCC_HSE_ON;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
    RCC_OscInitStruct.PLL.PLLM = 8;
    RCC_OscInitStruct.PLL.PLLN = 160;
    RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
    RCC_OscInitStruct.PLL.PLLQ = 4;
    HAL_RCC_OscConfig(&RCC_OscInitStruct);

    /* 配置系统时钟 */
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
    HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4);
}

/* GPIO初始化函数 */
static void MX_GPIO_Init(void)
{
    __HAL_RCC_GPIOA_CLK_ENABLE();
}

/* USART1初始化函数 */
static void MX_USART1_UART_Init(void)
{
    huart1.Instance = USART1;
    huart1.Init.BaudRate = 115200;
    huart1.Init.WordLength = UART_WORDLENGTH_8B;
    huart1.Init.StopBits = UART_STOPBITS_1;
    huart1.Init.Parity = UART_PARITY_NONE;
    huart1.Init.Mode = UART_MODE_TX_RX;
    huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    huart1.Init.OverSampling = UART_OVERSAMPLING_16;
    HAL_UART_Init(&huart1);
}

/* I2C1初始化函数 */
static void MX_I2C1_Init(void)
{
    hi2c1.Instance = I2C1;
    hi2c1.Init.Timing = 0x10909CEC;
    hi2c1.Init.OwnAddress1 = 0;
    hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
    hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
    hi2c1.Init.OwnAddress2 = 0;
    hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
    hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
    HAL_I2C_Init(&hi2c1);
}
代码说明
  • 初始化
    HAL_Init()函数初始化HAL库,SystemClock_Config()函数配置系统时钟。MX_GPIO_Init()、MX_USART1_UART_Init()、MX_I2C1_Init()分别用于初始化GPIO、USART和I2C外设。
  • DHT22读取
    在DHT22_Read()函数中,使用I2C接口模拟与温湿度传感器的数据交换,获取温湿度信息后通过USART串口输出。
  • 串口输出
    使用USART_Printf()函数将读取到的温湿度数据通过USART串口输出,以便调试和显示。
  • 系统时钟配置
    配置HSE(外部晶体振荡器)为系统时钟源,并设置PLL倍频,以使系统时钟达到所需的频率。

编译和烧录
  • 编译代码
    在STM32CubeIDE中点击“Build”按钮,编译项目。
  • 烧录代码
    使用ST-Link调试器或其他编程工具将代码烧录到STM32L476RG开发板。
  • 查看输出
    通过串口调试工具(如Tera Term)查看输出的温湿度数据。

总结通过以上步骤,你可以使用STM32L476RG开发板搭建一个低功耗的温湿度采集系统。该项目涉及到I2C和USART外设的配置,适合用于传感器数据采集及输出。STM32L476RG微控制器的低功耗特性使其在物联网和可穿戴设备中有着广泛的应用前景

使用特权

评论回复
沙发
公羊子丹| | 2025-1-17 07:33 | 只看该作者
STM32L476RG的低功耗特性太棒了,适合各种电池供电的应用!

使用特权

评论回复
板凳
周半梅| | 2025-1-17 07:33 | 只看该作者
用I2C与DHT22通信还是挺有挑战的,不过通过HAL库搞定了。

使用特权

评论回复
地板
帛灿灿| | 2025-1-17 07:34 | 只看该作者
这个项目特别适合做温湿度监测系统,拿来做智能家居刚刚好。

使用特权

评论回复
5
童雨竹| | 2025-1-17 07:34 | 只看该作者
之前用过STM32F103系列,L476RG的功耗优化真是提升了不少。

使用特权

评论回复
6
万图| | 2025-1-17 07:34 | 只看该作者
对于初学者来说,STM32的HAL库真的是一个好帮手,调试起来很方便。

使用特权

评论回复
7
Wordsworth| | 2025-1-17 07:34 | 只看该作者
我打算在这个基础上加个Wi-Fi模块,实现远程监控,期待效果。

使用特权

评论回复
8
Bblythe| | 2025-1-17 07:34 | 只看该作者
温湿度数据的输出格式很清晰,适合做数据分析。

使用特权

评论回复
9
Uriah| | 2025-1-17 07:35 | 只看该作者
如果可以加上一个OLED显示屏就更完美了,可以直接显示数据。

使用特权

评论回复
10
Clyde011| | 2025-1-17 07:35 | 只看该作者
我看到这篇文章后准备用STM32L476RG做一个温湿度监测仪,感谢分享!

使用特权

评论回复
11
Amazingxixixi| | 2025-1-21 17:19 | 只看该作者
学习一下啊,还有好多需要学习的。

使用特权

评论回复
12
SophiaOP| | 2025-1-22 21:36 | 只看该作者
现在好多智能家居的

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

37

主题

3909

帖子

0

粉丝