测温型 NTC 热敏电阻器(ADC、DMA)"/>
STM32(F103ZETX)物联网项目——MF52 珠状测温型 NTC 热敏电阻器(ADC、DMA)
MF52 珠状测温型 NTC 热敏电阻器数据手册如下:
链接:
提取码:dxct
--来自百度网盘超级会员V2的分享
程序功能:
1.上电后,数码管显示PCB温度。
ADC介绍
详情介绍见STM32数据手册,上一篇介绍看门狗的文章里面有分享。
简介:
12 位 ADC 是一种逐次逼近型模拟数字转换器。它有多达 18 个通道,可测量 16 个外部和 2 个内部 信号源。各通道的 A/D 转换可以单次、连续、扫描或间断模式执行。 ADC 的结果可以左对齐或右 对齐方式存储在 16 位数据寄存器中。 ADC的输入时钟不得超过14MHz,它是由PCLK2经分频产生。逐次逼近型ADC功能图:
ADC模块框图及时钟框图:(由于是从自己所画图片中截图,许多不清晰地方,建议对照STM32F10x手册观看,手册分享在看门狗章节) 注入组和介绍组介绍: 这里,我们打个比喻,将注入组和介绍组比喻为在饭店里点餐的两种方式。首先是规则组,它的通道最多有16个,这里我们比喻为有一个菜单,我们在这个菜单里最多可以点16个菜,但很尴尬的是,规则组的数据寄存器只有一个,相当于吃饭的桌子只能放一个菜,当后面的菜端上来之前,你得赶紧把桌上的菜吃掉,不然就会被“挤掉”,所以,使用规则组时,一般都会DMA一起使用;而注入组最多可以点4个菜,且有4个数据寄存器,相当于饭店的VIP座位,桌上可以放4个菜。 ADC的4中转换模式:单次转换、连续转换、扫描转换、非扫描模式。 1.单次转换模式下, ADC 只执行一次转换,即完成一组ADC通道转换后停止。 2.在连续转换模式中,当前面 ADC 转换一结束马上就启动另一次转换。 3.此模式用来扫描一组模拟通道。 单次转换/连续转换应和扫描转换/非扫描转换配合使用。DMA简介 因为规则通道转换的值储存在一个仅有的数据寄存器中,所以当转换多个规则通道时需要使用 DMA ,这可以避免丢失已经存储在 ADC_DR 寄存器中的数据。 只有在规则通道的转换结束时才产生 DMA 请求,并将转换的数据从 ADC_DR 寄存器传输到用户 指定的目的地址( 一般会在程序代码中建立一个数组,存入其中,当然,使用HAL库的话会更加方便 )。 使用DMA转换数据可以减少CPU的使用率,提高转换速度。 两种ADC规则组配合DMA使用的方式:
! 详情可去b站搜索江协科技的STM32教程,里面的ADC和DMA章节非常详细 。
实例
NTC硬件电路:
初始化:
ADC1(通道13)参数配置:
ADC1DMA请求配置:
温度转换表:
制作方法:对照MF52 珠状测温型 NTC 热敏电阻器数据手册的温度特性表在excel中制作。
转换电压的关系:0~3.3V对应采集模拟值0~4095,关系为:实际电压=(ADC采集值*3.3)/4095
程序代码:
NTC结构体类型:
//定义结构体类型
typedef struct
{void (*Get_NTC_Voltage)(void); //获取温度电压uint16_t usADC_Value; //获取采集值float fNTC_Voltage; //NTC电压void (*Get_Temperature_Value)(void); //获取温度float fTemperature; //温度值
} NTC_t;
获取温度函数:
/** @name Get_Temperature_Value* @brief 获取温度值* @param None* @retval None
*/
static void Get_Temperature_Value()
{ uint8_t Temp;临界温度处理if(NTC.usADC_Value < 589) //最高70°C{NTC.usADC_Value = 589;printf("Temperature is higher than 70¡æ\r\n");}if(NTC.usADC_Value > 3867) //最低-30°C{NTC.usADC_Value = 3867;printf("Temperature is below -30¡æ\r\n");}//二分法查数组if(NTC.usADC_Value > NTC_Table[50][1]){//查询0~49, 对应-30°C到19°Cfor(Temp=0;Temp<=49;Temp++){if((NTC.usADC_Value >= NTC_Table[Temp][0]) && (NTC.usADC_Value <= NTC_Table[Temp][1]))break;}}else if(NTC.usADC_Value < NTC_Table[50][0]){//查询51 - 100 对应21°C到70°Cfor(Temp=51;Temp<=100;Temp++){if((NTC.usADC_Value >= NTC_Table[Temp][0]) && (NTC.usADC_Value <= NTC_Table[Temp][1]))break;}}else{Temp = 50; //对应20°C}//计算温度NTC.fTemperature = (float)Temp - 30; printf("Temperature is :%.1f¡æ\r\n\r\n",NTC.fTemperature);
}
System.h里的系统运行函数:
/** @name Run* @brief 运行函数* @param None* @retval None
*/
static void Run()
{float Temp = 0;//获取电压NTC.Get_NTC_Voltage();//获取温度NTC.Get_Temperature_Value();//显示温度if(NTC.fTemperature < 0) //负温{Temp = 0 - NTC.fTemperature;Display.Disp_Other(Disp_NUM_3,0x40,Disp_DP_OFF); //3号数码管显示“-”号}else //正温{Temp = NTC.fTemperature;Display.Disp_Other(Disp_NUM_3,0x00,Disp_DP_OFF); //3号数码管关闭}Display.Disp_HEX(Disp_NUM_1,(uint8_t)Temp%10,Disp_DP_OFF);Display.Disp_HEX(Disp_NUM_2,(uint8_t)Temp/10,Disp_DP_OFF);HAL_Delay(1000); //间隔1秒显示温度
}
MyInit.h里的初始化函数:
/** @name Peripheral_Set* @brief 外设设置* @param None* @retval None
*/
static void Peripheral_Set()
{Display.TM1620_Init(); //ÊýÂë¹Ü³õʼ»¯HAL_ADC_Start_DMA(&hadc1,(uint32_t*)&NTC.usADC_Value,(uint32_t)1); //开启ADC1的DMA输出HAL_Delay(1); //延时,等待初始化稳定
}
补充:另外还做了DAC配合DMA输出1KHZ的正弦波操作,没有细讲,这里简单说说思路:
初始化:使用定时器输出频率,DAC配置中开启定时器事件中断输出,并配置DMA请求。
代码部分:在网上查找模拟值对应的电压,尽可能多,用作采集点,本项目选择了32个采集点,建立一个数组将其存入其中,开启DAC的DMA输出,输出值为数组元素值,DAC会自动转换输出电压值,将DAC输出端口连接到示波器,就会出现一个1KHZ的正弦波。
更多推荐
STM32(F103ZETX)物联网项目——MF52 珠状测温型 NTC 热敏电阻器(ADC、DMA)
发布评论