基于STM32战舰开发板的内部温度传感器实验

内部温度传感器简介

测量的温度位置

内部温度传感器集成在芯片中,测量的是芯片的温度。

如何测量对应位置的温度?

温度传感器与ADC1_CH16相连,另外ADC1_CH17是与内部参照电压VREF+相连,因此我们可以通过ADC1的第16路通道测量芯片温度实时对应的电压转换得来的数字量,也可以通过ADC1的第17路通道测量内部参照电压对应的数字量。

我们知道STM32的ADC转换DATA是12Bits的,因此输入电压(小于3.3V大于0V)ADC转换为数字量的值为“大于0小于4096”。

我们由“T-V关系图”,“V的数字量”和“ADC量程”,可以得知“此时的温度”。

内部传感器配置注意事项

① 读取内部温度传感器数据的周期应大于17.1us;

② 内部温度传感器的温度测量误差约为1.5℃,因此内部温度传感器更适合于检测温度的变化,而不是测量绝对的温度。如果需要测量精确的温 度,应该使用一个外置的温度传感器。

内部温度传感器配置流程

所属函数位置

执行步骤

ADCx的初始化函数

使能相应总线上(APB1或者APB2)ADCx与GPIOx的外设时钟

配置GPIOx口中ADCx对应的引脚为模拟输入模式(ADC外设对应的GPIO模式)

将ADCx复位为缺省值(就是将ADCx的所有设过的属性全部重设为默认值)

设置ADCx时钟分频

将ADCx的校准寄存器恢复为默认值(此时应用对应的标志位来判断此步过程是否完成,如果完成再执行下一步)

将ADCx的校准寄存器初始化,开始校准(此时应用对应的标志位来判断此步过程是否完成,如果完成再执行下一步)

使能ADC1_CH16对应的内部温度传感器

使能ADCx外设

ADCx_CHy通道数值读取函数

配置ADCx_CHy(ADCx对应的y通道)的转换序号与转换周期

启动ADCx_CHy继续转换(此时应用对应标志位判断ADCx外设所有通道是否转换完成)

读取ADCx_CHy通道的数字量的值

ADCx_CHy通道读取的数据的后期处理函数

对n次读取的数据进行取平均值处理

温度与电压数字量之间的转换函数

用温度与电压数字量之间的对应关系进行转换

内部温度传感器实验代码解析

ADC初始化代码

void ADC_InitConfig()
{  ADC_InitTypeDef ADC_InitStructure;  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);  ADC_DeInit(ADC1);  RCC_ADCCLKConfig(RCC_PCLK2_Div6);  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Left;  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;  ADC_InitStructure.ADC_NbrOfChannel = 1; // 定义规则通道的长度  ADC_InitStructure.ADC_ScanConvMode = DISABLE;  ADC_Init(ADC1,&ADC_InitStructure);  ADC_TempSensorVrefintCmd(ENABLE); // 使能内部温度传感器  ADC_Cmd(ADC1,ENABLE); // 使能ADC1  ADC_ResetCalibration(ADC1); // 开始ADC1的校准寄存器复位  while(ADC_GetResetCalibrationStatus(ADC1));  ADC_StartCalibration(ADC1); // 开始ADC1的自动校准功能  while(ADC_GetCalibrationStatus(ADC1));  delay_init();
}  

我们应该注意到:ADC1_CH16连接着内部温度传感器,不用初始化具体的GPIO口引脚,只需要将寄存器的相应位使能即可:

我们有些同学在用如下“等待”代码的时候有些疑问:

ADC_ResetCalibration(ADC1); // 开始ADC1的校准寄存器复位
while(ADC_GetResetCalibrationStatus(ADC1));  ADC_StartCalibration(ADC1); // 开始ADC1的自动校准功能
while(ADC_GetCalibrationStatus(ADC1));  

我们用while循环为ADC外设提供执行任务所需的等待时间,但是我们一对比如下while代码,就有点懵了:

ADC_SoftwareStartConvCmd(ADC1, ENABLE);     //使能指定的ADC1的软件转换启动功能  while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束  

在while循环中,应该“取非”?这个是个让人不解的问题。

我们此时应该看寄存器,看寄存器中位与状态的对应关系:

ADC1复位校准功能与ADC1执行校准功能分别对应“ADC控制寄存器 2(ADC_CR2)”对应的如下两个位:

我们看到上图,可以得到如下结论:

功能

状态

位标志

检验ADC校准功能复位状态(完成/进行中)

复位执行中

1(SET)

复位完成(复位指令执行完毕)

0(RESET)

检验执行ADC校准功能的状态(完成/进行中)

正在开始执行ADC校准功能

1(SET)

ADC校准功能执行完毕

0(RESET)

此外,ADC_SR状态寄存器中的标志位EOC位代表着“ADC转换工作是否结束”:

功能

状态

位标志

查看ADC转换是否结束

ADC转换结束

1(SET)

ADC转换完成

0(RESET)

ADC转换函数

