公羊子丹 发表于 2024-10-12 08:08

基于STM32F103C8T6的温度传感器应用及代码实现


STM32F103C8T6是一款基于ARM Cortex-M3内核的32位微控制器,具有出色的性能和丰富的外设接口,非常适合用于嵌入式开发。本文将以温度传感器为例,介绍STM32F103C8T6的应用,具体包括如何使用I2C接口与温度传感器进行通信,并通过串口将数据输出。

STM32F103C8T6 简介STM32F103C8T6是一款典型的低功耗、高性能的微控制器,内置Flash和SRAM存储,支持丰富的外设如I2C、SPI、UART、ADC等,广泛应用于工业控制、消费电子和智能设备等领域。

实现功能我们将使用I2C接口读取外部温度传感器的数据,并通过UART串口输出到上位机进行调试。硬件连接上,使用常见的I2C温度传感器如LM75,其特点是能够快速精确地测量温度。

硬件连接
[*]STM32F103C8T6 MCU
[*]LM75温度传感器
[*]UART串口与PC连接
I2C的SCL和SDA连接到STM32的相应I2C引脚,UART连接到PC,通过串口调试助手接收温度数据。

软件开发环境
[*]开发工具:Keil uVision 5
[*]编程语言:C语言
[*]固件库:STM32 HAL库

代码实现1. I2C 初始化与温度读取#include "stm32f1xx_hal.h"
#include "i2c.h"
#include "usart.h"

// LM75 I2C地址
#define LM75_ADDR 0x90

// I2C读取温度函数
float Read_Temperature(void)
{
    uint8_t temp_data;
    int16_t temp;
    HAL_I2C_Master_Receive(&hi2c1, LM75_ADDR, temp_data, 2, HAL_MAX_DELAY);
    temp = (temp_data << 8) | temp_data;
    return (float)temp / 256.0;
}

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_I2C1_Init();
    MX_USART1_UART_Init();
   
    while (1)
    {
      float temperature = Read_Temperature(); // 读取温度
      char buffer;
      sprintf(buffer, "Temperature: %.2f C\r\n", temperature);
      HAL_UART_Transmit(&huart1, (uint8_t*)buffer, strlen(buffer), HAL_MAX_DELAY);
      HAL_Delay(1000); // 每秒输出一次温度
    }
}
2. 串口初始化代码void MX_USART1_UART_Init(void)
{
    huart1.Instance = USART1;
    huart1.Init.BaudRate = 9600;
    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;
    if (HAL_UART_Init(&huart1) != HAL_OK)
    {
      Error_Handler();
    }
}
3. I2C初始化代码void MX_I2C1_Init(void)
{
    hi2c1.Instance = I2C1;
    hi2c1.Init.ClockSpeed = 100000;
    hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
    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;
    if (HAL_I2C_Init(&hi2c1) != HAL_OK)
    {
      Error_Handler();
    }
}
4. 系统时钟配置void SystemClock_Config(void)
{
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
    RCC_OscInitStruct.HSEState = RCC_HSE_ON;
    RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
    RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    {
      Error_Handler();
    }

    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |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;

    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
    {
      Error_Handler();
    }
}

代码说明
[*]I2C通信:使用STM32 HAL库的I2C接口与LM75温度传感器进行数据通信。通过调用HAL_I2C_Master_Receive函数读取温度传感器的数据,处理后转换为摄氏度。

[*]UART串口通信:通过HAL_UART_Transmit将温度数据通过串口发送到PC,以便在串口调试工具上显示温度。

[*]系统时钟配置:为确保I2C和UART通信的时序,正确配置系统时钟是至关重要的。

[*]代码结构:主循环中每隔1秒读取温度传感器的温度值,并通过串口输出。


功能扩展
[*]温度报警功能:可以根据温度范围设置报警阈值,当温度超出预定值时,点亮指示灯或发送报警信号。

[*]低功耗模式:通过STM32的低功耗模式,在非必要时间段降低功耗,延长电池寿命。

[*]多传感器应用:通过扩展I2C总线,可以读取多个温度传感器的数据,适用于环境监测或多点温度采集。


总结STM32F103C8T6作为一款高性能低功耗的MCU,具备丰富的I2C和UART等外设资源,能够很好地完成与传感器的通信和数据传输。通过简单的代码实现,可以方便地将温度数据实时发送到PC端进行调试和监控。该项目结构清晰、功能完善,适合嵌入式系统的开发者进行快速原型设计和验证。

周半梅 发表于 2024-10-12 10:52

这个温度传感器的应用挺实用的,正好我也在用STM32做类似的项目。

帛灿灿 发表于 2024-10-12 10:53

串口调试输出温度值的部分写得很清楚,简单又好用!

童雨竹 发表于 2024-10-12 10:53

我之前一直纠结于I2C的时序,看来HAL库的I2C用起来还是挺方便的。

万图 发表于 2024-10-12 10:54

这个项目功能很全,加入温度报警功能的话可以做个简单的温控系统。

Wordsworth 发表于 2024-10-12 10:55

STM32的I2C速度可以调更高吗?我打算用它读取多个传感器。

Pulitzer 发表于 2024-10-12 10:55

LM75这款传感器还挺不错,代码里解析温度值的方式简单明了。

Bblythe 发表于 2024-10-12 10:56

可以把温度数据存到SD卡吗?感觉数据存储也是个常用的扩展功能。

Uriah 发表于 2024-10-12 10:56

想请教一下,在多任务系统下如何处理这个温度传感器的数据?

Clyde011 发表于 2024-10-12 10:57

STM32的低功耗模式你用过吗?感觉挺适合电池供电的项目。

Stahan 发表于 2024-10-13 19:53

这个比单总线的用起来方便
页: [1]
查看完整版本: 基于STM32F103C8T6的温度传感器应用及代码实现