基于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端进行调试和监控。该项目结构清晰、功能完善,适合嵌入式系统的开发者进行快速原型设计和验证。
这个温度传感器的应用挺实用的,正好我也在用STM32做类似的项目。 串口调试输出温度值的部分写得很清楚,简单又好用! 我之前一直纠结于I2C的时序,看来HAL库的I2C用起来还是挺方便的。 这个项目功能很全,加入温度报警功能的话可以做个简单的温控系统。 STM32的I2C速度可以调更高吗?我打算用它读取多个传感器。 LM75这款传感器还挺不错,代码里解析温度值的方式简单明了。 可以把温度数据存到SD卡吗?感觉数据存储也是个常用的扩展功能。 想请教一下,在多任务系统下如何处理这个温度传感器的数据? STM32的低功耗模式你用过吗?感觉挺适合电池供电的项目。 这个比单总线的用起来方便
页:
[1]