u16 ADC_GetValue()
{     ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_239Cycles5 );  //ADC1,ADC通道3,第一个转换,采样时间为239.5周期                      ADC_SoftwareStartConvCmd(ADC1, ENABLE);     //使能指定的ADC1的软件转换启动功能  while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束  return ADC_GetConversionValue(ADC1);    //返回最近一次ADC1规则组的转换结果
}  

注意:我们一定要在读取ADC通道转换值得函数中去执行:

ADC_SoftwareStartConvCmd(ADC1, ENABLE);     //使能指定的ADC1的软件转换启动功能  while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束 

我们初始化时只想初始化ADCx设备的属性,而函数“ADC_SoftwareStartConvCmd”得功能是根据ADCx各个引脚的属性启动ADCx外设进行转换操作。显然,初始化时不应进行获取转换值得操作。

多次读取取平均函数

 //获取通道ch的转换值
//取times次,然后平均
u16 T_Get_Adc_Average(u8 ch,u8 times)
{  u32 temp_val=0;  u8 t;  for(t=0;t<times;t++)  {  temp_val+=T_Get_Adc(ch);  delay_ms(5);  }  return temp_val/times;
} 

ADC转换的数字量转换为所需温度的函数

//得到温度值
//返回值:温度值(扩大了100倍,单位:℃.)
short Get_Temprate(void)    //获取内部温度传感器温度值
{  u32 adcx;  short result;  double temperate;  adcx=T_Get_Adc_Average(ADC_Channel_16,20);  //读取通道16,20次取平均  temperate=(float)adcx*(3.3/4096);       //电压值   temperate=(1.43-temperate)/0.0043+25;   //转换为温度值       result=temperate*=100;                  //扩大100倍.  return result;
}

总体代码示例

TempSensor.c

#include "TempSensor.h"
#include "stm32f10x.h"
#include "delay.h"  void ADC_InitConfig()
{  ADC_InitTypeDef ADC_InitStructure;  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);  ADC_DeInit(ADC1);  RCC_ADCCLKConfig(RCC_PCLK2_Div6);  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Left;  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;  ADC_InitStructure.ADC_NbrOfChannel = 1; // 定义规则通道的长度  ADC_InitStructure.ADC_ScanConvMode = DISABLE;  ADC_Init(ADC1,&ADC_InitStructure);  ADC_TempSensorVrefintCmd(ENABLE); // 使能内部温度传感器  ADC_Cmd(ADC1,ENABLE); // 使能ADC1  ADC_ResetCalibration(ADC1); // 开始ADC1的校准寄存器复位  while(ADC_GetResetCalibrationStatus(ADC1));  ADC_StartCalibration(ADC1); // 开始ADC1的自动校准功能  while(ADC_GetCalibrationStatus(ADC1));  delay_init();
}  u16 ADC_GetValue()
{     ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_239Cycles5 );  //ADC1,ADC通道3,第一个转换,采样时间为239.5周期                      ADC_SoftwareStartConvCmd(ADC1, ENABLE);     //使能指定的ADC1的软件转换启动功能  while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束  return ADC_GetConversionValue(ADC1);    //返回最近一次ADC1规则组的转换结果
}  u16 ADC_GetAverageValue()
{  u8 i = 0;  u16 temp = 0;  for(;i<5;i++)  {  temp += ADC_GetValue();  delay_ms(5);  }  return temp/5;
}  u16 DigitalValueConversion()
{  float temp = ADC_GetAverageValue();  return ((1.43-3.3*(temp/4096))/0.043+25)*100;
}  

TempSensor.h

#ifndef _TEMPSENSOR_H
#define _TEMPSENSOR_H  #include "sys.h"  void ADC_InitConfig();
u16 ADC_GetValue();
u16 ADC_GetAverageValue();
u16 DigitalValueConversion();  #endif  

Main.c

#include "TempSensor.h"
#include "stm32f10x.h"
#include "usart.h"
#include "delay.h"
#include "lcd.h"  int main()
{  u16 temp = 0;  ADC_InitConfig();  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  uart_init(115200);  delay_init();  LCD_Init();  LCD_Clear(BLUE);  temp = DigitalValueConversion();  POINT_COLOR=RED;//设置字体为红色   LCD_ShowString(30,50,200,16,16,"WarShip STM32");      LCD_ShowString(30,70,200,16,16,"Temperature TEST");   LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");  LCD_ShowString(30,110,200,16,16,"2015/1/14");  LCD_ShowString(30,140,200,16,16,"TEMPERATE: 00.00C");  while(1)  {  temp = DigitalValueConversion();  LCD_ShowNum(30+11*8,140,temp/100,2,16);  LCD_ShowNum(30+14*8,140,temp%100,2,16);  delay_ms(150);  }
}  

程序运行结果

