使用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-17 09:08

MSP430单片机的电桥平衡自调节设计
在应变式火炮膛压测试仪中,直流不平衡电桥测量电路是测量火炮膛压信号的核心环节。由于电阻应变计阻值有一定的偏差,使得电桥在初始时达不到平衡,导致测试仪在没有应变时输出信号有为负值的可能性,致使测试仪所测得的数据无法以计算机数值校正方法实现。对于传统的机械电位器,手动调节的方法无法满足应变式火炮膛压测试仪封闭式、小体积的要求。本文设计的 MSP430F2002 单片机和MAX5402数字电位器所构成的电桥平衡自调节电路,具有结构简单、占用空间小、功耗低、可靠性高等特性,完全符合火炮膛压测试仪的要求。 1 电桥平衡自调节原理 在火炮膛压测试仪中,考虑到测试仪壳体结构的限制以及低功耗的要求,采用的电桥为1/4直流源电桥。电桥平衡
[单片机]
MSP430<font color='red'>单片机</font>的电桥平衡自调节设计
单片机延时程序分析
单片机延时程序分析 应用单片机的时候,经常会遇到需要短时间延时的情况。需要的延时时间很短,一般都是几十到几百微妙(us)。有时候还需要很高的精度,比如用单片机驱动 DS18B20的时候,误差容许的范围在十几us以内,不然很容易出错。这种情况下,用计时器往往有点小题大做。而在极端的情况下,计时器甚至已经全部派上了别的用途。这时就需要我们另想别的办法了。 汇编语言写单片机程序的时候,这个问题还是相对容易解决的。比如用的是12MHz晶振的51,打算延时20us,只要用下面的代码,就可以满足一般的需要: mov r0, #09h loop: djnz r0, loop 51 单片机的指令周期是晶振频率的1/12,也就是1u
[单片机]
基于C8051单片机的无线心电监护系统设计
   1 引言   随着经济的快速发展和人们生活水平的不断提高,健康已成为人们关注的焦点。心脏疾病是危害人类健康的一大杀手,其偶然性与突发性的特点使得心电监护系统具有重要的临床应用价值。由于传统的心电监护仪不能进行远距离的实时监护,所以便携式无线心电监护系统显得更加重要。无线医疗监护系统主要由生理信息与数据采集、无线数据通信、控制和显示等单元组成。目前国内已有用于临床的无线心电监护产品,但其采用的方案大都是“采集器+发送器(PDA或手机)”,从成本上看其价格昂贵;从无线传输方面看,大多是将心电数据以模拟信号传输,这必然导致信号在传输过程中发生失真。此外,由于人体电阻差异导致心电信号在1~10 mV之间变动,固定放大倍数系统缺乏适
[单片机]
基于NEC单片机的电动车充电器控制系统设计
进入21世纪,环境和能源危机日益突出。电动汽车作清洁、高效和可持续发展的交通工具,成为当今国际汽车行业发展的潮流和热点。 目前,制约电动汽车推广的主要因素之一是充电效果不好,同时充电控制方法的选择不当,使多数充电器与蓄电池不匹配。在这样的背景下,本文结合某公司的增程型车载电动汽车充电器研发项目,设计了一种基于NEC单片机的智能充电控制系统。该系统采用多级恒流与慢脉冲充电相结合的快速充电策略,使动力蓄电池工作在较理想的工况下,延长其使用寿命,提高充电效率。 1 充电方式设计 传统的充电方法主要有以下几种:恒流充电、恒压充电、恒压限流充电、恒流限压充电、阶段充电等。这些方法控制简单,实现容易,但是充电时间较长。国内外也提出
[单片机]
基于NEC<font color='red'>单片机</font>的电动车充电器控制系统设计
51单片机 步进电机旋转角度控制
#include reg52.h typedef unsigned char uchar; typedef unsigned int uint; typedef unsigned long ulong; uchar code beatCode = { 0xE, 0xC, 0xD, 0x9, 0xB, 0x3, 0x7, 0x6 }; ulong beats = 0; uchar T0RH = 0, T0RL = 0; void turnMotor(ulong angle){ EA = 0; beats = angle * 4076 / 360;
[单片机]
STM8单片机STVD环境监视数组变量的多个元素
调试时监视数组变量的多个元素修改如下设置
[单片机]
怎样才能知道单片机是否还能用?
首先应该确认电源电压是否正常。用电压表测量接地引脚跟电源引脚之间的电压,看是否是电源电压,例如常用的5V。接下来就是检查复位引脚电压是否正常。分别测量按下复位按钮和放开复位按钮的电压值,看是否正确。然后再检查晶振是否起振了,一般用示波器来看晶振引脚的波形,注意应该使用示波器探头的“X10”档。 另一个办法是测量复位状态下的IO口电平,按住复位键不放,然后测量IO口(没接外部上拉的P0口除外)的电压,看是否是高电平,如果不是高电平,则多半是因为晶振没有起振。另外还要注意的地方是,如果使用片内ROM的话(大部分情况下如此,现在已经很少有用外部扩ROM的了),一定要将EA引脚拉高,否则会出现程序乱跑的情况。有时用仿真器可以,而烧入片子
[单片机]
MCU厂商多策略确保实现产品差异化
MCU在我们的生活中几乎无处不在,有人曾做过统计,普通消费者日均接触300个左右的MCU。因此,MCU成为半导体厂商始终追逐的热点并不足为奇。然而,突发的次贷危机让很多厂商都被笼罩在经济衰退的阴影下。该如何加快产品上市时间、降低开发成本,同时实现产品差异化?本文帮读者节选了Microchip、NXP、TI等“玩家”最新的产品介绍和市场策略,希望对您有所裨益。 “世界憎恨变革,但只有变革才是唯一能带来进步的事物。” 通用汽车研究实验室前主任Charles Kettering的名言,为处在经济衰退阴影下的厂商指明了航向。美国微芯科技(Microchip)公司日前就宣布推出支持中档8位PIC12和PIC16 MCU
[单片机]
<font color='red'>MCU</font>厂商多策略确保实现产品差异化

推荐帖子

当年做的课程设计《综合课程设计简易计算器》
所说简单点,但是还是蛮可以的,不足之处求大家指正!当年做的课程设计《综合课程设计简易计算器》想了解一下是用什么编的哦!回复楼主冷枫yj的帖子是用C语言编写的回复沙发gaoxiao的帖子十分感谢~~~~~~同7楼!!!!!!下来看看先!!感谢分享!!顺便回10楼回帖就有芯币啦!!多多回帖吧!!!是用C语言编写的有用到栈吗收藏喽,,:)
冷枫yj 单片机
WinCE系统自带的数据库备份问题
各位大侠好,最近在WINCE上开发一个项目,数据量不是很大,在数据库方面,我就采用了系统自带的数据库CEDB,由于项目要求,现在要对数据库的备份文件进行基本的操作,比如说查询之类的,如果是在WINCE上操作还好说,但是要移植到PC机上面,这个问题一直不知道该怎么解决,希望高人基于指点!WinCE系统自带的数据库备份问题自己顶一下!
pengwr WindowsCE
我在学cadence软件,但是无从下手,大神们都是怎么学的呢?
同标题,学习cadence,不知道如何入手,主要是想学习第三方导入网表,用cadence进行布局布线。是不是需要从cadence的原理图设计开始呢?这个软件看起来比较复杂,大神们有没有什么推荐的视频以及书籍呢?谢谢啦我在学cadence软件,但是无从下手,大神们都是怎么学的呢?搜索于博士Cadence教程PCB制板设计要从原理图学起教程可以到下载中心找找https://download.eeworld.com.cn/eewsearcher?kw=cadence教程1910
651076842 PCB设计
vc2005开发的智能设备ocx,如何改造能在pc(x86)下的智能设备应用中开发使用?高手帮忙
vc2005开发的智能设备ocx,如何改造能在pc(x86)下的智能设备应用中开发使用?vc2005开发的智能设备ocx,如何改造能在pc(x86)下的智能设备应用中开发使用?高手帮忙拿源代码,重编译具体说,能指点以下吗?我的qq412925762楼主:给出详细的做法,本人刚入门
laoqiao 嵌入式系统
关于DE1-SOC上的USB部分
最近由于工作需要在DE1-SOC上移植UCOS,目前需要实现USB通信,但是官方的硬件库没有USB驱动,想问下关于上面这个USB的裸机驱动有没有什么参考或者指点关于DE1-SOC上的USB部分目前也需要这方面的资料,不知道哪里有我现在也碰到了这个问题,楼主能给点建议吗?谢谢!
柯哀LV王道 Altera SoC
【TI讨论】修整引脚在哪里?
某天,Bruce和他的朋友讨论了我们用于“修整”或者调整放大器补偿电压至极低值所使用的各种技术。这让他想到了补偿电压修整引脚——它们到哪里去了呢?工程师朋友们,如果不看文章,你们能回答得上来吗?【TI讨论】修整引脚在哪里?OPA系列的调零管脚很多还是有的。我固执的避免用加减法电路来实现调零,感到这样会引入噪声和温漂现在每个厂商都有零失调系列的运放把“调整”改为了“修整”,我咋说不知道是怎么回事呢!
德州仪器 模拟与混合信号
小广播
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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