基于STM32HAL库使用ADC采样方式,检测电压值与自带芯片温度值

目录

 

概述

1、原理图

2、STM32CubeMx工具配置

3、代码

1、串口(串口重映射打印配置)

2、ADC

3、main

4、运行结果


概述

      主控芯片:STM32L051C8T6

      IDE: keil + STM32CubeMx



1、原理图

分压电阻计算公式:

BAT_ADC=R26/(R26+R27)

2、STM32CubeMx工具配置

3、代码

1、串口(串口重映射打印配置)

usart.c文件

/* USER CODE BEGIN 0 */
#include "stdio.h"
/* USER CODE END 0 */



/* USER CODE BEGIN 1 */
#ifdef __GNUC__
  /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
     set to 'Yes') calls __io_putchar() */
  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
  #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
/**
  * @brief  Retargets the C library printf function to the USART.
  * @param  None
  * @retval None
  */
PUTCHAR_PROTOTYPE
{
  /* Place your implementation of fputc here */
  /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
 
  return ch;
}
/* USER CODE END 1 */

2、ADC

adc.c文件

/* USER CODE BEGIN 1 */
//读取ADC值
uint16_t ADC_GetValue(void)
{
	uint8_t i=0;
	float BAT=0,TEMP=0;
	int32_t AD_T=0,AD_BAT=0;
	
	//采样时间选择最长,更加准确
	//hadc.Init.SamplingTime = ADC_SAMPLETIME_160CYCLES_5;
	
	//开启ADC校准
	HAL_ADCEx_Calibration_Start(&hadc, ADC_SINGLE_ENDED);
	
	//开启ADC转换
	HAL_ADC_Start(&hadc);										//first conv
	//等待转换完成
	if(HAL_ADC_PollForConversion(&hadc, 200)== HAL_OK)
	{
		//获取在当前供电条件下的ADC采样值
		if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc), HAL_ADC_STATE_REG_EOC))
		{
			AD_BAT = HAL_ADC_GetValue(&hadc);
			BAT=(float)((3.3*AD_BAT/4096)*2.5);
		}
	}		
	
	//开启ADC转换
	HAL_ADC_Start(&hadc);										//second conv
	//等待转换完成
	if(HAL_ADC_PollForConversion(&hadc, 200)== HAL_OK)
	{
		//获取在当前供电条件下的ADC采样值
		if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc), HAL_ADC_STATE_REG_EOC))
		{
			AD_T = HAL_ADC_GetValue(&hadc);	//读取ADC通道值
			TEMP=(float)AD_T*(3.3/4096);		//电压值 
			TEMP=(1.43-TEMP)/0.0043+25;		  	//转换为温度值 
			if(TEMP<0)
				TEMP=-TEMP;				
		}
	}
	//停止ADC转换
	HAL_ADC_Stop(&hadc);										//stop conv
	
	printf("\r\nBat_Value=%lf \r\n",BAT);
	printf("**********************\r\n");
	printf("\r\ntemp=%.2f \r\n",TEMP);
	return BAT;
}


/* USER CODE END 1 */

BAT=(float)((3.3*AD_BAT/4096)*2.5);

这里说明一下,计算公式从官方手册找到的,网上很多资料都没怎么说明清楚,导致小白懵逼

先看一下,官方手册电压换算公式吧,^_^ 如下 : 请看下图

 我这里读取的ADC值为:AD_BAT为:1.64V(万用表实测的值),输入的电池电压为4.129V左右,通过上面的计算公式得出,还是可以接受的。(注:公式上有个*2.5V是通过原理图分压系数得出。也就是两个分压电阻的比例刚好是2.5倍)。

adc.h文件

/* USER CODE BEGIN Prototypes */
uint16_t ADC_GetValue(void);
/* USER CODE END Prototypes */

3、main

main.c文件

/* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    ADC_GetValue();
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */

4、运行结果

 

参考文章:(一)https://blog.csdn.net/qq_38410730/article/details/80080660

                  (二)https://blog.51cto.com/5796396/2326418?source=dra

代码

以下是使用STM32 HAL库读取ADC采样并计算电压的示例程序: ```c #include "main.h" #include "stdio.h" ADC_HandleTypeDef hadc1; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_ADC1_Init(void); int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_ADC1_Init(); uint32_t adc_value; float voltage; while (1) { HAL_ADC_Start(&hadc1); // 启动ADC转换 HAL_ADC_PollForConversion(&hadc1, 100); // 等待转换完成 adc_value = HAL_ADC_GetValue(&hadc1); // 获取转换结果 voltage = adc_value * 3.3f / 4096.0f; // 计算电压(假设参考电压为3.3V) printf("ADC value: %d, voltage: %.2fV\r\n", adc_value, voltage); // 输出结果到串口 HAL_Delay(500); } } void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Configure the main internal regulator output voltage */ __HAL_RCC_PWR_CLK_ENABLE(); __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); /** Initializes the CPU, AHB and APB busses clocks */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB busses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) { Error_Handler(); } } static void MX_ADC1_Init(void) { ADC_ChannelConfTypeDef sConfig = {0}; hadc1.Instance = ADC1; hadc1.Init.ScanConvMode = DISABLE; hadc1.Init.ContinuousConvMode = DISABLE; hadc1.Init.DiscontinuousConvMode = DISABLE; hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc1.Init.NbrOfConversion = 1; if (HAL_ADC_Init(&hadc1) != HAL_OK) { Error_Handler(); } sConfig.Channel = ADC_CHANNEL_0; // 选择ADC通道 sConfig.Rank = ADC_REGULAR_RANK_1; sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5; if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) { Error_Handler(); } } static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; __HAL_RCC_GPIOA_CLK_ENABLE(); /*Configure GPIO pin : PA0 */ GPIO_InitStruct.Pin = GPIO_PIN_0; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } ``` 在该程序中,我们使用PA0作为ADC输入引脚,启动连续单次ADC转换模式,并通过串口输出采样电压。需要注意的是,该程序中的参考电压为3.3V,如果使用其他参考电压,需要相应地调整计算公式。另外,ADC采样时间和通道等参数也需要根据实际情况进行配置。
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ch_champion

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值