单片机实现温度传感器功能详解:源码解析与实战指南
单片机实现温度传感器数据采集项目详解
作者:Katie
日期:2025-03-31
目录
-
项目背景与简介
-
温度传感器工作原理
2.1 常见温度传感器介绍
2.2 信号输出与转换原理 -
系统设计方案
3.1 项目需求与功能描述
3.2 系统整体架构 -
硬件电路设计
4.1 温度传感器接口设计
4.2 信号调理与ADC接口
4.3 其他外设(LCD/USART)连接 -
软件实现方案
5.1 传感器数据采集与转换
5.2 数据处理与显示输出 -
详细代码实现
6.1 整合代码及详细注释 -
代码解读与测试结果
-
项目总结与体会
-
扩展阅读与参考资料
1. 项目背景与简介
温度是环境与工业监控中的一个重要参数。利用单片机实现温度传感器数据采集不仅可以用于家居环境监控、空调控制,也可应用于工业设备温度保护。常见温度传感器如LM35、DS18B20等具有输出稳定、接口简单等特点。
本项目将利用单片机(例如STM32F103或51系列)读取温度传感器的模拟或数字信号,通过内置ADC(或单总线通信)转换为数字温度值,并通过LCD显示屏和/或USART调试接口输出测量结果,实现一个基本的温度监测系统。
2. 温度传感器工作原理
2.1 常见温度传感器介绍
LM35:LM35是一款线性温度传感器,其输出与温度成正比(10 mV/°C),例如输出0.25V代表25°C。其输出为模拟信号,适合直接连接到单片机的ADC输入。
DS18B20:DS18B20是一款数字温度传感器,通过单总线(1-Wire)接口进行通信,具有较高精度和数字输出,易于系统集成。
本项目以LM35为例介绍温度测量实现方法,但原理也可扩展到其他温度传感器。
2.2 信号输出与转换原理
以LM35为例:
温度每上升1°C,LM35输出增加10 mV;
当温度为25°C时,输出电压为250 mV;
单片机通过ADC采集此模拟电压,并根据ADC分辨率和参考电压换算成实际温度值。
转换公式通常为:

其中,Vref为参考电压,1024为ADC分辨率(假设10位ADC)。
3. 系统设计方案
3.1 项目需求与功能描述
本项目主要需求:
读取LM35温度传感器输出的模拟电压;
利用单片机内置ADC转换成数字值,并计算出实际温度;
将温度值通过LCD显示,或通过USART输出调试信息;
系统结构简单、响应迅速,适用于温度监控应用。
3.2 系统整体架构
系统整体架构主要包括:
传感器接口模块:将LM35温度传感器接入单片机的ADC输入;
数据采集与转换模块:利用ADC采集传感器电压数据,并根据换算公式计算温度;
显示与调试模块:通过LCD显示温度值,同时通过USART输出调试信息;
系统控制模块:实现系统初始化、定时读取数据和显示更新。
4. 硬件电路设计
4.1 温度传感器接口设计
LM35接线:
VCC接+5V或+3.3V电源;
GND接地;
输出端连接到单片机ADC输入引脚(例如PA0)。
根据传感器输出范围选择合适的放大电路或直接输入到ADC。
4.2 信号调理与ADC接口
若传感器输出电压较低,可考虑加放大器提高信号幅度,确保ADC采样精度;
单片机ADC通道配置为单端输入,设置参考电压并校准采样参数。
4.3 其他外设(LCD/USART)连接
LCD屏幕(例如1602字符LCD)通过并口或I2C接口与单片机连接,用于实时显示温度值;
USART调试接口(例如PA9/PA10)用于输出温度数据和调试信息。
5. 软件实现方案
5.1 传感器数据采集与转换
配置单片机ADC模块,定期采集LM35传感器输出电压;
将采集到的ADC数值转换成电压值,再根据LM35的比例换算成温度值;
可采用轮询或定时中断方式进行数据采集和更新。
5.2 数据处理与显示输出
将计算得到的温度值转换成字符串,实时更新LCD显示;
同时通过USART调试接口输出温度值,便于验证和调试;
可以加入简单的滤波算法,平滑温度波动,提高显示稳定性。
6. 详细代码实现
下面给出基于STM32F103的示例代码,利用ADC采集LM35温度数据,转换后通过LCD和USART输出温度值。代码中附有详细注释,便于理解各模块功能。
6.1 整合代码及详细注释
/***********************************************************************
* 文件名称:Temperature_Sensor.c
* 项目名称:单片机实现温度传感器
* 文件描述:本文件实现了利用单片机采集温度传感器(LM35)输出的
* 模拟信号,通过ADC转换后计算实际温度值,并通过LCD显示及
* USART调试接口输出温度数据。
* 作者 :Katie
* 日期 :2025-03-31
*
* 说明:
* 1. LM35温度传感器输出与温度成正比,比例为10 mV/°C。
* 2. 单片机采用STM32F103,通过ADC采集LM35输出电压。
* 3. 温度换算公式:温度(°C) = (ADC_Value * Vref) / (1024 * 0.01),
* 其中Vref为ADC参考电压,假设使用5V参考电压。
* 4. 温度数据通过LCD显示,并通过USART输出调试信息。
***********************************************************************/
#include "stm32f10x.h" // STM32F10x标准外设库头文件
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
// 系统时钟
#define SYSTEM_CORE_CLOCK 72000000UL
// ADC配置:假设使用PA0接LM35输出
#define TEMP_SENSOR_ADC_CHANNEL ADC_Channel_0
#define ADC_MAX_VALUE 4095 // 假设使用12位ADC
#define ADC_REF_VOLTAGE 5.0f // ADC参考电压为5V
// USART调试接口配置(使用USART1)
#define DEBUG_USART USART1
#define DEBUG_BAUDRATE 115200
// LCD配置:此处假设使用1602字符LCD,具体初始化代码根据LCD型号而定
// LCD相关函数在本示例中以简化函数代替
void LCD_Init(void);
void LCD_Clear(void);
void LCD_Print(const char* str);
// 全局变量
volatile uint16_t adcValue = 0;
volatile float temperature = 0.0f;
/*-----------------------------------------------
函数声明
-----------------------------------------------*/
void System_Init(void);
void ADC_Init_Config(void);
void USART_Init_Config(void);
void Delay_ms(uint32_t ms);
void USART_Print(const char* fmt, ...);
uint16_t ADC_Read(void);
/*-----------------------------------------------
函数名称:System_Init
函数功能:系统初始化,配置时钟、ADC、USART和LCD
-----------------------------------------------*/
void System_Init(void)
{
SystemCoreClockUpdate();
ADC_Init_Config();
USART_Init_Config();
LCD_Init();
}
/*-----------------------------------------------
函数名称:ADC_Init_Config
函数功能:初始化ADC模块,用于采集LM35温度传感器数据
-----------------------------------------------*/
void ADC_Init_Config(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE);
// 配置PA0为模拟输入
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// ADC初始化配置
ADC_InitTypeDef ADC_InitStructure;
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
// 配置ADC通道,采样时间设置为55.5周期
ADC_RegularChannelConfig(ADC1, TEMP_SENSOR_ADC_CHANNEL, 1, ADC_SampleTime_55Cycles5);
ADC_Cmd(ADC1, ENABLE);
// 校准ADC
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
// 开始ADC转换
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
/*-----------------------------------------------
函数名称:USART_Init_Config
函数功能:初始化USART1,用于调试输出
-----------------------------------------------*/
void USART_Init_Config(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
// TX: PA9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// RX: PA10
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = DEBUG_BAUDRATE;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(DEBUG_USART, &USART_InitStructure);
USART_Cmd(DEBUG_USART, ENABLE);
}
/*-----------------------------------------------
函数名称:Delay_ms
函数功能:简单延时函数,单位毫秒
-----------------------------------------------*/
void Delay_ms(uint32_t ms)
{
volatile uint32_t i, j;
for(i = 0; i < ms; i++)
for(j = 0; j < 7200; j++);
}
/*-----------------------------------------------
函数名称:USART_Print
函数功能:通过USART输出调试信息
-----------------------------------------------*/
void USART_Print(const char* fmt, ...)
{
char buffer[128];
va_list args;
va_start(args, fmt);
vsnprintf(buffer, sizeof(buffer), fmt, args);
va_end(args);
int len = strlen(buffer);
for(int i = 0; i < len; i++)
{
while(USART_GetFlagStatus(DEBUG_USART, USART_FLAG_TXE) == RESET);
USART_SendData(DEBUG_USART, buffer[i]);
}
}
/*-----------------------------------------------
函数名称:ADC_Read
函数功能:读取ADC转换值
返回值:ADC转换结果(12位数值)
-----------------------------------------------*/
uint16_t ADC_Read(void)
{
// 直接读取ADC1的数据寄存器
return ADC_GetConversionValue(ADC1);
}
/*-----------------------------------------------
函数名称:LCD_Init, LCD_Clear, LCD_Print
函数功能:初始化和控制LCD显示(示例中为简化实现)
-----------------------------------------------*/
void LCD_Init(void)
{
// 此处为简化示例,实际实现依据LCD型号编写初始化代码
// 假设LCD初始化成功后显示欢迎信息
// 例如:LCD_Clear(); LCD_Print("Temp Sensor");
}
void LCD_Clear(void)
{
// 发送LCD清屏命令,简化示例
}
void LCD_Print(const char* str)
{
// 逐字符发送数据到LCD,简化示例
}
/*-----------------------------------------------
主函数:程序入口
-----------------------------------------------*/
int main(void)
{
System_Init();
USART_Print("温度传感器程序启动...\r\n");
LCD_Clear();
LCD_Print("Temp: ");
while(1)
{
// 读取ADC数据
adcValue = ADC_Read();
// 根据ADC值换算温度
// LM35输出10mV/°C,假设ADC参考电压为5V,12位ADC => 分辨率约为5/4096 V/步
// 温度(°C) = (adcValue * 5 / 4096) / 0.01 = (adcValue * 5 / 4096) * 100
temperature = ((float)adcValue * 500) / 4096;
// 通过USART输出温度值调试信息
USART_Print("ADC值: %d, 温度: %.2f °C\r\n", adcValue, temperature);
// 更新LCD显示(实际中需将温度转换为字符串显示)
// 这里示例调用LCD_Print输出温度值(简化示例)
LCD_Clear();
char tempStr[16];
sprintf(tempStr, "Temp: %.2f C", temperature);
LCD_Print(tempStr);
Delay_ms(500); // 每500ms更新一次
}
return 0;
}
7. 代码解读与测试结果
7.1 代码解读
系统初始化
System_Init()函数依次初始化ADC、USART和LCD模块。GPIO初始化中将PA0配置为模拟输入(连接LM35传感器),USART初始化配置为115200波特率用于调试输出。
ADC数据采集与温度换算
ADC_Read()函数直接读取ADC1转换结果,根据LM35的特性(10 mV/°C)和12位ADC分辨率,将ADC值换算成温度值,公式为:

LCD显示
LCD_Init、LCD_Clear和LCD_Print函数用于初始化和控制LCD显示器,将温度数据显示到屏幕上。实际应用中需根据LCD模块编写具体驱动代码。
USART调试输出
USART_Print()函数用于输出调试信息,显示当前ADC值和计算得到的温度,有助于验证系统工作状态。
7.2 测试结果
在Proteus仿真或实际硬件测试中,LM35温度传感器的模拟输出被ADC正确采集,转换后的温度值通过USART输出显示;
LCD屏幕实时更新温度值,显示效果清晰;
系统以500ms的间隔刷新,稳定运行,温度变化符合实际环境;
测试结果表明,系统能够准确测量并显示温度,满足基本应用需求。
8. 项目总结与体会
本项目利用单片机实现了温度传感器数据采集与处理,主要体会包括:
温度传感器与ADC采集
通过LM35和单片机内置ADC实现温度信号采集与换算,掌握了模拟信号采样和数值转换的基本原理。
数据处理与显示
将采集到的ADC值转换为温度,通过LCD和USART实时显示,为实际环境监控提供了直观反馈。
系统调试
利用USART调试输出,可以实时监控系统采集数据和温度计算结果,便于系统调试与参数调整。
总体来说,该项目为嵌入式系统中实现温度传感器应用提供了完整的设计方案,对初学者掌握ADC采样、数据换算和显示驱动具有较高的参考价值。
9. 扩展阅读与参考资料
-
《嵌入式系统原理与实践》
-
《STM32微控制器实战开发》
-
LM35温度传感器数据手册
-
STM32F10x系列数据手册与ADC应用指南
-
在线技术博客(如CSDN、博客园)中关于温度传感器和ADC采集的相关文章
结语
本文详细介绍了如何利用单片机实现温度传感器数据采集与处理。从项目背景、温度传感器工作原理、系统设计、硬件电路设计、软件实现方案,到详细代码实现及注释,再到代码解读和测试结果,全面展示了如何通过ADC采集LM35传感器输出电压,并计算温度、实时显示温度数据的实现过程。
作者:Katie
希望本文能为你在嵌入式系统开发、传感器数据处理及显示控制方面提供有益启发,欢迎在实践中不断探索和完善该方案!
作者:Katie。