基于单片机的数字温度计设计

系统简介

数字温度计系统是一种快速直观的检测环境温度的设备,用于快速生成生活中对周围环境温度检测的设备,它也是快速提高各个测温效率的必要设备之一。为了满足生活中对数字温度计的这一需求,本文设计了一款精度高、可靠性高、操作简便的数字温度计系统。
本文利用STM32单片机控制DS18B20感温芯片,结合8段数码管、独立按键模块完成数字温度计功能,该系统不仅可以实时直观检测当前环境温度而且提供设置温度上限和下限,在超过温度上限或者降低到温度下限以后,报警灯开始闪烁。
通过对本系统的测试,结果表明本设计很好地实现了数字测温显示功能和超限报警功能。成熟的DS18B20模块增加了系统的稳定性,它不需经过模拟信号与数字信号的转换,只需要三线就可以完成温度的采集,简化了外围电路。高效的32位单片机STM32增加该系统的可扩展性。该系统不仅可以单独应用于生活中测量温度,还可以和其他模块连接起来组成一个全新的、更加高端的系统,例如恒温大棚温控系统,温度检测联动报警系统等。

1 整体方案设计

1.1 主控芯片类型选择
数字温度计系统可以使用一个主控制器来完成,在各项资料的收集与对比之后总结出本系统可供选择的控制方案有单片机控制和DSP控制,具体方案如下:
方案一:系统可以使用单片机作为主控芯片,单片机是一种虽然小但很完整的芯片,应用在集成电路中,也可以称之为微型计算机系统。它包括RAM、CPU、ROM、中断控制器,定时器和I/O模块,更先进的单片机还包括PWM、SPI、AD、IIC等电路[1]。在工业控制中,单片机已经应用在多个场景,以其强大的系统处理能力和稳定性著称。
方案二:系统能够采用DSP作为主控芯片,DSP即数字信号处理器,是一种研究用数字对信号进行分析,转换,滤波,检测,调制,解调和高速算法的元件。数字处理器的主要功能是完成各模块之间的通信,主要包括上电自举,键盘读取值,音频编码芯片和LCD屏幕初始化,以及通过LCD屏幕指示数字编解码芯片的运行状态。将音频数字信号存储在闪存中。
综上,DSP的运行速度很快,但其控制算法相对复杂。而单片机的系统的控制方法相对简单,且可靠性高、价格较低、功耗低,虽然单片机相比DSP功能比较简单,但是完全满足本设计需求。本设计考虑到后续的功能扩展,应选取高性能、低成本、低功耗的单片机。单片机系统功能强大,调试简便,可以很方便的组成测温系统。采用单片机作为本设计的控制部分,后续可以基于单片机高性能进行功能性扩展,比如一些恒温大棚温控系统中自动送风大型无刷电机精准控制驱动,工业节点温度检测回传系统等等,因此本设计选用单片机作为主控芯片。
1.2 测温电路选择
测温系统即对周围环境的温度进行收集并且传递至单片机,因为环境温度并不是恒定的温度,所以对于测温元件的要求会比较高,本测温电路可供选择的有光敏电阻测温电路和DS18B20测温模块控制方式,具体方案如下:
方案一:可以使用热敏电阻一类的温感效应器件,利用其某个参数会随着温度变化进行变化的特性,如电压或者电流,通过A/D转换后进入单片机处理从而可以得到对应的温度值[2],此方案需要用到A/D转换芯片,需要考虑模拟量在整个系统可靠性以及抗干扰能力,以及单片机运算能力,调试的功能点多,温度误差大等缺点。
方案二:可以使用DS18B20温测芯片,通过单线协议,在规定时序下即可读取温度值,DS18B20为全数字温度转换和输出芯片[3],先进的单总线数据通信。单线协议使外围电路简单只需要一根数据两个电源线即可完成温度的采集。
两种方案都可以读取到当前环境的温度值,但很容易看出方案二的DS18B20温测芯片实现起来更为简单,经过比较,第二种方案测量的温度数值比较稳定,所以选择方案二为测温电路更为合适。
1.3 系统总体方案
数字温度计系统要求实现实时温度的采集显示和监测。按照设计的要求,系统可分为三个部分,即对于温度数据的采集部分、对于温度检测的报警部分、对于数据的显示部分。其中的数据采集是运用单片机通过单线协议读取测温芯片数据,采集数据后通过显示部分对环境进行显示,方便用户读取实时温度,温度检测报警部分通过独立按键设置温度门限值,实时对比环境温度和门限温度,超出门限温度后控制LED闪烁报警。
本设计具体的系统方案如图1.1所示。

