[资源共享]

《芯圣51内核单片机HC89F0xx库分享》- NTC传感器

[复制链接]
862|4
手机看帖
扫描二维码
随时随地手机跟帖
正版长小强|  楼主 | 2024-1-2 08:43 | 显示全部楼层 |阅读模式
本帖最后由 正版长小强 于 2024-1-12 13:48 编辑

#技术资源# #每日话题# #申请原创#
一、前言
       项目需要近期接触芯圣HC89F0xx系列51核单片机 ,超高的 性价比、灵活性 深深的吸引了我 。 为后续项目更快落地,开始做基础功能的封装库工作。

       往期分享地址 : 软定时器  、 GPIO库  、ADC库

二、分享内容
      NTC 温度传感器驱动,NTC 温度传感器 应用简单 ,根据电阻随温度变化的特性,测量传感器自身的分压值。硬件设计确保单片机采集电压能力满足温度测量范围即可。
      基于ADC库做本应用底层的工作很少,更多的是做传感器的功能设计。像 温度对应表、实时温度、温度报警、传感器状态 这些 。

/**
*   ************************************************************************************
*                                                                DEV_NTC
*        ************************************************************************************
*        @Examle Version                V1.0.0.0
*        [url=home.php?mod=space&uid=1102]@demo[/url]         Version                V1.0.0.0
*        @Date                                2023.11.14
*        ************************************************************************************
*       
*   ************************************************************************************
**/




#include "dev_ntc.h"
#include "x_mainrun.h"


#define   NTC_TEMP_LOW        (int)-55          /*传感器可以测量的最低温度*/
#define   NTC_TEMP_HIGH        (int)125          /*传感器可以测量的最高温度*/

code unsigned int NTC_Temp_Tab[]  =    //电路连接方式:+5V----NTC(10K,B3950)----10K电阻----GND   12bit ADC,客供NTC
{
    //0       1      2      3     4       5     6      7      8      9        温度    表索引
                0x39,         0x35,        0x31,         0x2E,        0x2A,         0x27,                                                                                                                        //-50~-55
        0x6A,  0x63,  0x5D,         0x57,         0x51, 0x4B, 0x46,        0x41,         0x3D,        //-41~-49
        0x71,  0x79,  0x81,  0x8A,  0x93,  0x9C,  0xA7,  0xB1,  0xBD,  0xC8,  //-40~-31   (0-9)
    0xD5,  0xE2,  0xF0,  0xFE,         0x10D, 0x11D, 0x12D, 0x13F, 0x151, 0x164,  //-30~-21  (10-19)
    0x177, 0x18C, 0x1A1, 0x1B8, 0x1CF, 0x1E7, 0x1FF, 0x219, 0x234, 0x24F,  //-20~-11  (20-29)     
    0x26C, 0x289, 0x2A8, 0x2C7, 0x2E7, 0x308, 0x32A, 0x34D, 0x371, 0x395,  // -10~-1   (30-39)  
    0x3BA, 0x3E0, 0x407, 0x42F, 0x457, 0x480, 0x4AA, 0x4D4, 0x4FF, 0x52A,  //  0~9    (40-49)  
    0x556, 0x582, 0x5AF, 0x5DC, 0x609, 0x637, 0x664, 0x692, 0x6C0, 0x6EE,  // 10~19   (50-59)  
    0x71C, 0x74A, 0x778, 0x7A5, 0x7D3, 0x800, 0x82D, 0x85A, 0x886, 0x8B2,  // 20~29   (60-69)  
    0x8DE, 0x909, 0x933, 0x95D, 0x987, 0x9B0, 0x9D8, 0xA00, 0xA27, 0xA4D,  // 30~39   (70-79)  
    0xA73, 0xA98, 0xABD, 0xAE1, 0xB03, 0xB26, 0xB47, 0xB68, 0xB88, 0xBA8,  // 40~49   (80-89)
    0xBC6, 0xBE4, 0xC02, 0xC1E, 0xC3A, 0xC55, 0xC70, 0xC8A, 0xCA3, 0xCBB,  // 50~59   (90-99)
    0xCD3, 0xCEA, 0xD01, 0xD17, 0xD2C, 0xD41, 0xD55, 0xD69, 0xD7C, 0xD8E,  // 60~69   (100-109)
    0xDA0, 0xDB2, 0xDC3, 0xDD3, 0xDE3, 0xDF3, 0xE02, 0xE10, 0xE1F, 0xE2C,  // 70~79   (110-119)
    0xE3A, 0xE47, 0xE53, 0xE5F, 0xE6B, 0xE76, 0xE82, 0xE8C, 0xE97, 0xEA1,  // 80~89   (120-129)
    0xEAB, 0xEB4, 0xEBD, 0xEC6, 0xECF, 0xED7, 0xEDF, 0xEE8, 0xEEF, 0xEF7,   // 90~99   (130-139)  
    0xEFE, 0xF05, 0xF0B, 0xF12, 0xF19, 0xF1F, 0xF25, 0xF2A, 0xF30, 0xF36,   //100~109  (140-145)                                                                                                                                                                                                 //106~109
        0xF3B, 0xF40, 0xF45, 0xF4A, 0xF4F, 0xF53, 0xF58, 0xF5C, 0xF61, 0xF64,         //110~119
        0xF69, 0xF6C, 0xF70, 0xF74, 0xF77, 0xF7A                                                                                                                         //120~125
};


