关于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;

在这里插入图片描述

### STM32G030 ADC配置使用教程 #### 一、硬件准备 为了实现STM32G030微控制器上的ADC功能,需准备好相应的开发环境和硬件设备。具体来说,应具备基于STM32G030系列单片机的开发板[^3]。 #### 二、软件配置流程 在启动任何编程工作之前,先要借助STM32CubeMX完成必要的外设初始化设置: - 启动STM32CubeMX并选定目标器件型号为STM32G030F6P6; - 进入到ADC模块设定界面,挑选所需的模拟输入端口作为采样通道,并勾选启用DMA选项以便于后续大批量数据传输操作; - 调整系统时钟分配方案,确认ADC部分获得适当的工作频率支持其正常运作;最后点击生成工程文件按钮获取初步框架代码[^1]。 #### 三、多通道同步采集方法探讨 当涉及到多个传感器信号的同时测量任务时,则可以考虑采用DMA方式来优化效率。这种方式允许CPU在后台继续执行其他指令而不必等待每次A/D变换结束后的中断响应过程。对于该特定芯片而言,在CubeMX里正确开启DMA模式后能够自动处理好连续不断的转换请求并将结果存储至指定缓冲区内待读取[^2]。 #### 四、特殊注意事项说明 如果遇到某些特殊情况比如需要对第16号内部温度感应专用通道进行单独控制的话,则要注意按照HAL库官方文档指示将其标记成“不完全可配置”的状态来进行相应调整。尽管这样做可能会引起IDE界面上显示警告图标,但这并不会影响实际编译出来的固件逻辑有效性[^4]。 ```c // 示例:初始化ADC并启动DMA传输 void MX_ADC_Init(void){ hadc.Instance = ADC; // ...其余省略... } static void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc){ /* 当DMA完成一次完整的ADC采样周期之后触发此回调函数 */ } ```
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值