STM32F103ZET6之内部温度传感器实验
文章目录
前言
对于STM32的学习可分为3个版本。
1.寄存器版本
2.库函数版本
3.HAL库版本
由于个人原因,选择库函数版本来进行STM32的学习。
提示:软件安装等问题,不进行讲解!!!
一、原理
1.简介
2.ADC通道与引脚关系
3.原理图
STM32 有一个内部的温度传感器,可以用来测量 CPU 及周围的温度(TA)。该温度传感器在内部和 ADCx_IN16 输入通道相连接,此通道把传感器输出的电压转换成数字值。温度传感器模拟输入推荐采样时间是 17.1μs。STM32 的内部温度传感器支持的温度范围为:-40~125度。精度比较差,为±1.5℃左右。
二、相关配置
1.相关寄存器
ADC 控制寄存器(ADC_CR1 和 ADC_CR2)
ADC 采样事件寄存器(ADC_SMPR1 和 ADC_SMPR2)
ADC 规则序列寄存器(ADC_SQR1~3)
ADC 寄存器为 ADC 状态寄存器(ADC_SR)
2.电压与温度关系
3.配置步骤
三、程序源码
1.adc.h
代码如下:
#ifndef __ADC_H
#define __ADC_H
#include "sys.h"
void Adc_Init(void);
u16 Get_Adc(u8 ch);
u16 Get_Adc_Average(u8 ch,u8 times);
void T_Adc_Init(void);
short Get_Temperate(void);
#endif
2.adc.c
代码如下:
#include "adc.h"
#include "stm32f10x.h"
#include "delay.h"
void Adc_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
ADC_InitTypeDef ADC_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1, ENABLE);//使能PA时钟和ADC1时钟
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AIN;//模拟输入
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_1;
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
ADC_DeInit(ADC1);//复位ADC
RCC_ADCCLKConfig(RCC_PCLK2_Div6);//72M/6<14M 分频因子
ADC_InitStruct.ADC_ContinuousConvMode=DISABLE;//连续模式
ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right;//对齐设置
ADC_InitStruct.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;//硬件触发
ADC_InitStruct.ADC_Mode=ADC_Mode_Independent;//设置为独立模式
ADC_InitStruct.ADC_NbrOfChannel=1;//顺序进行规则转换的ADC 通道的数目
ADC_InitStruct.ADC_ScanConvMode=DISABLE;
ADC_Init(ADC1, &ADC_InitStruct);
ADC_Cmd(ADC1, ENABLE);//使能ADC1
ADC_ResetCalibration(ADC1);//开启复位校准
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);//开启AD校准
while(ADC_GetCalibrationStatus(ADC1));
}
u16 Get_Adc(u8 ch)
{
ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5);//配置规则通道
ADC_SoftwareStartConvCmd(ADC1, ENABLE);//开启软件转换
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));//等待转换完成
return ADC_GetConversionValue(ADC1);
}
u16 Get_Adc_Average(u8 ch,u8 times)//求平均值
{
u32 temp_val=0;
u8 t;
for(t=0;t<times;t++)
{
temp_val+=Get_Adc(ch);
delay_ms(5);
}
return temp_val/times;
}
void T_Adc_Init(void)
{
ADC_InitTypeDef ADC_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1, ENABLE);//使能PA时钟和ADC1时钟
ADC_DeInit(ADC1);//复位ADC
RCC_ADCCLKConfig(RCC_PCLK2_Div6);//72M/6<14M 分频因子
ADC_InitStruct.ADC_ContinuousConvMode=DISABLE;//独立模式
ADC_InitStruct.ADC_DataAlign=ADC_DataAlign_Right;//对齐设置
ADC_InitStruct.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;//硬件触发
ADC_InitStruct.ADC_Mode=ADC_Mode_Independent;//设置为独立模式
ADC_InitStruct.ADC_NbrOfChannel=1;//顺序进行规则转换的ADC 通道的数目
ADC_InitStruct.ADC_ScanConvMode=DISABLE;
ADC_Init(ADC1, &ADC_InitStruct);
ADC_TempSensorVrefintCmd(ENABLE);//打开内部温度传感器
ADC_Cmd(ADC1, ENABLE);//使能ADC1
ADC_ResetCalibration(ADC1);//开启复位校准
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);//开启AD校准
while(ADC_GetCalibrationStatus(ADC1));
}
short Get_Temperate(void)
{
u32 adcx;
short result;
double temperate;
adcx=Get_Adc_Average(ADC_Channel_16,20);
temperate=(float)adcx*(3.3/4096);//电压值
temperate=(1.43-temperate)/0.0043+25;//转换为温度值
result=temperate*100;
return result;
}
3.main.c
代码如下:
#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h"
#include "adc.h"
int main(void)
{
float temp;
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
uart_init(115200); //串口初始化为115200
LED_Init(); //LED端口初始化
LCD_Init();
T_Adc_Init();
POINT_COLOR=RED;//设置字体为红色
LCD_ShowString(60,50,200,16,16,"chen");
//显示提示信息
POINT_COLOR=BLUE;//设置字体为蓝色
LCD_ShowString(30,140,200,16,16,"TEMPERATE: 00.00C");
while(1)
{
temp=Get_Temperate(); //得到温度值
if(temp<0)
{
temp=-temp;
LCD_ShowString(30+10*8,140,16,16,16,"-"); //显示负号
}
else
LCD_ShowString(30+10*8,140,16,16,16," "); //无符号
LCD_ShowxNum(30+11*8,140,temp/100,2,16,0); //显示整数部分
LCD_ShowxNum(30+14*8,140,(int)temp%100,2,16, 0X80); //显示小数部分
LED0=!LED0;
delay_ms(250);
}
}
实验结果
总结
1.看完视频,一定自己写一遍程序。
2.烧写程序前,对程序进行分析,推理实验现象。
3.若实验现象与推理不一致,一定要认真分析程序。