使用STM8单片机+NTC热敏电阻自制简易温度巡检仪

发布者:TranquilSmile最新更新时间:2022-01-15 来源: eefocus关键字:STM8  单片机  NTC热敏电阻 手机看文章 扫描二维码
随时随地手机看文章

  最近在测试设备的时候需要监测设备的温度,平常测试时都是通过红外热成像仪测试,然后手动记录数据。这样测试的话工作量比较大,需要几分钟就记录一次数据。于是想着能不能用单片机做一个测试温度的装置,用电脑自动记录数据。手头刚好有STM8S003单片机和 5K的NTC热敏电阻,于是就做了一个简易的温度测试装置,并使用伏特加上位机软件将温度波形显示出来。


  最终测试效果如图所示:

请添加图片描述

  下面将制作步骤分享出来。


  首先设计NTC热敏电阻的采样电路。

请添加图片描述

  这里使用最简答电阻分压电路,将热敏电阻和一个10K电阻串联分压,然后将电压值直接送到单片机的AD采样口,由于热敏电阻的阻值会随着温度变化,所以送入单片机口的电压值也会随着温度变化,这样就可以通过单片机AD口采样的电压值推算出当前的温度值。


  温度采样电路设计了两路,输出的电压值分别送到单片机的AD采样口 19、20引脚,然后通过单片机的串口也就是2、3引脚将温度数据通过串口模块发送到电脑上。

在这里插入图片描述

  硬件电路很简单,连接完成图如下:

请添加图片描述

  将两路温度采样电路焊接在一个小板上,然后连接到STM8S003单片机最小系统上,USB转串口的模块也用杜邦线连接到单片机上。

  接下来开始编写代码,代码也很简单,就用到了ADC采样和串口部分。


  ADC采样代码如下:


#include "adc.h"

#include "main.h"


u16  DATAH = 0;                          //ADC转换值高8位

u16  DATAL = 0;                          //ADC转换值低8位

_Bool ADC_flag = 0;                     //ADC转换成功标志


//AD通道引脚初始化

void ADC_GPIO_Init( void )

{

    PD_DDR &= ~( 1 << 2 );              //PD2 设置为输入     电压

    PD_CR1 &= ~( 1 << 2 );              //PD2 设置为悬空输入

    PD_DDR &= ~( 1 << 3 );              //PD3 设置为输入      电流

    PD_CR1 &= ~( 1 << 3 );              //PD3 设置为悬空输入

}

//ch 为单片机的对应管脚

void ADC_CH_Init( u8 ch )

{

    char l = 0;

    ADC_CR1  = 0x00;                    //fADC = fMASTER/2, 8Mhz  单次转换,禁止转换

    ADC_CSR  = ch + 1;                  //控制状态寄存器 选择要 AD输入通道  如:PD2(AIN3)

    ADC_CR2  = 0x00;                    //默认左对齐 读数据时先读高在读低

    ADC_TDRL = ( 1 << ( ch + 1 ) );     //禁止相应通道 施密特触发功能 1左移ch+1位

    ADC_CR1 |= 0x01;                    //使能ADC并开始转换

    ADC_CSR |= 0x20;                    //EOCIE 使能转换结束中断  EOC中断使能

    for( l = 0; l < 100; l++ );         //延时,保证ADC模块的上电完成 至少7us

    ADC_CR1 = ADC_CR1 | 0x01;           //再次将CR1寄存器的最低位置1 使能ADC 并开始转换

}


//采集PD2电压值

u16 ReadVol_CH2( void )

{

    u16 voltage = 0;

    ADC_CH_Init( 2 );

    if( ADC_flag )

    {

        ADC_flag = 0;

        voltage = ( DATAH << 2 ) + DATAL ;

        ADC_CR1 = ADC_CR1 | 0x01;

    };

    return voltage;

}

//采集PD3电压值

u16 ReadVol_CH3( void )

{

    u16 voltage = 0;

    ADC_CH_Init( 3 );

    if( ADC_flag )

    {

        ADC_flag = 0;

        voltage = ( DATAH << 2 ) + DATAL ; //得到十位精度的数据  0--1024

        ADC_CR1 = ADC_CR1 | 0x01;          //再次将CR1寄存器的最低位置1  启动下一次转换

    };

    return voltage;

}


//AD中断服务函数 中断号22

#pragma vector = 24                     // IAR中的中断号,要在STVD中的中断号上加2

__interrupt void ADC_Handle( void )