/*************************************************
  NTC-温度转换
  参数 NTC_AD_Value  ADC 值
  返回:   温度-浮点类型
*************************************************/
xdata int temp_adc_v =   ((NTC_TEMP_HIGH - NTC_TEMP_LOW) + 1);

static float NTCTemp(unsigned int NTC_AD_Value)
{
        int i;
        float temp = 0;                  // -50~125C显示范围,
      
    if(NTC_AD_Value > 0xF7A)       //大于125度
    {
        return NTC_TEMP_HIGH;      //返回125度表示传感器短路
    }   
    else if(NTC_AD_Value < 0x39)   //小于-50度
    {
        return NTC_TEMP_LOW;       //返回-50度表示传感器开路
    }
    else
    {
        for (i = 0; i < temp_adc_v; i++)
            {
              if (NTC_Temp_Tab[i] >= NTC_AD_Value)
              {
                         if((i == 0) ||(i == (temp_adc_v - 1)))
             {
                                 temp = i + NTC_TEMP_LOW;
                           }
                         else
                         {
                                 temp =         (NTC_AD_Value - NTC_Temp_Tab[i - 1] );
                                temp = temp / (float)(NTC_Temp_Tab[i] - NTC_Temp_Tab[i - 1] );
                                 temp =  temp + (i + NTC_TEMP_LOW);       
                         }

                        break;
              }
            }            
            return(temp);
    }
}
/*************************************************
  NTC EVE 事件函数
*************************************************/
static  void  ntc_eve(struct   NTC_m *NTC)
{
   NTC->w_delay =   NTC->w_delay; //没有意义防止参数未调用警告
}
/*************************************************
  NTC 状态更新
*************************************************/
void Temp_status(struct      NTC_m  *NTC)
{
    struct      NTC_data   *NTC_d  = &NTC->temp;
   
        if(NTC_d->temp >= NTC_TEMP_HIGH){NTC_d->status = NTC_E2;        NTC->eve(NTC);        }        /*传感器短路*/
        if(NTC_d->temp <= NTC_TEMP_LOW) {NTC_d->status = NTC_E1;        NTC->eve(NTC);    }        /*传感器开路*/

        if(NTC_d->w_low < NTC_d->w_high ) /*上下限功能基础合法检测*/
        {
                if(NTC_d->temp > NTC_d->w_high) {NTC_d->status = NTC_W_HIGH;NTC->w_delay = 50;    NTC->eve(NTC);      }       
                else if(NTC_d->temp < NTC_d->w_low) {NTC_d->status = NTC_W_LOW;NTC->w_delay = 50; NTC->eve(NTC);          }
                else  
                {
                        if(NTC->w_delay > 0 ){NTC->w_delay --;  if(NTC->w_delay == 0){NTC->eve(NTC);}}
                        else
                        {
                                NTC_d->status = NTC_OK;
                        }
                }
        }
}

/*
    温度获取
    1 ADC 获取   
    2 ADC 缓冲区均值滤波
    3 ADC - temp
    4 temp 状态更新
*/
static void  Temp_get( struct HC_adc_m  *ADC,unsigned int val)
{
    struct   NTC_m  *NTC = (struct   NTC_m  *)ADC;
    xdata unsigned char i;
    NTC->adc_val = 0;
    NTC->adc_buf[NTC->adc_buf_num] = val;
    NTC->adc_buf_num ++; if(NTC->adc_buf_num >= ADC_BUF_SIZE)  {NTC->adc_buf_num = 0;}

    for(i = 0; i < ADC_BUF_SIZE; i ++)
    {
       NTC->adc_val += NTC->adc_buf[i] ; //注意数组初始化清零
    }
    NTC->adc_val = NTC->adc_val / ADC_BUF_SIZE;

    NTC->temp.temp =  NTCTemp(NTC->adc_val);  //温度转换

    Temp_status(NTC); //状态更新
}
/*
    NTC 初始化
    Pin_BCD   NTC 挂接的引脚
    *NTC      NCT 实体数据结构
    返回:  1 成功 ,:0 这个IO不支持 ADC
*/
unsigned char  NTC_Init(unsigned char Pin_BCD,struct   NTC_m *NTC)
{
   
   if(ADC_Config(Pin_BCD,Temp_get, &NTC->adc) == 0) return 0;
   memset(NTC,0,sizeof(struct   NTC_m));
   
  // NTC->get_ADC = Temp_get;
   NTC->eve = ntc_eve;
   NTC->temp.w_high = NTC_TEMP_HIGH;
   NTC->temp.w_low = NTC_TEMP_LOW;
   
   return 1;
}

