本帖最后由 正版长小强 于 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 //温度值
}
}
*******************************************/
|
共1人点赞
|
@21ic小能手
@21小能手
@21小跑堂