Skip to main content
This topic has been closed for replies.

3 replies

Tesla DeLorean
Guru
April 6, 2022

It is architected to read multiple channels in a looping fashion into a DMA buffer, with little user interaction and waiting.

You want individual channel sampling, perhaps look at the Injected method.

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
LCE
Principal II
April 7, 2022

Here's my quick (CubeMX and HAL) and not too smart (polling... meh... & CubeMX and HAL :D ) version for F767:

/* Includes ------------------------------------------------------------------*/
#include "adc.h"
 
 
ADC_HandleTypeDef hadc1;
 
float TemperatureMCU = 0.0f;
 
 
/* read internal ADC channel */
HAL_StatusTypeDef ADC1_GetAdcVal(uint32_t channel, uint16_t *u16AdcVal)
{
	if( ADC1_ChannelSelect(channel) != HAL_OK ) return HAL_ERROR;
	if( HAL_ADC_Start(&hadc1) != HAL_OK ) return HAL_ERROR;
	if( HAL_ADC_PollForConversion(&hadc1, ADC_TIMEOUT_TEMP_MS) != HAL_OK ) return HAL_ERROR;
	*u16AdcVal = (uint16_t)HAL_ADC_GetValue(&hadc1);
	if( HAL_ADC_Stop(&hadc1) != HAL_OK ) return HAL_ERROR;
 
	return HAL_OK;
}
 
 
/* read internal temperature sensor */
HAL_StatusTypeDef ADC1_GetTempVal(uint16_t *u16TempVal, float *flTempVal)
{
	uint32_t u32AdcVal = 0;
	float flAdcVal = 0.0f;
 
	if( ADC1_ChannelSelect(ADC_CHANNEL_TEMPSENSOR) != HAL_OK ) return HAL_ERROR;
	if( HAL_ADC_Start(&hadc1) != HAL_OK ) return HAL_ERROR;
	if( HAL_ADC_PollForConversion(&hadc1, ADC_TIMEOUT_TEMP_MS) != HAL_OK ) return HAL_ERROR;
	u32AdcVal = HAL_ADC_GetValue(&hadc1);
	*u16TempVal = (uint16_t)u32AdcVal;
	if( HAL_ADC_Stop(&hadc1) != HAL_OK ) return HAL_ERROR;
 
	/* calculate temperature, see reference manual */
	flAdcVal = (float)u32AdcVal * ADC_VOLT_PER_LSB;
	flAdcVal -= (float)ADC_TEMP_SENSE_V25DEG;
	flAdcVal /= (float)ADC_TEMP_SENSE_AVG_SLOPE;
	flAdcVal += (float)25.0;
	*flTempVal = flAdcVal;
 
	return HAL_OK;
}
 
 
/* ADC channel select */
HAL_StatusTypeDef ADC1_ChannelSelect(uint32_t Channel)
{
	ADC_ChannelConfTypeDef sConfig = { 0 };
 
	sConfig.Channel 		= Channel;
	sConfig.Rank 			= ADC_REGULAR_RANK_1;
	sConfig.SamplingTime 	= ADC_SAMPLETIME_3CYCLES;
	sConfig.Offset 			= 0;
	if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
	{
		uart_printf("Error HAL_ADC_ConfigChannel()\n\r");
		return HAL_ERROR;
	}
 
	return HAL_OK;
}
 
 
/**
 * @brief ADC1 Initialization Function
 * @param None
 * @retval None
 */
void MX_ADC1_Init(void)
{
	ADC_ChannelConfTypeDef sConfig = {0};
 
	/** 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_DIV8;
	hadc1.Init.Resolution 				= ADC_RESOLUTION_12B;
	hadc1.Init.DataAlign 				= ADC_DATAALIGN_RIGHT;
	hadc1.Init.ScanConvMode 			= ADC_SCAN_DISABLE;
	hadc1.Init.EOCSelection 			= ADC_EOC_SINGLE_CONV;
	hadc1.Init.ContinuousConvMode 		= DISABLE;
	hadc1.Init.NbrOfConversion 			= 1;
	hadc1.Init.DiscontinuousConvMode 	= DISABLE;
	//hadc1.Init.NbrOfDiscConversion 		= 0;
	hadc1.Init.ExternalTrigConv 		= ADC_SOFTWARE_START;
	hadc1.Init.ExternalTrigConvEdge 	= ADC_EXTERNALTRIGCONVEDGE_NONE;
	hadc1.Init.DMAContinuousRequests 	= DISABLE;
	if (HAL_ADC_Init(&hadc1) != HAL_OK)
	{
		Error_Handler_FL(__FILE__, __LINE__);
	}
 
	/** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
	*/
	sConfig.Channel 		= ADC_CHANNEL_9;
#if(0)
	sConfig.Channel 		= ADC_CHANNEL_3;
	sConfig.Channel 		= ADC_CHANNEL_VREFINT;
	sConfig.Channel 		= ADC_CHANNEL_TEMPSENSOR;
#endif
	sConfig.Rank 			= ADC_REGULAR_RANK_1;
	sConfig.SamplingTime 	= ADC_SAMPLETIME_3CYCLES;
	sConfig.Offset 			= 0;
	if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
	{
		Error_Handler_FL(__FILE__, __LINE__);
	}
 
}
 
 
/**
* @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)
	{
		/* Peripheral clock enable */
		__HAL_RCC_ADC1_CLK_ENABLE();
 
#if( 0 )
		__HAL_RCC_GPIOA_CLK_ENABLE();
		/** ADC1 GPIO Configuration
			PA3		------> ADC1_IN3
		*/
		GPIO_InitStruct.Pin 	= GPIO_PIN_3;
		GPIO_InitStruct.Mode 	= GPIO_MODE_ANALOG;
		GPIO_InitStruct.Pull 	= GPIO_NOPULL;
		HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
#endif
 
		__HAL_RCC_GPIOB_CLK_ENABLE();
		/** ADC1 GPIO Configuration
			PB1		------> ADC1_IN9
		*/
		GPIO_InitStruct.Pin 	= GPIO_PIN_1;
		GPIO_InitStruct.Mode 	= GPIO_MODE_ANALOG;
		GPIO_InitStruct.Pull 	= GPIO_NOPULL;
		HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
	}
}
 
 
/**
* @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)
	{
		/* Peripheral clock disable */
		__HAL_RCC_ADC1_CLK_DISABLE();
 
		/**ADC1 GPIO Configuration
		PA0	------> ADC1_IN0
		PA3	------> ADC1_IN3
		*/
		HAL_GPIO_DeInit(GPIOA, GPIO_PIN_0|GPIO_PIN_3);
 
		/* ADC1 DMA DeInit */
		HAL_DMA_DeInit(hadc->DMA_Handle);
	}
}
 

LCE
Principal II
April 7, 2022

The above code is written in an editor with TAB = 4 spaces, sorry for that ugly piece...