/*
    NTC 高低温报警设置
    W_High  高温  ,W_Low 低温
*/
void  NTC_Warning_Set(float W_High,float W_Low ,struct   NTC_m *NTC)
{
    NTC->temp.w_high = W_High;
    NTC->temp.w_low = W_Low;
}

/*
    NTC 状态变化回调函数
    W_High  高温  ,W_Low 低温
*/
void  NTC_EVERun_Set(void (*eve)(struct   NTC_m *NTC),struct   NTC_m *NTC)
{
    NTC->eve = eve;
}   










.h 头文件



/**
*   ************************************************************************************
*                                                                DEV_NTC
*        ************************************************************************************
*        @Examle Version                V1.0.0.0
*        [url=home.php?mod=space&uid=1102]@demo[/url]         Version                V1.0.0.0
*        [url=home.php?mod=space&uid=212281]@date[/url]                                2023.11.14
*        ************************************************************************************
*        
*   ************************************************************************************
**/




#ifndef __DEV_NTC_H__
#define __DEV_NTC_H__

#include "x_include.h"
#include "x_adc.h"


enum  NTC_status
{
        NTC_OK                = 0X00,
        NTC_W_LOW        = 0X01,
        NTC_W_HIGH        = 0X02,   

        NTC_E1                = 0X10,        /*传感器未连接*/
        NTC_E2                = 0X20,        /*传感器短路*/
};

struct    NTC_data
{
        float temp;                                   /*当前温度*/
        float w_high;                          /*警示温度上限*/
        float w_low;                    /*警示温度下限*/
        enum  NTC_status  status; /*状态 */
}        ;

#define ADC_BUF_SIZE 8   /*ADC 滤波缓冲区*/
struct   NTC_m
{
    struct HC_adc_m     adc;
    unsigned int        adc_val;                //滤波后ADC
    unsigned int        adc_buf[ADC_BUF_SIZE];  //ADC 最近转换值
    unsigned char       adc_buf_num;            //ADC 最新数据位置
    unsigned char       w_delay;                //温度状态滞后时间 10ms
    struct    NTC_data  temp;
    void (*get_ADC)(struct HC_adc_m  *ADC,unsigned int val);
    void (*eve)(struct   NTC_m *NTC);  //事件函数
};




/*
    NTC 初始化
    Pin_BCD   NTC 挂接的引脚
    *NTC      NCT 实体数据结构
    返回:  1 成功 ,:0 这个IO不支持 ADC
*/
extern unsigned char  NTC_Init(unsigned char Pin_BCD,struct   NTC_m *NTC);
/*
    NTC 高低温报警设置
    W_High  高温  ,W_Low 低温
*/
extern void  NTC_Warning_Set(float W_High,float W_Low ,struct   NTC_m *NTC);
/*
    NTC 状态变化回调函数
    W_High  高温  ,W_Low 低温
*/
extern void  NTC_EVERun_Set(void (*eve)(struct   NTC_m *NTC),struct   NTC_m *NTC);

#endif

应用示例 ,两个NTC 传感器 ,NTC1 有上下限状态反馈 ,NTC2 单纯获取温度  。 配置完成即可使用
/********************************举例***********
xdata  struct   NTC_m  NTC1;
xdata  struct   NTC_m  NTC2;

void  NTC1_Eve(struct   NTC_m  *NTC)
{
    //这里进行事件状态定位并进行需要的动作
    switch(NTC->temp.status)
        {
            case NTC_E1:  break;
            case NTC_E2:  break;

            case NTC_OK:  break;
            case NTC_W_LOW:  break;
            case NTC_W_HIGH:  break;
    }
}


void main (void)
{

                Main_Iint();


    NTC_Init(NTC1_PIN,&NTC1);
    NTC_Init(NTC2_PIN,&NTC2);
    NTC_Warning_Set(20,40,&NTC1);
    NTC_EVERun_Set(NTC1_Eve,&NTC1);
   
    while(1)
    {
        NTC1.temp.temp  //温度值
    }
}


*******************************************/






  

使用特权

评论回复
评论
正版长小强 2024-1-2 08:44 回复TA
@21小能手 
guoyin88| | 2024-1-17 12:55 | 显示全部楼层
不错,感谢!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

60

主题

194

帖子

4

粉丝