概述
一、具体需求
- 使用ADC的通道5采集外部输入的电压信号
- 使用 芯片的内部温度传感器采集温度
二、Cubemx的具体配置
由于有两路ADC,使用DMA+多通道扫描的方式,配置了以下2个通道:
G0系列的ADC在多通道扫描有两种模式:
- Sequencer fully configurable
- Sequencer not fully configurable
在使用Sequencer fully configurable方式时,最多支持8个序列通道,只有ADC_IN0~ADC_IN14通道才可以使用这种模式,这个要特别注意一下,但我们现在使用到的只要通道5和温度采集通道(内部与12通道是相连的),所以这里两种方式都是可以使用的。
配置写成后生成工程。
三、MDK代码
- 生成的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 */
}
}
- 生成的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 */
}
- 添加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;
最后
以上就是朴实眼睛为你收集整理的关于STM32G030C8T6的ADC与芯片内部温度采集的全部内容,希望文章能够帮你解决关于STM32G030C8T6的ADC与芯片内部温度采集所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复