该用户从未签到
论坛元老
- 最后登录
- 2021-11-17
|
本帖最后由 队长shiwo 于 2017-7-27 21:39 编辑
使用ADC1的ADC_CHANNEL_TEMPSENSOR;//ADC1 内部温度传感器通道和ADC_CHANNEL_VREFINT;//ADC1 内部参考电压通道来实现双通道ADC的转换,
内部温度传感器特性:
支持的温度范围: -40 °C 到 125 °C
精度: ±1.5 °C
使用以下公式计算温度:
温度(单位为 °C) = {(VSENSE – V25) / Avg_Slope} + 25
其中:
– V25 = 25 °C 时的 VSENSE 值
– Avg_Slope = 温度与 VSENSE 曲线的平均斜率(以 mV/°C 或 µV/°C 表示)
有关 V25 和 Avg_Slope 实际值的相关信息,请参见数据手册中的电气特性一节。
1、设置 ADC1, 开启内部温度传感器。
在 HAL 库中开启内部温度传感器,只需要将 ADC 通道改为 ADC_CHANNEL_TEMPSENSOR 即可,调用 HAL_ADC_ConfigChannel()函数配置通道的时候,会自动检测如果是温度传感器通道会在函数中设置 TSVREFE 位。
2、读取通道 16 的 AD 值,计算结果。
在设置完之后,我们就可以读取温度传感器的电压值了,得到该值就可以用上面的公式计算温度值了。
内部参考电压:
注意:必须将 TSVREFE 位置 1 才能同时对两个内部通道进行转换: ADC1_IN16(温度传感器)和ADC1_IN17 (VREFINT)。
采用连续扫描模式,DMA循环模式,具体看代码的注释
主要代码:
- /**
- ******************************************************************************
- * File Name : ADC.c
- * Description : This file provides code for the configuration
- * of the ADC instances.
- ******************************************************************************
- 内部温度值计算:
- T(℃) =[(Vsense - V25)/Avg_Slope]+25
- 上式中:
- V25=Vsense 在 25 度时的数值(典型值为: 0.76)。
- Avg_Slope=温度与 Vsense 曲线的平均斜率(单位为 mv/℃或 uv/℃)(典型值为2.5mV/℃)。
- */
- /* Includes ------------------------------------------------------------------*/
- #include "adc.h"
- #include "dma.h"
- /* USER CODE BEGIN 0 */
- #include "lcd.h"
- //ADC_HandleTypeDef ADC1_Handler;
- #define ADC1_NUMOFCHANNEL 2
- /* USER CODE END 0 */
- /* ADC1 init function */
- ADC_HandleTypeDef hadc1;
- void MX_ADC1_Init(void)
- {
- ADC_ChannelConfTypeDef ADC1_ChanConf;
-
- /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) */
- hadc1.Instance = ADC1;
- hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;//分频系数:4分频,APB2=108MHZ, ADC时钟:108/4=27MHZ,不能高于36MHZ,精度会下降的
- hadc1.Init.Resolution = ADC_RESOLUTION_12B; //采样分辨率
- hadc1.Init.ScanConvMode = ENABLE; //扫描模式
- hadc1.Init.ContinuousConvMode = ENABLE; //开启连续转换模式
- hadc1.Init.DiscontinuousConvMode = DISABLE; //不连续采样模式
- hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; //外部触发边沿:无
- hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; //外部触发方式 :软件触发
- hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; //右对齐
- hadc1.Init.NbrOfConversion = ADC1_NUMOFCHANNEL; //规则序列中有多少个转换
- hadc1.Init.DMAContinuousRequests = ENABLE; //开启 DMA 请求连续模式或者单独模式
- hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV; //EOC 标志是否设置 规则转换完成标志
- if (HAL_ADC_Init(&hadc1) != HAL_OK)
- {
- _Error_Handler(__FILE__, __LINE__);
- }
- /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. */
- ADC1_ChanConf.Channel = ADC_CHANNEL_TEMPSENSOR;//ADC1 内部温度传感器通道
- ADC1_ChanConf.Rank = 1; //规则通道中的第1个转换
- ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_144CYCLES; //采样间隔144个周期
- if (HAL_ADC_ConfigChannel(&hadc1, &ADC1_ChanConf) != HAL_OK)
- {
- _Error_Handler(__FILE__, __LINE__);
- }
-
- /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. */
- ADC1_ChanConf.Channel = ADC_CHANNEL_VREFINT;//ADC1 内部参考电压通道
- ADC1_ChanConf.Rank = 2; //规则通道中的第2个转换
- //ADC1_ChanConf.SamplingTime = ADC_SAMPLETIME_144CYCLES;//采样间隔144个周期
- if (HAL_ADC_ConfigChannel(&hadc1, &ADC1_ChanConf) != HAL_OK)
- {
- _Error_Handler(__FILE__, __LINE__);
- }
-
- //HAL_ADC_Start(&hadc1); //开启 ADC1
- }
- __IO uint16_t ADC1_DMA2_Buff[ADC1_NUMOFCHANNEL];
- DMA_HandleTypeDef hdma_adc1;
- void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
- {
- if(adcHandle->Instance==ADC1)
- {
- /* USER CODE BEGIN ADC1_MspInit 0 */
- /* USER CODE END ADC1_MspInit 0 */
- /* ADC1 clock enable */
- __HAL_RCC_ADC1_CLK_ENABLE();
- /* DMA controller clock enable */
- __HAL_RCC_DMA2_CLK_ENABLE();
-
- /* ADC1 DMA Init 看DMA2的各数据流通道映射表:ADC1-DMA2 通道0 数据流0*/
- /* ADC1 Init */
- hdma_adc1.Instance = DMA2_Stream0; // DMA2 数据流0
- hdma_adc1.Init.Channel = DMA_CHANNEL_0; // DMA2 通道0
- hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY; // 外设到内存
- hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE; // 外设地址寄存器不变
- hdma_adc1.Init.MemInc = DMA_MINC_ENABLE; // 内存地址寄存器递增
- hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;// 外设数据宽度为半字
- hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; // 内存数据宽度为半字
- hdma_adc1.Init.Mode = DMA_CIRCULAR; // 工作在循环缓存模式
- hdma_adc1.Init.Priority = DMA_PRIORITY_HIGH; // DMA通道 x拥有高优先级
- hdma_adc1.Init.FIFOMode = DMA_FIFOMODE_DISABLE; // FIFO禁止
- if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)
- {
- _Error_Handler(__FILE__, __LINE__);
- }
- __HAL_LINKDMA(adcHandle,DMA_Handle,hdma_adc1);
- /* ADC1 interrupt Init */
- // HAL_NVIC_SetPriority(ADC_IRQn, 1, 2);
- // HAL_NVIC_EnableIRQ(ADC_IRQn);
-
- /*DMA interrupt init DMA2_Stream0_IRQn interrupt configuration */
- HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 1, 1);
- HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
- /* USER CODE BEGIN ADC1_MspInit 1 */
-
- /* USER CODE END ADC1_MspInit 1 */
- }
- }
- void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle)
- {
- if(adcHandle->Instance==ADC1)
- {
- /* USER CODE BEGIN ADC1_MspDeInit 0 */
- /* USER CODE END ADC1_MspDeInit 0 */
- /* Peripheral clock disable */
- __HAL_RCC_ADC1_CLK_DISABLE();
- /* ADC1 DMA DeInit */
- HAL_DMA_DeInit(adcHandle->DMA_Handle);
- /* ADC1 interrupt Deinit */
- HAL_NVIC_DisableIRQ(ADC_IRQn);
- /* USER CODE BEGIN ADC1_MspDeInit 1 */
- /* USER CODE END ADC1_MspDeInit 1 */
- }
- }
- /* USER CODE BEGIN 1 */
- uint16_t Get_Adc(uint32_t channel)
- {
- // ADC_ChannelConfTypeDef ADC1_ChanConf;
- // ADC1_ChanConf.Channel=channel; //通道
- // ADC1_ChanConf.Rank=1; //第 1 个序列,序列 1
- // ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES; //采样时间
- // ADC1_ChanConf.Offset=0;
- // HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf); //通道配置
- HAL_ADC_Start(&hadc1); //开启 ADC1
- HAL_ADC_PollForConversion(&hadc1,10); //轮询转换
- return (uint16_t)HAL_ADC_GetValue(&hadc1); //返回最近转换结果
- }
- //获取指定通道的转换值,取 count 次,然后平均
- //channel:获取次数
- //返回值:通道 ch 的 channel 次转换结果平均值
- uint16_t Get_Adc_Average(uint32_t channel,uint8_t count)
- {
- uint32_t temp_val=0;
- uint8_t t;
- for(t=0;t<count;t++)
- {
- temp_val+=Get_Adc(channel);
- //delay_ms(5);
- }
- return temp_val/count;
- }
- short Get_Temprate_Value(void)
- {
- short result;
- double temperate;
- //uint32_t adcx;
-
- //adcx=Get_Adc_Average(ADC_CHANNEL_TEMPSENSOR,10);
- //读取内部温度传感器通道,10 次取平均
- temperate=(float)(ADC1_DMA2_Buff[0] *(3.3/4096)); //电压值adcx
- temperate=(temperate-0.76)/0.0025 + 25; //转换为温度值
- result=temperate*=100; //扩大 100 倍.
- return result;
- }
- short Get_Vref_Value(void)
- {
- uint16_t VRef;
- VRef = (ADC1_DMA2_Buff[1] * VREF)/(MAX_CONVERTED_VALUE);
- return VRef;
- }
- //显示内部温度和内部参考电压值
- uint8_t Show_flag = 0;
- void Show_TempVref_Value(void)
- {
- /*内部温度值计算:
- T(℃) =[(Vsense - V25)/Avg_Slope]+25, V25=Vsense 在 25 度时的数值(典型值为: 0.76)。
- Avg_Slope=温度与 Vsense 曲线的平均斜率(单位为 mv/℃或 uv/℃)(典型值为2.5mV/℃)。*/
-
- // JTemp = ((((ADC1_DMA2_Buff[0] * VREF)/MAX_CONVERTED_VALUE) - V25_TEMP) * 10 / AVG_SLOPE) + AMBIENT_TEMP;
- short temp;
- char Tmp_TempBuf[3]={0};
- char *Tmp_TempBuff = Tmp_TempBuf;
- char Tmp_VrefBuf[3]={0};
- char *Tmp_VrefBuff = Tmp_VrefBuf;
- if(Show_flag == 0)//只显示一次
- {
- Show_flag = 1;
-
- LCD12896_Display_12x12str(5,12, "CPU:"); //
- HAL_Delay(200);
- LCD12896_Display_12x12str(5,36, "温度:"); //
- HAL_Delay(200);
- LCD12896_Display_12x12str(5,92,"."); //显示小数点
- HAL_Delay(200);
- LCD12896_Display_12x12str(5,108, "`C"); //显示`C
- HAL_Delay(200);
-
- LCD12896_Display_12x12str(7,12, "参考电压:"); //
- HAL_Delay(200);
- LCD12896_Display_12x12str(7,84,"."); //显示小数点
- HAL_Delay(200);
- LCD12896_Display_12x12str(7,108, "V"); //
- HAL_Delay(200);
-
- }
-
- temp=Get_Temprate_Value(); //得到温度值
- if(temp < 0)
- {
- temp = -temp;
- LCD12896_Display_12x12str(5,68,"-"); //显示负号
- }
- else
- LCD12896_Display_12x12str(5,68," "); //无符号
- Tmp_TempBuff[0]=temp/100/10 + 48 +'\0';
- Tmp_TempBuff[1]=temp/100%10 + 48 +'\0';
- LCD12896_Display_12x12str(5,76,&Tmp_TempBuff[0]); //显示整数部分
- //HAL_Delay(20);
- LCD12896_Display_12x12str(5,84,&Tmp_TempBuff[1]); //显示整数部分
- //HAL_Delay(20);
- Tmp_TempBuff[2]=temp%100/10 + 48 +'\0';
- LCD12896_Display_12x12str(5,100,&Tmp_TempBuff[2]); //显示小数部分
- HAL_Delay(20);
-
- temp = Get_Vref_Value();
- Tmp_VrefBuff[0]=temp/1000 + 48 +'\0';
- LCD12896_Display_12x12str(7,76,&Tmp_VrefBuff[0]); //显示整数部分
- //HAL_Delay(20);
- Tmp_VrefBuff[1]=temp/100%10 + 48 +'\0';
- Tmp_VrefBuff[2]=temp%100/10 + 48 +'\0';
- LCD12896_Display_12x12str(7,92,&Tmp_VrefBuff[1]); //显示小数部分
- //HAL_Delay(20);
- LCD12896_Display_12x12str(7,100,&Tmp_VrefBuff[2]); //显示小数部分
- HAL_Delay(20);
-
- }
- /* USER CODE END 1 */
- /**
- * @}
- */
- /**
- * @}
- */
- /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
复制代码 1s读取一次DMA BUFF的值来转换:
- while (1)
- {
- /* USER CODE END WHILE */
- /* USER CODE BEGIN 3 */
-
-
-
-
- if(TempVref_count >= TEMP_REFRESH_PERIOD)//1s
- {
- Show_TempVref_Value();
- TempVref_count = 0;
-
- }
-
-
- }
复制代码 CPU周围的温度在36度到40度左右,具体看CPU执行的任务程度吧,
内部参考电压维持在1.20V--1.21V
|
评分
-
查看全部评分
|