关于STM32G030C8T6的ADC与芯片内部温度采集

一、具体需求
  1. 使用ADC的通道5采集外部输入的电压信号
  2. 使用 芯片的内部温度传感器采集温度
二、Cubemx的具体配置

由于有两路ADC,使用DMA+多通道扫描的方式,配置了以下2个通道:
在这里插入图片描述
在这里插入图片描述
G0系列的ADC在多通道扫描有两种模式:

  • Sequencer fully configurable
  • Sequencer not fully configurable
    在使用Sequencer fully configurable方式时,最多支持8个序列通道,只有ADC_IN0~ADC_IN14通道才可以使用这种模式,这个要特别注意一下,但我们现在使用到的只要通道5和温度采集通道(内部与12通道是相连的),所以这里两种方式都是可以使用的。
    在这里插入图片描述
    在这里插入图片描述在这里插入图片描述
    在这里插入图片描述
    配置写成后生成工程。
三、MDK代码
  1. 生成的stm32g0xx_hal_msp.c下关于ADC的初始化部分
/**
* @brief ADC MSP Initialization
* This function configures the hardware resources used in this example
* @param hadc: ADC handle pointer
* @retval None
*/
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(hadc->Instance==ADC1)
  {
  /* USER CODE BEGIN ADC1_MspInit 0 */

  /* USER CODE END ADC1_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_ADC_CLK_ENABLE();

    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**ADC1 GPIO Configuration
    PA5     ------> ADC1_IN5
    */
    GPIO_InitStruct.Pin = ADC_CDS_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(ADC_CDS_GPIO_Port, &GPIO_InitStruct);

    /* ADC1 DMA Init */
    /* ADC1 Init */
    hdma_adc1.Instance = DMA1_Channel1;
    hdma_adc1.Init.Request = DMA_REQUEST_ADC1;
    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_LOW;
    if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)
    {
      Error_Handler();
    }

    __HAL_LINKDMA(hadc,DMA_Handle,hdma_adc1);

  /* USER CODE BEGIN ADC1_MspInit 1 */

  /* USER CODE END ADC1_MspInit 1 */
  }

}

/**
* @brief ADC MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param hadc: ADC handle pointer
* @retval None
*/
void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc)
{
  if(hadc->Instance==ADC1)
  {
  /* USER CODE BEGIN ADC1_MspDeInit 0 */

  /* USER CODE END ADC1_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_ADC_CLK_DISABLE();

    /**ADC1 GPIO Configuration
    PA5     ------> ADC1_IN5
    */
    HAL_GPIO_DeInit(ADC_CDS_GPIO_Port, ADC_CDS_Pin);

    /* ADC1 DMA DeInit */
    HAL_DMA_DeInit(hadc->DMA_Handle);
  /* USER CODE BEGIN ADC1_MspDeInit 1 */

  /* USER CODE END ADC1_MspDeInit 1 */
  }

}

  1. 生成的main.c下注意DMA与ADC的部分
/**
  * Enable DMA controller clock
  */
static void MX_DMA_Init(void)
{

  /* DMA controller clock enable */
  __HAL_RCC_DMA1_CLK_ENABLE();

  /* DMA interrupt init */
  /* DMA1_Channel1_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);

}
/**
  * @brief ADC1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_ADC1_Init(void)
{

  /* USER CODE BEGIN ADC1_Init 0 */

  /* USER CODE END ADC1_Init 0 */

  ADC_ChannelConfTypeDef sConfig = {0};

  /* USER CODE BEGIN ADC1_Init 1 */

  /* USER CODE END ADC1_Init 1 */
  /** 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;
  hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.ScanConvMode = ADC_SCAN_SEQ_FIXED;
  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc1.Init.LowPowerAutoWait = DISABLE;
  hadc1.Init.LowPowerAutoPowerOff = DISABLE;
  hadc1.Init.ContinuousConvMode = ENABLE;
  hadc1.Init.NbrOfConversion = 1;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc1.Init.DMAContinuousRequests = ENABLE;
  hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  hadc1.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_12CYCLES_5;
  hadc1.Init.OversamplingMode = DISABLE;
  hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_5;
  sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC1_Init 2 */

  /* USER CODE END ADC1_Init 2 */

}
  1. 添加adc.c文件