{

    ADC_CSR &= ~0x80;                   // 转换结束标志位清零  EOC

    //默认左对齐 读数据时先读高高8位 再读低8位

    DATAH = ADC_DRH;                    // 读出ADC结果的高8位

    DATAL = ADC_DRL;                    // 读出ADC结果的低8位

    ADC_flag = 1;                       // ADC中断标志 置1

}


  串口相关代码如下:


#include "uart.h"

#include "stdio.h"

#include "main.h"


//在Library Options中将Printf formatter改成Large

//重新定向putchar函数,使支持printf函数

int putchar(int ch)

{

    while(!(UART1_SR&0X80));//循环发送,直到发送完毕

    UART1_DR = (u8) ch;

    return ch;

}

void Uart1_IO_Init(void)

{

    PD_DDR |= (1<<5);   //输出模式 TXD

    PD_CR1 |= (1<<5);   //推挽输出


    PD_DDR &= ~(1<<6);  //输入模式 RXD

    PD_CR1 &= ~(1<<6);  //浮空输入

}


//波特率最大可以设置为38400

void Uart1_Init( unsigned int baudrate )

{

    unsigned int baud;

    baud = 16000000 / baudrate;

    Uart1_IO_Init();

    UART1_CR1 = 0;

    UART1_CR2 = 0;

    UART1_CR3 = 0;

    UART1_BRR2 = ( unsigned char )( ( baud & 0xf000 ) >> 8 ) | ( ( unsigned char )( baud & 0x000f ) );

    UART1_BRR1 = ( ( unsigned char )( ( baud & 0x0ff0 ) >> 4 ) );

    UART1_CR2_bit.REN = 1;                      //接收使能

    UART1_CR2_bit.TEN = 1;                      //发送使能

    UART1_CR2_bit.RIEN = 1;                     //接收中断使能

}


  由于单片机只需要通过串口发送数据,而不需要接收数据,所以这里就没有串口接收相关代码。


  接下来就是最重要的部分了,需要将串口采样到的ADC值转换为对应的温度值。这里需要查阅NTC热敏电阻的资料,将热敏电阻的阻值和温度变化做成一张表,然后单片机通过查表获取温度值。

在这里插入图片描述

  在网上查找资料,找到了一张NTC热敏电阻的阻值和温度对照表,这张表中温度对应的是电阻阻值,所以还需要将NTC的阻值和单片机ADC采样值对应起来。

在这里插入图片描述

  由于采样电路是10K固定电阻和NTC分压所得。假设NTC的阻值为R,那么根据分压公式可以算出,两个电阻分压后的电压值为 Vo = 5V / (10K + R) * R ,,将热敏电阻的阻值和温度对照表复制到Excel表格中,然后根据分压公式计算出每个温度对应的分压电压值。


  由于单片机采样的AD值并不是电压值,所以还需要将计算出来的电压值转换为单片机的采样值,这里使用的单片机AD精度为10位,所以最大的采样值为2^10=1024,单片机位5V供电,使用公式 采样ADC值 = 温度电压值 / 5V * 1024,计算采样值和分压值的对应关系。可以直接在表格中使用公式计算。

在这里插入图片描述

  这样就将单片机的采样值和温度值对应起来了,为了程序编写的方便,这里温度选择直接从0度开始,0度以下的数据不考虑。

在这里插入图片描述

  将从0度开始的单片机ADC采样值存在数组中,单片机从AD口读取到数据后,在数组中查找当前采样的数据最接近数组中的哪个数据,然后对应数组的下标刚好就是温度值,比如采样值为340,那么在数组中最接近的数字就是341,而341在数组中第25位,那么当前的温度值就是25℃。

为了减小单片机的计算量,将表格中计算出来的单片机采样值统一变成整数,将转换好的整数存放在数组中。

在这里插入图片描述

  接下来在主程序中就可以读取ADC采样值,然后查表去找出对应的温度值了。主函数代码如下:


void main( void )