基于STM32战舰开发板的内部温度传感器实验相关推荐

  1. 基于STM32战舰开发板的USMART调试组件的使用

    基于STM32战舰开发板的USMART调试组件的使用 USMART调试组件是什么? USMART是正点原子团队为其STM32开发平台开发的一种类似linux的shell的调试工具.具体工作过程是通过串 ...

  2. 基于stm32物联网开发板(1)

    基于stm32物联网开发板(1)   本开发板采用了STM32F103RET6作为核心CPU,72MHZ工作频率,512KB flash,64KB Sram.本开发平台外设模块有ESP8266 WIF ...

  3. 基于stm32物联网开发板(2)--LCD屏幕

    基于stm32物联网开发板(2)–LCD屏幕 LCD应用展示: LCD屏幕应用 1.概述 屏幕尺寸为1.3寸,分辨率240*240,颜色格式RGB565,驱动IC:ST7789VW: 超大可视角度:大 ...

  4. 基于stm32物联网开发板(3)--SYN6288语音模块

    基于stm32物联网开发板(3)–SYN6288语音模块 1.SYN6288语音模块展示示例 SYN6288语音模块 2.概述   SYN6288-A语音合成模块是一款性价比更高,效果更自然的一款中高 ...

  5. 【STM32F103ZE】TOF250(TTL)基于STM32系列开发板的运用

    目录 @[TOC](目录) 一.前言 二.硬件准备 二.软件准备 三.硬件接线图 四.例程源码 五.烧录说明 5.1 烧录接线示意图 5.2 烧录动态图 六.结果输出 一.前言 此片文章主要介绍如果通 ...

  6. *基于RT-Thread的战舰开发板连接Onenent云平台(学习笔记)**

    基于RT-Thread的战舰开发板连接Onenent云平台(学习笔记) 摘要:本文主要是我在使用正点原子开发板在rt_thread框架下连接onenet云平台的学习笔记.此文主要介绍配置步骤和开发过程 ...

  7. SSI技术的前端动态实现(AJAX+SSI,适用于任何系统,包括搭载嵌入式RTOS的STM32系列开发板)

    SSI技术的前端动态实现(AJAX+SSI,适用于任何系统,包括搭载嵌入式RTOS的STM32系列开发板) 前言 RTOS简述及开发困难所在 开发环境 详细的解决方案 SSI初加载 基础的动态操作 伪 ...

  8. 基于易灵思开发板RiscV的调试流程

    基于易灵思开发板RiscV的调试流程 一.相关环境准备 1.软件Install 2.硬件Device 二.硬件环境搭建 1.开发板连接 2.下载代码到开发板 三.软件环境搭建 1.启动Eclipse软 ...

  9. 基于全志A33开发板linux系统移植学习记录(Boot0)

    基于全志A33开发板linux系统移植学习记录 第一章 Boot0基于ARMGCC的编译与修改 文章目录 基于全志A33开发板linux系统移植学习记录 前言 一.全志A33简介以及上电引导流程 二. ...

  10. 基于MSP430G2553官方开发板的音乐播放器

    基于MSP430G2553官方开发板的音乐播放器 实现目标 硬件资源 芯片资源使用情况 外接硬件 程序实现 开发环境配置 各部分硬件驱动 主循环功能实现 实现目标 实现以蜂鸣器为播放设备,能够对简谱乐 ...

最新文章

  1. Unity InvalidOperationException: out of sync错误
  2. Oracle中nolog干什么用的,在oracle中,sqlplus / nolog是做什么用的
  3. Py之textgenrnn:textgenrnn库的简介、安装、使用方法详细攻略
  4. c++ 调用cmd命令行函数 可隐藏黑框 四种方法总结
  5. Hadoop Hive导入数据命令
  6. LeetCode 1634. 求两个多项式链表的和
  7. 开源搜索引擎solr4.0+tomcat7实现中文分词
  8. 10分钟虚拟设备接入阿里云IoT平台实战
  9. solr的多条件组合查询和solr的范围查询【转】
  10. 语音自训练平台技术详解,快速训练专属语音识别模型
  11. LeetCode【709. 转换成小写字母】
  12. Android中关于Task的一些认识
  13. php 小米路由器_云水日记-捣鼓小米路由器开发版本
  14. 自然语言理解gpt_GPT-3:自然语言处理的创造潜力
  15. Fragstats4.2之计算景观格局指数(一)
  16. 洛谷题解:P1007 独木桥
  17. 7月编程排行榜新鲜出炉,再次上演神仙打架!
  18. Java架构师之路:从Java码农到年薪八十万的架构师
  19. PHP删除字符串中的空格和换行符终极方法
  20. matlab三维数据切片二维

热门文章

  1. 金山云服务器e1型,金山云-文档中心-重装系统
  2. 从底层看android5.0系统的启动过程
  3. 小米账号登陆无法连接服务器,登录小米账号显示,无法连接网络,怎么回事?...
  4. linux——alsa中多个声卡设备时打开某一指定声卡的PCM设备
  5. 基于专利多属性融合的技术主题划分方法研究
  6. 动态ActionForm
  7. 聚合物/硅胶色谱填粒径1.7μm到50μm
  8. cmd关闭计算机指令,取消CMD自动关机的命令是什么
  9. linux foxit,Foxit PDF SDK
  10. 解决:启动word等office相关软件时,比较慢,会卡在一步Foxit PDF Creator COM Add-in很久