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

[复制链接]
4090|10
 楼主| 公羊子丹 发表于 2024-10-12 08:08 | 显示全部楼层 |阅读模式

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的SCLSDA连接到STM32的相应I2C引脚,UART连接到PC,通过串口调试助手接收温度数据。

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

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

  4. // LM75 I2C地址
  5. #define LM75_ADDR 0x90

  6. // I2C读取温度函数
  7. float Read_Temperature(void)
  8. {
  9.     uint8_t temp_data[2];
  10.     int16_t temp;
  11.     HAL_I2C_Master_Receive(&hi2c1, LM75_ADDR, temp_data, 2, HAL_MAX_DELAY);
  12.     temp = (temp_data[0] << 8) | temp_data[1];
  13.     return (float)temp / 256.0;
  14. }

  15. int main(void)
  16. {
  17.     HAL_Init();
  18.     SystemClock_Config();
  19.     MX_I2C1_Init();
  20.     MX_USART1_UART_Init();
  21.    
  22.     while (1)
  23.     {
  24.         float temperature = Read_Temperature(); // 读取温度
  25.         char buffer[50];
  26.         sprintf(buffer, "Temperature: %.2f C\r\n", temperature);
  27.         HAL_UART_Transmit(&huart1, (uint8_t*)buffer, strlen(buffer), HAL_MAX_DELAY);
  28.         HAL_Delay(1000); // 每秒输出一次温度
  29.     }
  30. }
2. 串口初始化代码
  1. void MX_USART1_UART_Init(void)
  2. {
  3.     huart1.Instance = USART1;
  4.     huart1.Init.BaudRate = 9600;
  5.     huart1.Init.WordLength = UART_WORDLENGTH_8B;
  6.     huart1.Init.StopBits = UART_STOPBITS_1;
  7.     huart1.Init.Parity = UART_PARITY_NONE;
  8.     huart1.Init.Mode = UART_MODE_TX_RX;
  9.     huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  10.     huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  11.     if (HAL_UART_Init(&huart1) != HAL_OK)
  12.     {
  13.         Error_Handler();
  14.     }
  15. }
3. I2C初始化代码
  1. void MX_I2C1_Init(void)
  2. {
  3.     hi2c1.Instance = I2C1;
  4.     hi2c1.Init.ClockSpeed = 100000;
  5.     hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
  6.     hi2c1.Init.OwnAddress1 = 0;
  7.     hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  8.     hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  9.     hi2c1.Init.OwnAddress2 = 0;
  10.     hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  11.     hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  12.     if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  13.     {
  14.         Error_Handler();
  15.     }
  16. }
4. 系统时钟配置
  1. void SystemClock_Config(void)
  2. {
  3.     RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  4.     RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  5.     RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  6.     RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  7.     RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  8.     RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  9.     RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  10.     RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  11.     if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  12.     {
  13.         Error_Handler();
  14.     }

  15.     RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  16.                                 |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  17.     RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  18.     RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  19.     RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  20.     RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  21.     if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  22.     {
  23.         Error_Handler();
  24.     }
  25. }

代码说明
  • 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 | 显示全部楼层
这个比单总线的用起来方便
您需要登录后才可以回帖 登录 | 注册

本版积分规则

208

主题

6622

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部