cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F765 ADC reading on channel individual at a time

BFlin.1
Associate II
 
3 REPLIES 3

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 Venmo
Up vote any posts that you find helpful, it shows what's working..
LCE
Principal

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

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