图1.1 系统设计方案

2 系统的硬件电路设计

2.1 单片机系统设计
2.1.1 单片机型号的选择
为了保证系统更好更快的运行,应该选择性价比高,可靠性高,低功耗的控制器。由于温度测量需要掉电保护来防止温度测量时出现太大误差,所以需要使用掉电存储数据的时候可以直接使用单片机内部的存储,因此应选择含有2k字节的EEPROM存储的单片机。基于此有以下方案可供选择:
方案一:使用STC89C51单片机作为主控制器。它采用8051内核,它是一个8位通用CPU外加一些闪存单元组成。用户代码可以通过串行通信口下载到芯片中,成本低是它的一个优势。
方案二:使用MSP430混合信号处理器作为它的主控单元,它是一个16位能量消耗超低的精简指令集[5] 的CPU。一般来说,需要使用电池供电的设备仪表使用该系列的单片机。开发难度一般比较大、价格稍微贵些。
方案三:使用STM32F103C8T6单片机作为主控单元,STM32F103是以低功耗、高性能、高稳定性32位的CONTESTM3内核的单片机,满足高稳定系和后续处理复杂控制的可扩展性。
MSP430单片机价格稍微贵些,且属于16位CPU,STC89C51单片机开发难度较低但是满足不了复杂程度高的处理,STM32系列单片机价格低,性能出众满足设计所需,因此本系统使用STM32系列单片机。
2.1.2 单片机的引脚说明
本设计是以STM32F103C8T6为最小系统作为主控单元,主要引脚说明见表2.1。它将所有的引脚以插针形式全部引出,板载晶振和复位逻辑,采用3.3V供电。该封装在焊接的时候可以采用一个IC插座进行先焊接然后焊接完成后再将芯片插到IC插座上这样做方便更换单片机单元。STM32F103一共具有48只引脚,其中可以用来控制的引脚有32个分别是PA0-15、PB0-15、PC13-15。这些引脚默认都可以当做GPIO来使用,可输入可输出,在这些引脚上同时也提供了第二功能,比如SPI,IIC,AD等等。

图2.1 STM32封装形式

表2.1 单片机引脚功能

引脚 功能
PA12 普通I/O口,与DS18B20相连
PA11 普通I/O口输入,与按键相连
PA10 普通I/O口,与DS18B20相连
PA9 普通I/O口输出,与LED相连
PA8 普通I/O口,与ISD4004相连
PB13 IPU(上拉输入口),上拉输入
PB12 OD(开漏输出口),开漏输出
2.1.3 单片机的最小系统
一个芯片的最小系统主要包括电源电路、晶振电路、复位电路和调试电路。
本设计中STM32单片机的工作电压在3.3V可以正常工作。电源部分使用的是5V电源适配器,通过一个mini USB口供给最小系统使用。
在晶振电路中使用了两个无源晶振,8MHZ晶振是给HSE用,主时钟,32.768KHZ晶振是外部低频晶振,用于计时或者系统在待机低功耗时使用。两个晶振通过输入端两个负载电容进入单片机,如图2.2。

图2.2 晶振电路
复位电路分为手动按键复位和上电自动复位。如图2.3所示,电容器C2两端的电压在上电时不会快速变化。此时,电容器的负端子连接到RST,并且电压全部施加到电阻器R2,RESET输入高电平,芯片复位。由于之后3.3V直流电源对电容供电,导致电阻两端电压不断降低,直到变为0的时候芯片开始照常工作。有一个与电容器C2并联的复位按钮,当它没有被按下的时候,系统完成上电复位。在系统照常工作后,可以通过按钮使RST引脚变为高电平,完成手动复位。

图2.3复位电路
调试电路采用SWD模式,其中只使用4根线就可以很方便的通过JLINK调试器进行在线调试程序,原理图如图2.4

图2.4 SWD调试电路
图2.5为STM32单片机最小系统的电路图。

