内部温度传感器简介
测量的温度位置
内部温度传感器集成在芯片中,测量的是芯片的温度。
如何测量对应位置的温度?
温度传感器与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℃,因此内部温度传感器更适合于检测温度的变化,而不是测量绝对的温度。如果需要测量精确的温 度,应该使用一个外置的温度传感器。
内部温度传感器配置流程
内部温度传感器实验代码解析
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_SR状态寄存器中的标志位EOC位代表着“ADC转换工作是否结束”:
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 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战舰开发板的USMART调试组件的使用
下一篇:STM32的ADC实验的原理简介
推荐阅读最新更新时间:2024-11-11 02:39
设计资源 培训 开发板 精华推荐
- 光伏逆变器3V DC转DC单路输出电源
- STM32F411-BORD
- 使用 P 沟道 Mosfet 电路的典型应用稳压器,用于 Tc105 Pfm/Pwm 降压直流/直流控制器
- LT6004 的典型应用 - 双路 1.6V、1 uA 精密轨至轨输入和输出运算放大器
- ESP8266墨水屏驱动板-2.13寸
- LT1072CS8 为离线应用驱动高压 FET 的典型应用
- 温湿度计
- LTC4052-4.2 的典型应用 - 具有过流保护功能的锂离子电池脉冲充电器
- AD9250-FMC-250EBZ,用于 AD9250、2 通道、14 位、250 MSPS 模数转换器的评估板
- LTC3559/LT3559-1 的典型应用 - 具有双降压稳压器的线性 USB 电池充电器