之————06 ADC进行NTC采样DMA
时间:10-02
整理:3721RD
点击:
前面进行了ADC对内部芯片的测试,可以解决内部温度过高烧芯片的问题,当内部温度过高时加热器的功率可降低温度。今天测试NTC对外部环境温度测试的。原理非常简单,找了10K的NTC,并在厂家拿到了对应的温度数据表,连接硬件进行测试,虽然看看看别人做比较简单,自己动手做起来还是这样那样的问题。
一、硬件部分
1.1、打开开发板原理图先选定输入引用为PB1,因为PB1比较方便接线。
1.2、连接好电路
二、环境配置
2.1这个方便,先好PB1设置成输入就好。
2.2开启DMA
其它配置参考。做好设置后输出工程。
三、软件编程
3.1 设计思路:
3.1.1先将厂家拿到的参数表建立两个数组,分别存零度以上与零以下的组参数->
3.1.2将NTC采样的数据转化为电压数据->
3.1.3电压数据转成电阻->
3.1.4通过查询前面建立的数据可以查询到整数温度值->
3.1.5在通过计算小数部->
3.2 为了方便使用,建立ntc.c与ntc.h两个文件
3.2.1 ntc.h
#ifndef __ntc_H
#define __ntc_H
#ifdef __cplusplus
extern "C" {
#endif
#include "stm32f4xx_hal.h"
#include <stdio.h>
uint32_t Reg_Find_Down(uint32_t data); //零度以下查找
uint32_t Reg_Find_Up(uint32_t data); //零度以上查找
uint32_t AdcToReg(uint16_t data); //ACD数据转成电阻值
float Temp1(uint16_t adc); //计算温度
#ifdef __cplusplus
}
#endif
#endif /*__ NTC_H */
3.2.2 ntc.c 为了提高速度采用2分法进行查询。(注意不能将数据定义到NTC.h中会出现重复定义问题)
/* 包含系统头文件 */
/* 包含自定义头文件 */
#include "ntc.h"
#include "stm32f4xx_hal.h"
/* 自定义新类型 */
typedef unsigned int uint;
uint32_t ntcDown[]= //ntc10k热敏电阻分压表。-55~-1℃
{
33621,35455,37405,39477,41681,44026,46522,49179,52011,55028, //0~-9度
58246,61678,65341,69253,73432,77898,82674,87783,93252,99109, //-19~-10度
105385,112112,119328,127071,135385,144317,153918,164243,175354,187316,//-29~-20度
200204,214096,229079,245249,262710,281577,301975,324043,347933,373810,//-39~-30度
401860,432283,465304,501167,540145,582536,628672,678920,733685,793416,//-49~40度
858613,929827,1007674,1092837,1186075,1288234, //-50~-55度
};
uint32_t ntcUp[]= //ntc10k热敏电阻分压表内。0~200℃
{
33621,31893,30266,28733,27288,25925,24639,23425,22279,21197, //0~9度
20175,19208,18294,17430,16612,15837,15104,14409,13751,13127, //10~19度
12535,11974,11441,10936,10456,10000,9567,9155,8764,8391, //20~29度
8037,7700,7379,7074,6783,6506,6241,5989,5749,5520, //30~39度
5301,5093,4894,4703,4522,4348,4182,4024,3872,3727, //40~49度
3588,3455,3328,3207,3090,2978,2871,2769,2671,2577, //50~59度
2486,2399,2316,2237,2160,2086,2016,1948,1883,1820, //60~69度
1760,1702,1646,1593,1541,1492,1444,1398,1354,1311, //70~79度
1270,1231,1193,1156,1121,1087,1054,1022,992,962, //80~89度
934,906,880,854,829,805,782,760,738,718, //90~99度
698,678,659,641,623,606,590,574,559,544, //100~109度
529,515,502,488,476,463,451,440,429,418, //110~119度
407,397,387,377,368,359,350,341,333,325, //120~129度
317,310,302,295,288,281,275,268,262,256, //130~139度
250,245,239,234,228,223,218,213,209,204, //140~149度
200,195,191,187,183,179,175,172,168,164, //150~159度
161,158,154,151,148,145,142,139,136,134, //160~169度
131,128,126,123,121,119,116,114,112,110, //170~179度
108,106,104,102,100,98,96,94,93,91, //180~189度
89,88,86,84,83,81,80,79,77,76,74, //190~200度
};
/* 自定义宏 */
#define R_b 9771 //定义基准万用表测量
/*实现函数部分*/
/*******************************************************************************
* 名称: uint16_t AdcToReg(uint16_t data)
* 功能: 将ADC送来的数转化为电阻
* 形参: data为ADC数
* 返回: 无
* 说明: 采样电阻10k
******************************************************************************/
uint32_t AdcToReg(uint16_t data)
{
uint32_t Reg;
if ((data!=0x0)&&(data<=0xFFF)) //判定ADC数据是否正常
{
Reg=(R_b*data)/(0xFFF-data); //计算电阻大小
return Reg;
}
else
{
return 9999;//如果数据不正常返回9999
}
}
/*******************************************************************************
* 名称: int Reg_Find_Up(uint16_t nuiResVal)
* 功能: 向零度以上查询
* 形参: nuiResVal为ADC数
* 返回: 无
* 说明: 采样电阻10k
******************************************************************************/
uint32_t Reg_Find_Up(uint32_t nuiResVal)
{
uint nuiTempMin = 0;
uint nuiTempMax = 190;
uint nuiMidVal = 0;
if(nuiResVal<=ntcUp[nuiTempMax])
{return 912;}
else
{
while(nuiResVal >= ntcUp[nuiTempMax])
{
nuiMidVal = (nuiTempMax + nuiTempMin) / 2;
if((nuiMidVal == nuiTempMin) || (nuiMidVal == nuiTempMax))
{
break;
//return nuiTempMin;
}
if(nuiResVal >= ntcUp[nuiMidVal])
{
nuiTempMax = nuiMidVal;
}
else
{
nuiTempMin = nuiMidVal;
}
}
return nuiMidVal;}
}
/*******************************************************************************
* 名称: int Reg_Find_DWON(uint32_tnuiResVal)
* 功能: 向零度以下查询
* 形参: nuiResVal为ADC数
* 返回: 无
* 说明: 采样电阻10k
******************************************************************************/
uint32_t Reg_Find_Down(uint32_t nuiResVal)
{ uint nuiTempMin = 0;
uint nuiTempMax = 54;
uint nuiMidVal = 55;
while(nuiResVal <= ntcDown[nuiTempMax])
{
nuiMidVal = (nuiTempMax + nuiTempMin) / 2;
if((nuiMidVal == nuiTempMin) || (nuiMidVal == nuiTempMax))
{
break;
//return nuiTempMin;
}
if(nuiResVal <= ntcDown[nuiMidVal])
{
nuiTempMax = nuiMidVal;
}
else
{
nuiTempMin = nuiMidVal;
}
}
return nuiMidVal;
}
/*******************************************************************************
* 名称: public float Temp(uint32_tadc)
* 功能: 返回ADC對應的電阻
* 形参: 为ADC数
* 返回: 正常温度,-99表示超低温,+911表示超高温200度
* 说明: 采样电阻10k
******************************************************************************/
float Temp1(uint16_t adc)
{
uint32_t reg; uint16_t temp;float tempD;
if(adc!=0)
{
reg=AdcToReg(adc);
if(reg>=ntcUp[0])
{
temp=Reg_Find_Down(reg);
tempD=((float)reg-ntcDown[temp])/(ntcDown[temp+1]-ntcDown[temp]);
if(tempD>1){tempD=0;return -999;}
else
{tempD= (temp+tempD);}
return -tempD;
}else
{
temp=Reg_Find_Up(reg);
tempD=(ntcUp[temp] -(float)reg)/(ntcUp[temp]-ntcUp[temp+1]) ;
if(temp==912){return 999;}else{
tempD=temp+tempD;
return (float)tempD;}
}
}else
{
return 888 ; //ADC电路断开
}
}
3.2.2 main程序部分
3.2.3测试显示
NTC与芯片只要放手在上面温度都会增加,但芯片温度好像比较低原因还要查一下。