图2.5 单片机最小系统
2.2 显示模块设计
2.2.1 显示器件的选择
数字温度计为了方便用户读取当前实时温度,直观的展现出温度数据需要通过显示器件将温度信息显示出来,温度信息占用两位数字,不用太过复杂的显示器件,显示器件可以有以下选择:
方案一:使用LCD1602液晶显示屏[4]作为用于显示的设备。LCD1602液晶显示器将最多32个字母分成两行显示,也称为文字液晶显示器,显示数字、字母、符号或文字。LCD1602液晶显示器由大量的位图字符构成,每个位图字符可以显示一个字符,字符与每个位的每行分开,这称为字符间距和行间距。因此,图像在画面上不能很好地工作。而为了更完美的显示,该液晶需要采用控制器,大多使用的是HD44780,才能完成字符的功能。
方案二:使用LED数码管[5]作为系统的显示设备。其对于展示数字和字母有很好的效果,并且价位低廉。本设计显示温度只有两位数字位,因此直接将所有16位引脚可以直接接到单片机上,为了克服主控制器端口的电流输出不足问题,可以用三极管对电流进行放大后控制数码管。实现简单方便。
液晶显示屏造成资源浪费,且实现方式比较复杂,使用LED数码管可以满足本设计的功能要求。因此本系统采用LED数码管实现。
2.2.2 显示模块的工作原理
LED数码管分为共阳极和共阴极两种,共阳极就是把每位数码管的8个显示LED的正极连接到一起,用控制端把每个段的负极连接,控制端为低有效;共阴极就是讲每位数码管的8个显示LED的负极连接到一起,控制端连接每个段的正极,控制端为高有效,本设计采用共阳极设计;
因为单片机输出引脚的驱动电流太小,不足以驱动LED数码管或者驱动LED数码管太暗,就需要通过三极管增加驱动电流[6],现选型C9012 PNP型三极管,封装如2.6图所示,发射级接VCC,基级接GND,集电极接数码管公共脚。LED接线原理图如图2.7所示;

图2.6 C9012三极管封装

图2.7显示部分电路原理图
2.3 温度读取电路的设计
2.3.1 温感芯片的选择
本设计选择的单线数字温度传感器DS18B20[7]为主要的温感器件,这种器件是一种新型的“一线器件”,它适用的电压范围比较宽,外型小巧,价格经济实惠,也是世界上第一片支持一线总线接口的温度传感器,多片温度传感器还可以使用一个接口并联在一起做多点温度检测,线路简单节省逻辑电路和引线,扩展性强。
DS18B20的通常可以采用的供电方式有两种。一种是寄生电源供电方式见图2.8[8],寄生电源供电方式,DS18B20从单线信号线上汲取能量;在信号线DQ处于高电平期间把能量储存在内部电容里,信号线在低电平时,消耗电容器上的电能,工作到高电平,再对寄生电源(电容器)充电。

图2.8寄生电源供电
这种供电方式带来的好处有:
(1)电路简单,连接单一,一根线连接就可以;
(2)在进行远距离测温的时候,无需主机电源支持。
另外一种供电方式就是对外部的电源进行供电的方法,如图2.9所示,DS18B20的工作电源通过VDD引脚连接。此时,I/O线不需要强上拉,也不存在供电电流不足的问题,保证了转换精度。同时,任意数量的DS18B20传感器理论上可以连接在总线上,形成多点温度测量系统;

图2.9 外部电源方式供电
本系统采用外部电源供电方式,一是为了以后扩张多节点系统做准备,二是保证充足的电源供应,可以保证转换精度,同时工作稳定可靠,抗干扰能力强。
2.3.2 温度传感器电路设计
DS18B20的工作电源可以在3V~5.5V之间,STM32的工作电源为3.3V,同样IO支持3.3V驱动,因此可以直接将DS18B20连接到单片机的通用IO口上,虽然STM32有些IO口可以支持5V驱动电压,不过为了电路原理图简单,现用3.3V驱动方式,原理图如图2.10所示;

图2.10温度传感器电路设计
DS18B20引脚3接供电电源3.3V,引脚2(数据口)通过供电电源3.3V接入到单片机PB5上,引脚1接入电源地。

3 系统软件设计

