微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 之————06 ADC进行NTC采样DMA

之————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与芯片只要放手在上面温度都会增加,但芯片温度好像比较低原因还要查一下。



Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top