{

    static u16 temp1 = 100, temp2 = 200;

    static u16 value1 = 0, value2 = 0;

    u16 i = 0, j = 0;

    u32 sum = 0;


    SysClkInit();

    __asm( "sim" );                       //禁止中断

    LED_GPIO_Init();

    delay_init( 16 );

    Uart1_Init( 9600 );

    __asm( "rim" );                       //开启中断

    while( 1 )

    {

        sum = 0;

        for( i = 0; i < 16; i++ )       //测量两路温度数据

        {

            sum += ReadVol_CH3();

            delay_ms( 10 );

        }

        value1 = sum >> 4;

        temp1 = find_by_seq( tem_table, NUM, value1 );       //通过采样值查表计算对应温度值


        sum = 0;


        for( i = 0; i < 16; i++ )

        {

            sum += ReadVol_CH2();

            delay_ms( 10 );

        }

        value2 = sum >> 4;

        temp2 = find_by_seq( tem_table, NUM, value2 );       //通过采样值查表计算对应温度值



        LED = ~LED;

        printf( "%d,%d,%d,%drn", value1, value2, temp1, temp2 );


    }

}


  为了避免采样到的温度值跳变,所以这里每个通道采样16次,然后取平均值,每次采样间隔10ms。计算出采样的平均值之后,通过查找函数检测当前的采样值最接近数组中的那个数字,然后返回对应的下标。这里查找数据使用了最简单的顺序查找法。


/*

 * 顺序查找法

 * @description :   在数组中寻找和数据最接近的那个数字,并返回数字所在数组的下标

 * @param - arr :   数组首地址

 * @param - length : 数组大小

 * @param - num :   要查找的数据

 * @return :        最接近的数组所在数组下标

 *

 * 基本思路:数组按照顺序排列好之后,从数组头开始依次比较各个数据。                

 */

int find_by_seq( int *arr, int length, int num )

{

    int i;

    int min = abs( *arr - num );        // 要查找的数据和数组中第一个数字的差作为最小值

    int index = 0;


    for( i = 0; i < length; i++ )

    {

        if( abs( arr[i] - num ) < min )

        {

            min = abs( arr[i] - num );

            index = i;

        }

    }


    //return arr[index];      //返回数据

    return index;         //返回下标

}


  虽然顺序查找法效率不高,但是这个程序本身也很简单,同时外部设备温度的变化也比较缓慢,所以使用顺序查找法对系统的运行也没有多大的影响。查找的原理就是采样值依次和数组中的每个数据相减然后求绝对值,最后返回绝对值最小的数据索引。由于数组中的数据是从0度开始的,每次递增一度,所以数组的下标刚好就是温度值,不需要再进行换算。


  最后通过printf()函数将数据从串口发送到 上位机软件上,进行波形显示。在烧水器上少了一杯开水,直接将NTC热敏电阻放到水里面测试。

请添加图片描述

  在上位机软件上测试波形如下:

请添加图片描述

  逐渐上升的两条曲线是采样到的原始值,逐渐下降的两条曲线是查表后换算出来的温度值。可以将波形放大,查看实时显示的值。

请添加图片描述

  这时波形动态打印效果图。

请添加图片描述

  为了使温度看起来更方便,可以在界面上添加两个温度显示表盘。

请添加图片描述

  通过最右边的两个表盘就可以实时显示温度值,通过左边的曲线查看温度变化趋势。

请添加图片描述

  用手捏了一下热敏电阻,可以看到温度反应还是比较灵敏的。到此这个简易的温度巡检仪就算搞定了。


  还可以使用软件中的其他控件来显示温度。

请添加图片描述

  这些控件都可以在软件左侧的空间工具栏中找到。

在这里插入图片描述

关键字:STM8  单片机  NTC热敏电阻 引用地址:使用STM8单片机+NTC热敏电阻自制简易温度巡检仪

上一篇:在STM8单片机中自己实现 printf()函数功能
下一篇:如何通过map文件优化代码

推荐阅读最新更新时间:2024-11-12 11:39