/**
  ******************************************************************************
  * @file    pwm.c
  * @author  深圳市沃瑞珂科技有限公司--嵌入式开发团队
             SHENZHEN WRC Application Team
  * @version V1.0.0
  * @date    2022-04-19
  * @brief   CHY-6YH-JK板子的adc相关操作与初始化
  ******************************************************************************
  */
#include "adc.h"
#include "delay.h"

extern ADC_HandleTypeDef hadc1;
extern DMA_HandleTypeDef hdma_adc1;

#define  ADC_VALUE_NUM   32
#define  ADC_CHANNEL_NUM  2

__IO uint16_t adcCovValueBuff[ADC_VALUE_NUM][ADC_CHANNEL_NUM] = {0};	//存放ADC的值ADC_CHANNEL_NUM通道  每个通道存放30个值,由DMA循环写入
uint16_t adcAverageBuff[ADC_CHANNEL_NUM] = {0};	                                    //对每个通道30个ADC值取平均值
 
/**
* @brief  CDS ADC Init.
* @param  None
* @retval None
*/
void CDS_ADC_Init(void)
{ 
	HAL_ADCEx_Calibration_Start(&hadc1);					 //校准ADC
	delay_ms(100);
	HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adcCovValueBuff, ADC_VALUE_NUM*ADC_CHANNEL_NUM);
}

//获得ADC值
//ch: 通道值 0~16,取值范围为:ADC_CHANNEL_0~ADC_CHANNEL_16
//返回值:转换结果
uint16_t Get_Adc_value(uint8_t ch)   
{
	uint32_t sum = 0;
	
    if((ch > ADC_CHANNEL_NUM) ||(ch == 0))  return -1;
	
	for(uint8_t count = 0; count < ADC_VALUE_NUM; count++)
	{
		sum += adcCovValueBuff[count][ch-1];
	}
	
	adcAverageBuff[ch-1] = sum / ADC_VALUE_NUM;
    sum = 0;
	
	return adcAverageBuff[ch-1];
}


float Get_MCU_Temperature(void)   
{
	uint32_t sum = 0;
	float Vol_Value=0;
	float Temperature=0;
	uint8_t TEMP_CH;
	uint16_t TS_CAL1;
	
	TEMP_CH = TEMP_NUMBER;
	
	if((TEMP_CH > ADC_CHANNEL_NUM) ||(TEMP_CH == 0))  return -1;
	
	for(uint8_t count = 0; count < ADC_VALUE_NUM; count++)
	{
		sum += adcCovValueBuff[count][TEMP_CH-1];
	}
	
	adcAverageBuff[TEMP_CH-1] = sum / ADC_VALUE_NUM;
	
	TS_CAL1 = *(__IO uint16_t *)(0x1FFF75A8);
	Temperature = (30.0f) / (TS_CAL1) * ((float) adcAverageBuff[TEMP_CH-1] - TS_CAL1) + 30.0f;

	
	return Temperature;
}

/**
  ******************************************************************************
  * @file    adc.h
  * @author  深圳市沃瑞珂科技有限公司--嵌入式开发团队
             SHENZHEN WRC Application Team
  * @version V1.0.0
  * @date    2022-04-19
  * @brief   CHY-6YH-JK板子的adc相关操作与初始化
  ******************************************************************************
  */
#ifndef __adc_H__
#define __adc_H__

#ifdef __cplusplus
 extern "C" {
#endif

#include <stdarg.h>
#include <stdio.h>
#include "main.h" 

#define CSD_NUMBER  1
#define TEMP_NUMBER 2

/**
* @brief  CDS ADC Init.
* @param  None
* @retval None
*/
void CDS_ADC_Init(void);
uint16_t Get_Adc_value(uint8_t ch);
float Get_MCU_Temperature(void);


#ifdef __cplusplus
}
#endif
#endif

四、关于温度的计算

在这里插入图片描述
在这里插入图片描述

	TS_CAL1 = *(__IO uint16_t *)(0x1FFF75A8);
	Temperature = (30.0f) / (TS_CAL1) * ((float) adcAverageBuff[TEMP_CH-1] - TS_CAL1) + 30.0f;

在这里插入图片描述

  • 3
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值