3.1 软件开发环境的介绍
本应用程序使用Keil MDK μVision5[9]实现。Keil MDK μVision5是Keil公司对于ARM微控制器,尤其是ARM Cortex-M内核微控制器最好的一款集成开发工具。MDK-ARM包含了工业标准的Keil C编译器、宏汇编器、调试器、实时内核等组件。Keil MDK μVision5具有业行领先的ARM C/C++编译工具链,完美支持Cortex-M、Cortex-R4、ARM7和ARM9系列器件,包含世界上品牌的芯片。比如:ST、Atmel、Freescale、NXP、TI等众多大公司微控制器芯片。
3.2 系统重要函数
3.2.1 主函数设计
基本上所有的嵌入式程序都是以main()函数作为程序的入口点,main函数中最开始部分一般都是各个外围设备的初始化,然后主函数轮训处理任务。
本设计中首先对定时器、延时模块、LED数码管和按键的初始化,初始化一般是打开需要用到的资源的时钟,中断,分配GPIO等等。然后初始化DS18B20器件最后进入主轮询任务。流程图如图3.1,轮询任务中首先读取温度值,然后读取按键值并且做一些温度上下限的温度调节,再然后就是现实控制逻辑。

图3.1 系统流程图
3.2.2 显示函数的设计
8段数码管的显示的分为共阳极和共阴极两种方式。它们区别就是在输出口低有效还是高有效,只要在控制端取反既可以相互通用。显示控制提供三个接口函数,这三个接口函数分别是引脚初始化、温度高位显示字符、温度低位显示字符:
void c8ledInit(void);
void updateChar0(u8 numb);
void updateChar1(u8 numb);
对于显示接口,入口参数只需要输入0-15即可在相应位置上显示十六进制0到F字符,输入16为空值,LED数码管全部熄灭。函数内部通过预制映射数组查找入口参数的LED显示数值,通过GPIO_WriteBit函数写入到相应的引脚实现;
初始化参数主要是初始化LED引脚对应的GPIO值。设置为强推输出模式等。
3.2.3 读取温度模块设计和温控报警实现
DS18B20温度传感器采用的“一线协议”,连接结构简单,但是通信要求有严格的时序。其实我们可以大概分为两个周期:第一个周期首先是复位、紧接着就是跳过ROM的指令、然后就是执行温度转换存储器操作指令、等待500uS温度转换时间。在此之后紧接着执行第二个周期为复位、接着是跳过ROM的指令、执行由RAM存储器接收的操作指令、读数据,流程图见图3.2;

图3.2 流程图
读取到温度数据以后,首先转变为高低位调用显示接口将温度显示到LED数码管上,同时判断当前温度是否在温度上下限内,如果超出上下限后,温度显示将开始闪烁提示温度超出设置温度。

4 系统调试

4.1 系统硬件测试
在系统的焊接过程中,上电前需要对系统进行开路和短路测试,尤其是电源的两极是不是有短路现象,找出一些具有方向的元件,查看是否有设计和焊接出错的。需要将实物电路板对照着原理图,首先检查每一个器件的位置以及焊接时候是否虚焊的地方。然后对于短路、短路、虚焊这些情况,只能采用仪器进行测量,如数字万用表,将数字万用表打到蜂鸣档,检测短路、断路、虚焊。
在使用万用表检测时,将数字万用表打到蜂鸣档,如果红笔和黑笔出现短路,万用表就会给出嘟嘟提示,根据这个原理可以用来检测电路短路、断路、虚焊。在需要检测元件或电线两端是否连接有两支笔时,蜂鸣器的声音是正常的,反之异常。
确认硬件没有问题以后就可以上电,注意观察电流值,如果电流值过大肯定电路板有短路的地方,用手可以触碰一下芯片,如果瞬间发热严重也代表有问题。
系统硬件调试遇到的问题:
(1)DS18B20过热
初次上电后,发现DS18B20芯片瞬间发热严重,断电检查电路发现官方器件原理图画法有问题,特别容易让用户搞反1脚和3脚,重新焊接问题解决。所以在画原理图部分时候一定要仔细核对各个引脚的相对位置。
(2)测温距离过短
在项目初期测温时测温距离过短,与设计预期相差甚远,后经过查阅资料发现连接DS18B20的总线电缆长度有限。当电缆每米扭转次数越多,通信距离越远。因此,在设计使用DS18B20的远程温度测量系统时,要充分考虑母线分布电容与阻抗的匹配问题。
4.2 系统软件测试
系统软件用Keil5集成开发工具编写,Keil5集成开发工具可以连接JLINK ARM调试工具,通过SWD调试口可以非常方便的进行系统软件在线调试。SWD调试口为串行线调试口,我们常见的JTAG有20pin接口,拥有太多的Pin接口自然会会导致PCB布线会非常麻烦,而支持SWD接口调试,只需要使用4个Pin口:GND、3.3V、SWIO、SWCLK。
程序同样可以通过SWD调试口下载到单片机中。
系统软件调试主要遇到以下问题:
(1)DS18B20双向口实时切换问题。
GPIO可以设置IO方向,在51单片机,如果需要输入则直接给引脚赋值1即可读取引脚数据,对于STM32单片机来说,如果是双向口,就不可以这样处理,最开始DS18B20一直没有发现回应,数据口是双向的,必须要随着逻辑变化GPIO口的方向,通过查找资料,用寄存器赋值方式简化了切换方向的方式,解决了问题。
(2)DS18B20返回信号问题。
在DS18B20测温程序设计过程中,系统向DS18B20发出温度转换的命令之后,程序通常会等待来自DS18B20的返回信号。但是如果DS18B20中有不不恰当的接触或错误的断线,会在读DS18B20时无法接收到返回信号,程序就会陷入死循环,不能继续进行。因此,调试前应该仔细检查硬件的连接。