基于MSP430单片机高精度温度测量的补偿方法
摘要:用MSP430P315单片机的A/D转换器,实现阻性温度传感器的电阻检测;用查表和线性插值结合的方法,简化标度变换的算法结构。对电池电压的降低进行补偿的同时分析补偿电阻的精度对温度检测的影响。 引言 长期以来,人们在测量温度时,大部分使用常规的测量方法测量。检测精度要求较高时,调理电路复杂、A/D的位数高,使设计的系统成本居高不,很难普及。随着电子技术的发展,出现了很多功能完备的低功耗、低电压大规模集成电路,为设计便携式高精度测温系统提供了硬件基础。本文介绍的高精度便携式测温仪,使用了非常适合作低功耗便携式测试设备美国TI公司的MSP430P325为控制器,用Pt500铂电阻完成温度检测,检测的温度通过液晶显示器显示。本
[单片机]
51单片机C编程(七、5个IO口扫描10个按键)
程序名称:5个IO口扫描10个按键 作 者:jumpmysoul 日 期:2009年5月22日 程序功能:用P1口的P00~P04实现10个按键的扫描,并将键值用一个数码管显示 proteus仿真电路如下: #include reg51.h #define uchar unsigned char #define uint unsigned int #define SEG P0 uchar code tab ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x08};//共阳数码管段码 void delay1ms(uint); uchar pr
[单片机]
基于控制器设计的纹锁
随着指纹自动识别系统体积的不断缩小,以及微处理器功能与速度的不断提高,复杂的指纹识别门锁控制算法已可以被固化到一块体积非常小的嵌入式微处理器模块上,该模块与指纹传感器、门锁控制机构组成的系统称为嵌入式指纹识别门锁系统。嵌入式指纹锁的应用领域十分广泛,有保险箱、实验室、楼道的身份确认等。本文基于指纹识别模块设计和实现了嵌入式指纹锁,给出了一套比较完整的软、硬件设计方案。 指纹识别门锁系统的硬件结构 指纹识别门锁系统的硬件结构主要包括:指纹识别模块、微控制器、读写模块、电源管理和电控锁机构以及门锁功能所需的红外感应电路和液晶LCD显示等,其中核心部分是指纹识别模块和微控制器。指纹识别门锁系统的结构框图如图1所示,虚线内
[单片机]
基于控制器设计的纹锁
单片机控制LED轮廓显示原理及总体方案设计
  LED护栏管又名丽得管,是一种先进的LED装饰照明灯饰产品。以红、绿、蓝3种颜色的LED作为光源,使用了微电子和数码技术,能进行色彩追逐,色彩过渡渐变,灰度变化和七色变化,能产生十分丰富的色彩变幻效果。该产品外形采用一次成型,灯管和底座浑为一体,防水性更好,重量更轻。广泛适用于酒吧、舞厅、大厦、广场、桥梁、栏杆等各种大型建筑装饰,全彩管更可以在一个大范围的区域实现灯光群控和显示动态节目,适合大型主题夜景。   文中提出了一种主从式单片机的LED轮廓显示屏解决方案,该设计方案利用STC单片机自身的FLASH ROM和RAM,外部无需任何存储电路,电路结构简单。可实现交流同步显示,驱动当前LED亮化市场中的多款LED护栏管与点光
[单片机]
<font color='red'>单片机</font>控制LED轮廓显示原理及总体方案设计
单片机对SD卡读写系列(一)
SD卡,是一种基于半导体快闪记忆器的新一代记忆设备,SD于1999年8月研制成功,其重量只有2克。但却拥有高记忆容量、快速数据传输率、极大的移动灵活性以及很好的安全性。SD卡也很容易重新格式化,有广泛的应用领域,如音乐、电影、新闻等多媒体文件都可以方便地保存,数码相机也开始支持SD卡。SD卡容量最高能达到4GB。 SD卡在24mm 32mm 2.1mm的体积内结合了〔SanDisk〕快闪记忆卡控制与MLC(Multilevel Cell)技术和Toshiba(东芝)0.16u及0.13u的NAND技术,通过9针的接口界面与专门的 驱动器 相连接,不需要额外的 电源 来保持其上记忆的信息。而且它是一体化固体介质,没有任何移动部分,所以
[单片机]
单片机经典实验实例精华详解(附源程序) (二)
一、八路LED跑马灯实验   现在让我们开始做第一个实验:八路发光二极管轮流点亮的实验,也就是通常所说的跑马灯实验,首先让我们来完成必须的硬件部分,我们需要焊接上8个发光二极管和8个限流电阻,可以参考下面的原理图和实物图像进行操作,需要注意的是LED是有极性的,引脚长的为正极,引脚短的为负极,负极和电阻一侧连接,如果接错那么相应的那一路可能在实验中不会点亮了,在焊接前要看仔细哦~~~      下面我们来完成软件编程设计,这里我们没有采用高深的编程技巧,而是用了最笨、最直接的向端口送数的办法来实现,一来程序比较简单,没必要玩深沉,而且初学者看起来直观易懂。   ORG 0000H   START:MOV P1,#011
[模拟电子]
<font color='red'>单片机</font>经典实验实例精华详解(附源程序) (二)
基于51单片机老人防跌倒GSM短信报警系统
1、项目简介 选题指导,项目分享: Lighter-z/嵌入式基地 1.1 系统构成 本设计由STC89C52单片机电路+ADXL345加速度传感器电路+按键电路+蜂鸣器报警电路+DS18B20温度传感器电路+LED灯电路+GSM模块电路+电源电路组成。 1.2 系统功能 1、板子竖直放置的时候,蜂鸣器不报警,板子歪倒一定角度,则蜂鸣器鸣叫报警。一段时间约15s未回复正确状态,GSM发送报警信息给手机:Help me!!。 2、如果温度超过38度,蜂鸣器报警,持续温度过高约15s左右,同时短信报警:has a cold 3、设计带有误报警按键,蜂鸣器报警的时候,如果老人认为是误报警,则按键按下,蜂鸣器停止报警,如果持续问题存在还会
[单片机]
P51XA单片机与图形液晶显示器的接口设计
P51XA是PHILIPS公司的一种16位单片机,可管理的存储器空间大,运行速度快,支持实时多任务系统的增强了实现高级语言的支持,可以运用在需要复杂、高速控制的场合,在体系结构上与MCS-5高度兼容,便于实现向高性能微控制器的快速、平滑转移。北京精电蓬远显示技术有限公司的MGLS240128T是一种240×128点阵的图形LCD(液晶显示器),可以显示图形、曲线,全屏可显示15×8个汉字,适宜用在需要有较多显示内容的场合,它内含T6963C控制器,能直接与INTEL系列的微处理器接口。 1 P51XAG37单片机和T6963C简介 P51XA单片机的内部结构和外部数据总线均为16位结构,支持扩展的外部存储器空间为1MB-16M
[单片机]
P51XA<font color='red'>单片机</font>与图形液晶显示器的接口设计

