原贴链接:http://www.openedv.com/forum.php?mod=viewthread&tid=31
3.14内部温度传感器实验这一节我们将向大家介绍STM32的内部温度传感器。本节将利用STM32的内部温度传感器来显示温度值,并在TFTLCD模块上显示出来。本节分为如下几个部分: 3.14.1 STM32 内部温度传感器简介 3.14.2 硬件设计 3.14.3 软件设计 3.14.4 下载与测试
3.14.1 STM32 内部温度传感器简介 STM32有一个内部的温度传感器,可以用来测量CPU及周围的温度(TA)。该温度传感器在内部和ADCx_IN16输入通道相连接,此通道把传感器输出的电压转换成数字值。温度传感器模拟输入推荐采样时间是17.1μs。 STM32的内部温度传感器支持的温度范围为:-40~125度。精度比较差,为±1.5℃左右。 STM32内部温度传感器的使用很简单,只要设置一下内部ADC,并激活其内部通道就差不多了。关于ADC的设置,我们在上一节已经进行了详细的介绍,这里就不再多说。接下来我们介绍一下和温度传感器设置相关的2个地方。 第一个地方,我们要使用STM32的内部温度传感器,必须先激活ADC的内部通道,这里通过ADC_CR2的AWDEN位(bit23)设置。设置该位为1则启用内部温度传感器。 第二个地方,STM32的内部温度传感器固定的连接在ADC的通道16上,所以,我们在设置好ADC之后只要读取通道16的值,就是温度传感器返回来的电压值了。根据这个值,我们就可以计算出当前温度。计算公式如下: T(℃)={(V25-Vsense)/Avg_Slope}+25 该式中: V25=Vsense在25度时的数值(典型值为:1.43)。 Avg_Slope=温度与Vsense曲线的平均斜率(单位为mv/℃或uv/℃)(典型值为4.3Mv/℃)。 利用以上公式,我们就可以方便的计算出当前温度传感器的温度了。 现在,我们就可以总结一下STM32内部温度传感器使用的步骤了,如下: 设置ADC,并开启ADC_CR2的AWDEN位。 关于如何设置ADC,上一节已经介绍了,我们采用与上一节一样的设置,这里我们只要增加使能AWDEN位这一句就可以了。 读取通道16的AD值,计算结果。 在设置完之后,我们就可以读取温度传感器的电压值了,得到该值就可以用上面的公式计算温度值了。
3.14.2 硬件设计
这部分硬件只需要1个TFTLCD模块,其他的就不需要了。TFTLCD的连接在前面已经介绍过了,这里就不再介绍了。
3.14.3 软件设计
打开上一节的工程,打开adc.c,修改Adc_Init函数代码如下: void Adc_Init(void) { //先初始化IO口 RCC->APB2ENR|=1<<2; //使能PORTA口时钟 GPIOA->CRL&=0XFFFF0000;//PA0 1 2 3 anolog输入 //通道10/11设置 RCC->APB2ENR|=1<<9; //ADC1时钟使能 RCC->APB2RSTR|=1<<9; //ADC1复位 RCC->APB2RSTR&=~(1<<9);//复位结束 RCC->CFGR&=~(3<<14); //分频因子清零 //SYSCLK/DIV2=12M ADC时钟设置为12M,ADC最大时钟不能超过14M! //否则将导致ADC准确度下降! RCC->CFGR|=2<<14; ADC1->CR1&=0XF0FFFF; //工作模式清零 ADC1->CR1|=0<<16; //独立工作模式 ADC1->CR1&=~(1<<8); //非扫描模式 ADC1->CR2&=~(1<<1); //单次转换模式 ADC1->CR2&=~(7<<17); ADC1->CR2|=7<<17; //软件控制转换 ADC1->CR2|=1<<20; //使用用外部触发(SWSTART)!!! 必须使用一个事件来触发 ADC1->CR2&=~(1<<11); //右对齐 ADC1->CR2|=1<<23; //使能温度传感器
ADC1->SQR1&=~(0XF<<20); ADC1->SQR1&=0<<20; //1个转换在规则序列中 也就是只转换规则序列1 //设置通道0~3的采样时间 ADC1->SMPR2&=0XFFFFF000;//通道0,1,2,3采样时间清空 ADC1->SMPR2|=7<<9; //通道3 239.5周期,提高采样时间可以提高精确度 ADC1->SMPR2|=7<<6; //通道2 239.5周期,提高采样时间可以提高精确度 ADC1->SMPR2|=7<<3; //通道1 239.5周期,提高采样时间可以提高精确度 ADC1->SMPR2|=7<<0; //通道0 239.5周期,提高采样时间可以提高精确度 ADC1->SMPR1&=~(7<<18); //清除通道16原来的设置 ADC1->SMPR1|=7<<18; //通道16 239.5周期,提高采样时间可以提高精确度
ADC1->CR2|=1<<0; //开启AD转换器 ADC1->CR2|=1<<3; //使能复位校准 while(ADC1->CR2&1<<3); //等待校准结束 //该位由软件设置并由硬件清除。在校准寄存器被初始化后该位将被清除。 ADC1->CR2|=1<<2; //开启AD校准 while(ADC1->CR2&1<<2); //等待校准结束 //该位由软件设置以开始校准,并在校准结束时由硬件清除 } 这部分代码与上一节的Adc_Init代码几乎一摸一样,我们仅仅在里面增加了 ADC1->CR2|=1<<23; //使能温度传感器 铜过该句使能温度传感器。 然后,我们保存一下该文件,接着打开adc.h,修改文件如下: #ifndef __ADC_H #define __ADC_H //Mini STM32开发板 //ADC 驱动代码 //正点原子@ALIENTEK //2010/6/7
#define ADC_CH0 0 //通道0 #define ADC_CH1 1 //通道1 #define ADC_CH2 2 //通道2 #define ADC_CH3 3 //通道3 #define TEMP_CH 16 //温度传感器通道 void Adc_Init(void); //ADC通道初始化 u16 Get_Adc(u8 ch); //获得某个通道值 #endif 这里我们也只增加了一句,就是宏定义多增加了一个温度传感器通道TEMP_CH。接下来我们就可以开始读取温度传感器的电压了。在test.c文件里面我们修改main函数如下: int main(void) { u16 adcx; float temp; float temperate; Stm32_Clock_Init(9);//系统时钟设置 delay_init(72); //延时初始化 uart_init(72,9600); //串口1初始化 LED_Init(); LCD_Init(); Adc_Init();
POINT_COLOR=RED;//设置字体为红色 LCD_ShowString(60,50,"Mini STM32"); LCD_ShowString(60,70,"TEMPERATE TEST"); LCD_ShowString(60,90,"ATOM@ALIENTEK"); LCD_ShowString(60,110,"2010/6/7"); //显示时间 POINT_COLOR=BLUE;//设置字体为蓝色 LCD_ShowString(60,130,"TEMP_VAL:"); LCD_ShowString(60,150,"TEMP_VOL:0.000V"); LCD_ShowString(60,170,"TEMPERATE:00.00C"); while(1) { adcx=Get_Adc(TEMP_CH); LCD_ShowNum(132,130,adcx,4,16);//显示ADC的值 temp=(float)adcx*(3.3/4096); temperate=temp;//保存温度传感器的电压值 adcx=temp; LCD_ShowNum(132,150,adcx,1,16); //显示电压值整数部分 temp-=(u8)temp; //减掉整数部分 LCD_ShowNum(148,150,temp*1000,3,16);//显示电压小数部分 temperate=(1.43-temperate)/0.0043+25;//计算出当前温度值 LCD_ShowNum(140,170,(u8)temperate,2,16); //显示温度整数部分 temperate-=(u8)temperate; LCD_ShowNum(164,170,temperate*100,2,16);//显示温度小数部分 LED0=!LED0; delay_ms(250); } } 这里同上一节的主函数也大同小异,上面红色部分代码将温度传感器得到的电压值,换算成温度值。然后,我们在TFTLCD模块上显示出来。 代码设计部分就为大家讲解到这里,下面我们开始下载与测试。
3.14.4 下载与测试
在代码编译成功之后,我们通过下载代码到ALIENTEK MiniSTM32开发板上,可以看到LCD显示如下内容:
图3.14.4.1内部温度传感器实验测试图 伴随DS0的不停闪烁,提示程序在运行。大家可以看看你的温度值与实际相差是否很大?(因为芯片会发热,一般会比实际温度稍高一些)
附件:
|