写点什么

基于 51 单片机设计的热敏电阻测温系统

作者:DS小龙哥
  • 2024-08-07
    重庆
  • 本文字数:3460 字

    阅读完需:约 11 分钟

一、项目介绍

当前文章介绍基于 51 单片机的热敏电阻测温系统的设计过程,用于实时监测环境温度,并在温度超过预设阈值时进行报警。由于采用的是热敏电阻测温技术,无需外置温度传感器,使得系统具有结构简单、成本较低等优点。


主控芯片采用 STC89C52,具有良好的稳定性和可靠性,适应于工业控制等领域的应用需要。ADC 采集模块采用 PCF8591 模块,可方便地实现对热敏电阻温度数据的转换和采集,提高了系统的准确度和实用性。


系统通过 4 位数码管显示出温度值,同时通过按键设置温度上限阀值,当温度超过阀值时,会通过蜂鸣器报警,提醒用户注意环境温度的变化情况。


在项目中主要是用到了热敏电阻和 PCF8591 模块。


(1)热敏电阻介绍


热敏电阻(Thermistor)是一种基于材料的电阻元件,其电阻值随温度的变化而发生相应的变化。通常情况下,热敏电阻的电阻值随温度升高而降低,反之则随温度降低而升高,这种特性被称为负温度系数(NTC)或正温度系数(PTC)。


热敏电阻的工作原理是基于材料的温度敏感性质。在热敏电阻中,存在许多导电粒子,当温度升高时,导电粒子与材料中的离子激发程度增强,导致导电粒子的数量变多,因此电阻值降低;反之,当温度降低时,导电粒子的数量变少,电阻值增加。



(2)PCF8591


PCF8591 是一款 4 通道、8 位模数转换器(ADC)和 1 通道、8 位数模转换器(DAC)的集成电路芯片。可以通过 I2C 总线与微控制器进行通信,实现模拟信号的输入和输出。


PCF8591 的输入电压范围为 0V~VCC(通常为 5V),可以通过外部电阻进行放大或缩小。它还有一个内部参考电压源,可以通过软件控制选择使用。


PCF8591 的输出电压范围也是 0V~VCC,可以用于控制模拟信号的输出,比如控制电机的转速、LED 的亮度等。


在热敏电阻测温系统中,使用 PCF8591 模块来采集热敏电阻的电压信号,并将其转换为数字信号,进而计算出温度值。




二、设计思路

2.1 系统结构

系统采用单片机作为主控芯片,热敏电阻用于测量环境温度,PCF8591 模块采集热敏电阻的温度数据并将其转换为正常温度值,通过数码管进行显示。同时,系统设置上限阀值,当温度超过该值时,系统会通过蜂鸣器报警。

2.2 硬件设计

(1)主控芯片


本系统采用 STC89C52 单片机作为主控芯片,具有强大的计算能力、稳定的性能和较低的功耗,支持多种外设接口,适合于工业控制等领域的应用需求。


(2)温度传感器


本系统采用热敏电阻作为温度传感器,其结构简单、价格便宜,且无需额外的电源供应,可直接通过 PC8591 模块的输入端口进行检测。


(3)ADC 采集模块


系统采用 PCF8591 模块进行 ADC 采集,具有 4 路模拟输入通道和一个模拟输出通道,采样精度高达 8 位,能够满足本系统对温度信号的准确采集需求。


(4)数码管显示模块


系统采用 4 位共阳数码管进行数据显示,其显示范围为-999~+9999,可满足本系统对温度数据的实时显示需求。


(5)蜂鸣器报警模块


系统采用蜂鸣器进行报警提示,当温度超过预设阈值时,蜂鸣器会发出持续声响,提醒用户注意环境温度的变化情况。


(6)按键模块


按键模块,方便用户进行阀值的设置和调整操作。

2.3 软件设计

(1)温度采集与转换


系统使用 ADC 采集热敏电阻的温度信号,并将采集到的数字信号转换成温度值进行显示。转换公式为: T=(adc_value/255.0)*330,其中 adc_value 为 AD 转换器输出的数字值,330 是热敏电阻的参考电阻值。


(2)温度上限阀值设置


系统通过按键实现温度上限阀值的设置和调整操作,用户可以根据自己的需求进行设定。


(3)报警功能设计


系统在采集到温度超过预设阈值时,蜂鸣器会发出声响进行提醒,并且 LED 指示灯会亮起。

2.4 总体流程

(1)初始化各个模块,包括单片机、PCF8591、数码管、蜂鸣器和按键等。


(2)采集热敏电阻的温度信号,并将数字信号转换为温度值。


(3)将温度值通过数码管进行显示。


(4)检测当前温度是否超过预设阈值,若超过,则触发报警并点亮 LED 指示灯。


(5)用户可以通过按键设置温度上限阀值,系统会保存设置的阈值并进行下一次温度比较。

三、代码实现

以下是基于 51 单片机设计的热敏电阻测温系统的实现代码。


#include <reg52.h>#include <intrins.h>
typedef unsigned char u8;typedef unsigned int u16;
#define PCF8591_address_write 0x90#define PCF8591_address_read 0x91
sbit SCLK = P1^0; //PCF8591模块时钟线sbit DOUT = P1^1; //PCF8591模块数据线sbit DIN = P1^2; //PCF8591模块数据线sbit CS = P1^3; //PCF8591模块片选线
sbit LATCH1 = P3^4; //锁存器1sbit LATCH2 = P3^5; //锁存器2
sbit KEY1 = P2^0; //按键1sbit KEY2 = P2^1; //按键2
sbit BUZZ = P2^3; //蜂鸣器
u16 ADC_value; //采集到的ADC值float temperature; //计算得到的温度值
u8 table[] = { //共阳数码管段码表 0xc0, //0 0xf9, //1 0xa4, //2 0xb0, //3 0x99, //4 0x92, //5 0x82, //6 0xf8, //7 0x80, //8 0x90, //9 0xbf, //-};
void delay(u16 i){ while(i--);}
void delay_ms(u16 ms){ u16 i, j; for(i=0; i<ms; i++){ for(j=0; j<110; j++); }}
void write_PCF8591(u8 data){ u8 i; DIN = 1; SCLK = 0; CS = 0; for(i=0; i<8; i++){ DOUT = (data & 0x80) >> 7; data <<= 1; SCLK = 1; SCLK = 0; } CS = 1;}
u16 read_ADC(){ u16 value; CS = 0; DIN = 1; SCLK = 0; DIN = 0; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); SCLK = 1; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); value = P1; SCLK = 0; value <<= 8; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); SCLK = 1; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); value |= P1; CS = 1; return value;}
void display(u8 addr, u8 dat){ LATCH1 = 0; LATCH2 = 0; P0 = addr; LATCH1 = 1; LATCH1 = 0; P0 = table[dat]; LATCH2 = 1; LATCH2 = 0;}
void main(){ u8 set_value = 40; //温度上限阀值 u8 temp; write_PCF8591(0x40); while(1){ ADC_value = read_ADC(); temperature = (float)ADC_value * 330 / 255; temperature -= 50; if(temperature > set_value){ //温度超过上限阀值,触发报警 BUZZ = 1; } else{ BUZZ = 0; } if(temperature < -99){ temp = '-'; display(0x00, temp); display(0x01, 10); display(0x02, 10); display(0x03, 10); } else if(temperature < 0){ temp = '-'; display(0x00, temp); temp = ~(int)temperature + 1; display(0x01, temp/10); display(0x02, temp%10); display(0x03, 11); //小数点 } else if(temperature > 999){ display(0x00, 10); display(0x01, 9); display(0x02, 9); display(0x03, 9); } else{ display(0x00, temperature/100); display(0x01, temperature/10%10); display(0x02, temperature%10); display(0x03, 11); //小数点 } if(KEY1 == 0){ //按键1按下,增加上限阀值 delay_ms(10); if(KEY1 == 0){ set_value++; while(!KEY1); } } if(KEY2 == 0){ //按键2按下,减小上限阀值 delay_ms(10); if(KEY2 == 0){ set_value--; while(!KEY2); } } delay_ms(10); }}
复制代码


代码中采用了共阳数码管,通过采集热敏电阻产生的电压值,计算得到环境温度值,再通过数码管进行显示;当温度超过设定的上限值时,会触发蜂鸣器报警。可以通过按键对温度上限阀值进行设置和调整操作。


发布于: 刚刚阅读数: 5
用户头像

DS小龙哥

关注

微信公众号:DS小龙哥嵌入式技术资讯 2022-01-06 加入

所有项目文章对应的工程源码,都可以在我的微信公众号:《DS小龙哥嵌入式技术资讯》 里下载。

评论

发布
暂无评论
基于51单片机设计的热敏电阻测温系统_8月月更_DS小龙哥_InfoQ写作社区