推荐帖子

IAR能否直接读取TXT文件中的数据?
如题,请教各位高手,能否在IAR中直接读取已有的TXT文件中的数据?IAR能否直接读取TXT文件中的数据?
qubeini 微控制器 MCU
PCB转换成原理图
本人初学protel,想把一个PCB图转换成原理图,有没有这样的软件?PCB图上有布了很多铜线什么的,看的很复杂,有没有什么操作能简化PCB,看清楚各个元件封装的连接!谢谢!PCB转换成原理图有这样的软件,不过要在网上找的呀.Re:PCB转换成原理图没用过Re:PCB转换成原理图能转吗?没有用过!不过倒是可以同步来修正原理图Re:PCB转换成原理图想学习就画一遍,多清楚.这样的软件还没听说过.Re:PCB转换成原理图protel应该也有把PCB转换成原理
ben007 PCB设计
高性能单核处理器——C2000 Delfino LaunchPad(LAUNCHXL-F28377S)评测
以下内容是转载1简介C2000DelfinoLaunchPad(LAUNCHXL-F28377S)是一款基于TI最新Delfino器件TMS320F28377S的低成本开发套件,板载XDS100v2仿真器,只需一根USB线就可以进行开发、调试和代码烧写,并提供UART实现PC机和目标板的串行通信。如下图所示,LAUNCHXL-F28377SC2000LaunchPadEVM板主要特性如下:ØUSBDebug和编程接口,板载高速、隔离的XDS1
好大一阵风 微控制器 MCU
UART接收程序丢失数据的问题
各位大侠,我用AVRATMEGA16的UART来接收上位机串口调试助手发来的数据,假设为0x53,0x26,0x53,0x89,0x47,前面两个数据总是对的,然后第三位就接到了最后一个数据,中间的数据就丢失了。接收中断程序如下:#pragmainterrupt_handleruart_rx_isr:12voiduart_rx_isr(void){if(!rx_isfull){*rx_pointer=UDR;rx_pointer++
q91391 嵌入式系统
急急求助:Launchpad配置I2C,没有输出脉冲?为什么?
紧急求助:程序的目的:Launchpad-MSP430G2(是g2553型号的)用USCI配置做I2C,往存储卡AT24C02写数据,然后再读卡里的数据。出现的问题:跟本读不到数据。我把读存储器数据的部分屏蔽掉,只运行写存储器部分来做测试,用示波器看输出的SCL和SDA线上没有脉冲。是我的寄存器配置不对吗?求高手指点?很急啊!/**求助:*Launchpad-MSP430G2553选I2C模式,往存储
994824405 微控制器 MCU
【翌创ET6001测评】FOC电流环算力
测试目的:评估在200M主频下的执行FOC电流环的算力测试结果:如下图所示,ADC完成采样中断时,置IO为高电平,读ADC,计算FOC电流环,设置PWM输出,置IO为低电平。测试得到单次FOC电流环时间为1.72uS。说明:由于我开发环境,暂无法DEBUG,无法单次调试抓内存数据,只能通过GPIO测定FOC电流环执行时间;开发板是只有IO的最小系统,没有BLDC电控需要的MOS驱动以及ADC配合PGA的真实采样环路,所以测试的仅为算力测试。一般在1
majorshu 国产芯片交流
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved