如何较快制作温度与电压值对照表

目录

为什么要写这篇

有什么难度

阻值-温度表格转成mv值-温度表格

代码及运行结果


为什么要写这篇

前些天写过ADC数据滤波,写过二分查找表,都是很基础的知识,但没有提过查找表如何得来的,本来工作接手的时候已经有了,直接拿过来用就好了。

结果今天就交给我一个小任务。要做一个电机的热保护,电机工作时会持续发热,当发热达到某个阈值时则停止电机输出。要测量发热就需要温度采集,你以为会是温度传感器,直接单总线就读出温度值了,但实际工作中接触到的都是NTC热敏电阻(NTC: 负温度系数,随温度增加热敏电阻阻值减小)通过ADC测量采集点的mv值,根据与确定阻值的电阻分压(一般要求分压电阻与基准电压较精确),(串联电路中流经两个电阻的电流一致,电压比就等于电流比)来判断出当前热敏电阻阻值是多少,再根据厂家给出的阻值与温度对照表来了解到当前热敏电阻采集到的温度是多少。

有什么难度

那直接采电压,然后经过一个简单的公式得到电阻值然后查表不就好了吗。有什么可说的,并不是这样

  • 首先,从使用角度来看,直接采集到mv电压值,然后和数据表中对照一下就得到温度更符合操作习惯(用户体验),
  • 其次,电阻值都是浮点数,如10.214k。而mv电压值都是整数,正整数。先将一个正整数(mv电压值),转换成浮点数(NTC电阻阻值),然后再去查一个浮点数表,程序处理浮点数的速度要比处理正整数慢,高级些的单片机还有专门处理浮点数的单元,但一劳永逸优化代码提高运行速度的事肯定要做呀
  • 第三,前面文章也提到过,我写的二分查找表,并不支持浮点数,那只能用顺序查表法了

阻值-温度表格转成mv值-温度表格

那如何从厂家给出的PDF文档的阻值-温度表格转成程序代码的mv值-温度表格呢?

如果只是要求温度的大致范围,可能我就省些事,算出20°C~100°C中整10的温度对应的mv值就好了(因为电机工作温度不可能比环境温度还低),没几个数据,算一下十分钟左右就差不多了。

但要求做实验,工作多久会发烫比较严重,要看到温度上升曲线(这个可以有,但非要求),当人体感觉发烫严重时实际温度是多少,要一个精确值,方便最后讨论设置热保护阈值。那就只能将0~100°C 的阻值-温度对照表转换成mv值-温度对照表了。

每个温度还对应一个阻值上限一个阻值下限,那就需要处理202个数据了,如何换算,首先考虑到的就是编程实现了。

处理表格肯定要使用excel了,涉及到两个基本操作,表格数字后面加后缀 (后缀为f,)和 表格列转行,从PDF文档截取表格复制,在excel粘贴后将将无用数据删除(PDF的复制是基于行的,只能将那部分表格整个复制过来),

然后换算,excel也能实现,但程序员有程序员的方法:先产生两个伪阻值表,然后一个公式完成换算,输出到终端。后面有时间会将输出到终端封装成一个函数。

再将数据拷贝到代码中。

代码及运行结果

下面代码可在菜鸟C在线工具运行,但输出效果并不好,之后会试着将其封装成一个函数的同时可设置输出为几列。

/* 电机工作发热温度采集,确立哪个温度点采取热保护 */
#include <stdio.h>
#include <math.h>
#include <stdint.h>

#define ARRAY_SIZE  101

/* 用于热保护 */
float motor_ntc_Res_lower_limit[ARRAY_SIZE] = {0}; ///< 数组中未初始化元素自动置0

float motor_ntc_Res_higher_limit[ARRAY_SIZE] = {0};



/**
 * main
 * @brief   得到mv值-温度表
 * @note    关于motor_ntc_Res_lower_limit 和 motor_ntc_Res_higher_limit数组元素 为模拟NTC电阻阻值的伪数据
 * @note    12V供电,10K上拉分压电阻  采集点的mV值为 y = 12.0 * (x/(10k + x)) x单位为k, 即表格中数值,为得到单位为mV,乘以1000
 * @note    以上基准电压和分压电阻阻值 为伪数据
 */
int main(void)
{
    for(uint8_t i=0; i<ARRAY_SIZE; i++)
    {
        motor_ntc_Res_lower_limit[i] = (float)(1.0f * (ARRAY_SIZE - i));   ///< 1.0f被作为float数处理, 1.0被作为double数处理
    }
    for(uint8_t i=0; i<ARRAY_SIZE; i++)
    {
        motor_ntc_Res_higher_limit[i] = (float)(3.0f * (ARRAY_SIZE - i));
    }

    printf("const uint16_t motor_ntc_mV_lower_limit[%d] = \n",(ARRAY_SIZE));    ///< 将宏所表示常数打印出来
    printf("{ \n");
    for(uint8_t i = 0; i < ARRAY_SIZE; i++)     ///< i的作用域为其所处整个for循环
    {
        uint16_t num = (uint16_t)(float)(5.0f * 1000.0f * motor_ntc_Res_lower_limit[i] / (10.0f + motor_ntc_Res_lower_limit[i]));
        if(i != ARRAY_SIZE - 1)                 ///< 比较运算符优先级低于算术运算符
        {
            printf("\t%d,", num);
        }else
        {
            printf("\t%d", num);                ///< 最后一个元素无 ,
        }

        if(i % 10 == 9)
        {
            printf("\n");
        }
        if(i == ARRAY_SIZE - 1)                 ///< 比较运算符优先级低于算术运算符
        {
            printf("\n");
            printf("}");
            printf(";");                        ///< ; 需单独打印
            printf("\n");
        }
    }

    printf("const uint16_t motor_ntc_mV_higher_limit[%d] = \n",(ARRAY_SIZE));   ///< 将宏所表示常数打印出来
    printf("{ \n");
    for(uint8_t i = 0; i < ARRAY_SIZE; i++)      ///< i的作用域为其所处整个for循环
    {
        uint32_t num = (float)(12.0f * 1000.0f * motor_ntc_Res_higher_limit[i] / (30.0f + motor_ntc_Res_higher_limit[i]));

        if(i != ARRAY_SIZE - 1)                 ///< 比较运算符优先级低于算术运算符
        {
            printf("\t%d,", num);
        }else
        {
            printf("\t%d", num);                ///< 最后一个元素无 ,
        }
        
        if(i % 10 == 9)
        {
            printf("\n");
        }
        if(i == ARRAY_SIZE - 1)                ///< 比较运算符优先级低于算术运算符
        {
            printf("\n");
            printf("}");
            printf(";");            ///< ; 需单独打印
            printf("\n");
        }
    }
}

猜你喜欢

转载自blog.csdn.net/quanquanxiaobu/article/details/111656916