图4.1 软件调试成功图

附录1 总体原理图设计

附录2 源程序清单

#include “stm32f10x.h”
#include “main.h”
#include “timer2.h”
#include “c8LedShow.h”
#include “delay.h”
#include “ds18b20.h”
#include “key.h”

void systemInit()
{
timer2_init(); //初始化定时器2,提供运行时间判断
c8ledInit(); //8段数码管初始化
KEY_Init(); //IO初始化
}
short temperature;
u32 lsRdTempTime = 0;
u32 lsShowTempTime = 0;
u8 lsJustSta = 0;
u16 showTime_h = 0;
u16 showTime_l = 0;
int main(void)
{
int hVal,lVal;
u8 t;
//延时函数初始化
delay_init();
//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
//系统初始化
systemInit();
//DS18B20初始化
while(DS18B20_Init())
{
delay_ms(200);
delay_ms(200);
}
lsRdTempTime = timer2_getCurTime();
lsShowTempTime = timer2_getCurTime();
while(1)
{
justThreshold();
//100ms延时进入读取一次温度
if(timer2_getInterval(lsRdTempTime) >= 100)
{
lsRdTempTime = timer2_getCurTime();
temperature=DS18B20_Get_Temp();
}
//如果现在是调整温度高阈值
if(g_tempJust == JUST_HSHOLD)
{
hVal = g_tempHshold/10;
lVal = (g_tempHshold – hVal10);
showTime_h = 300;
showTime_l = 300;
}
//如果现在是调整温度低阈值
else if(g_tempJust == JUST_LSHOLD)
{
hVal = g_tempLshold/10;
lVal = (g_tempLshold – hVal
10);
showTime_h = 300;
showTime_l = 300;
}
//在在正常显示模式
else
{
int temp = temperature/10;
hVal = temp/10;
lVal = (temp – hVal*10);
//如果超出温度阈值,则进行闪烁显示温度
if((temp > g_tempHshold) || (temp < g_tempLshold))
{
showTime_h = 100;
showTime_l = 100;
}
else
{
showTime_h = 300;
showTime_l = 0;
}
}
//if(g_tempJust != JUST_NJUST)
//显示控制电路
{
if(showTime_l == 0)
{
updateChar0(hVal);
updateChar1(lVal);
}
//300ms亮 100ms灭
//设置亮的时间
else if((lsJustSta == 0) &&(timer2_getInterval(lsShowTempTime) >= showTime_h)) //100ms定时处理
{
updateChar0(16);
updateChar1(16);
lsJustSta = 1;
lsShowTempTime = timer2_getCurTime();
}
//设置灭的时间
else if((lsJustSta == 1) &&(timer2_getInterval(lsShowTempTime) >= showTime_l))
{
updateChar0(hVal);
updateChar1(lVal);
lsJustSta = 0;
lsShowTempTime = timer2_getCurTime();
}
}

}

}

作者:qq_2083558048

物联沃分享整理
物联沃-IOTWORD物联网 » 基于单片机的数字温度计设计

发表回复