cancel
Showing results for 
Search instead for 
Did you mean: 

Hello, I am using STM32L053 nucleo board. I am trying to read Multiple ADC Channels but values are not coming correct. Here is my code in details. I am using continuous mode using polling method.

chinmaydixit
Associate II

#include "main.h"

#include<stdio.h>

ADC_HandleTypeDef hadc;

UART_HandleTypeDef huart2;

void SystemClock_Config(void);

static void MX_GPIO_Init(void);

static void MX_USART2_UART_Init(void);

static void MX_ADC_Init(void);

int main(void)

{

 HAL_Init();

 SystemClock_Config();

 MX_GPIO_Init();

 MX_USART2_UART_Init();

 MX_ADC_Init();

 if(HAL_ADC_Start(&hadc) !=HAL_OK)

 {

  Error_Handler();

 }

 while (1)

 {

 if(HAL_ADC_PollForConversion(&hadc, HAL_MAX_DELAY)== HAL_OK)

 {

  raw_1 = HAL_ADC_GetValue(&hadc);

printf("x value=%d",raw_1);

 HAL_Delay(1000);

 }

  else

 {

 Error_Handler();

 }

 if(HAL_ADC_PollForConversion(&hadc, HAL_MAX_DELAY)== HAL_OK)

 {

 raw_2 = HAL_ADC_GetValue(&hadc);

 printf("y value=%d",raw_2);

 HAL_Delay(1000);

 }

 else

 {

 Error_Handler();

 }

}

void SystemClock_Config(void)

{

 RCC_OscInitTypeDef RCC_OscInitStruct = {0};

 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

 RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

 /** Configure the main internal regulator output voltage

 */

 __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

 /** Initializes the RCC Oscillators according to the specified parameters

 * in the RCC_OscInitTypeDef structure.

 */

 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;

 RCC_OscInitStruct.MSIState = RCC_MSI_ON;

 RCC_OscInitStruct.MSICalibrationValue = 0;

 RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_5;

 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;

 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

 {

  Error_Handler();

 }

 /** Initializes the CPU, AHB and APB buses clocks

 */

 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK

               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;

 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;

 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;

 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)

 {

  Error_Handler();

 }

 PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;

 PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;

 if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)

 {

  Error_Handler();

 }

}

/**

 * @brief ADC Initialization Function

 * @param None

 * @retval None

 */

static void MX_ADC_Init(void)

{

 /* USER CODE BEGIN ADC_Init 0 */

 /* USER CODE END ADC_Init 0 */

 ADC_ChannelConfTypeDef sConfig = {0};

 /* USER CODE BEGIN ADC_Init 1 */

 /* USER CODE END ADC_Init 1 */

 /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)

 */

 hadc.Instance = ADC1;

 hadc.Init.OversamplingMode = DISABLE;

 hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV1;

 hadc.Init.Resolution = ADC_RESOLUTION_12B;

 hadc.Init.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;

 hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;

 hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;

 hadc.Init.ContinuousConvMode = ENABLE;

 hadc.Init.DiscontinuousConvMode = DISABLE;

 hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;

 hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;

 hadc.Init.DMAContinuousRequests = DISABLE;

 hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;

 hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;

 hadc.Init.LowPowerAutoWait = DISABLE;

 hadc.Init.LowPowerFrequencyMode = ENABLE;

 hadc.Init.LowPowerAutoPowerOff = DISABLE;

 if (HAL_ADC_Init(&hadc) != HAL_OK)

 {

  Error_Handler();

 }

 /** Configure for the selected ADC regular channel to be converted.

 */

 sConfig.Channel = ADC_CHANNEL_0;

 sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;

 if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)

 {

  Error_Handler();

 }

 /** Configure for the selected ADC regular channel to be converted.

 */

 sConfig.Channel = ADC_CHANNEL_1;

 if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)

 {

  Error_Handler();

 }

 /* USER CODE BEGIN ADC_Init 2 */

 /* USER CODE END ADC_Init 2 */

}

/**

 * @brief USART2 Initialization Function

 * @param None

 * @retval None

 */

static void MX_USART2_UART_Init(void)

{

 /* USER CODE BEGIN USART2_Init 0 */

 /* USER CODE END USART2_Init 0 */

 /* USER CODE BEGIN USART2_Init 1 */

 /* USER CODE END USART2_Init 1 */

 huart2.Instance = USART2;

 huart2.Init.BaudRate = 115200;

 huart2.Init.WordLength = UART_WORDLENGTH_8B;

 huart2.Init.StopBits = UART_STOPBITS_1;

 huart2.Init.Parity = UART_PARITY_NONE;

 huart2.Init.Mode = UART_MODE_TX_RX;

 huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;

 huart2.Init.OverSampling = UART_OVERSAMPLING_16;

 huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;

 huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;

 if (HAL_UART_Init(&huart2) != HAL_OK)

 {

  Error_Handler();

 }

 /* USER CODE BEGIN USART2_Init 2 */

 /* USER CODE END USART2_Init 2 */

}

/**

 * @brief GPIO Initialization Function

 * @param None

 * @retval None

 */

static void MX_GPIO_Init(void)

{

 GPIO_InitTypeDef GPIO_InitStruct = {0};

 /* GPIO Ports Clock Enable */

 __HAL_RCC_GPIOC_CLK_ENABLE();

 __HAL_RCC_GPIOH_CLK_ENABLE();

 __HAL_RCC_GPIOA_CLK_ENABLE();

 /*Configure GPIO pin Output Level */

 HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);

 /*Configure GPIO pin : B1_Pin */

 GPIO_InitStruct.Pin = B1_Pin;

 GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;

 GPIO_InitStruct.Pull = GPIO_NOPULL;

 HAL_GPIO_Init(B1_GPIO_Port, &GPIO_InitStruct);

 /*Configure GPIO pin : LD2_Pin */

 GPIO_InitStruct.Pin = LD2_Pin;

 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

 GPIO_InitStruct.Pull = GPIO_NOPULL;

 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

 HAL_GPIO_Init(LD2_GPIO_Port, &GPIO_InitStruct);

}

/* USER CODE BEGIN 4 */

int __io_putchar(int ch)

{

HAL_UART_Transmit(&huart2, (uint8_t *)&ch,1, 0xFFFF);

return ch;

}

/* USER CODE END 4 */

/**

 * @brief This function is executed in case of error occurrence.

 * @retval None

 */

void Error_Handler(void)

{

 /* USER CODE BEGIN Error_Handler_Debug */

 /* User can add his own implementation to report the HAL error return state */

 __disable_irq();

 while (1)

 {

 }

 /* USER CODE END Error_Handler_Debug */

}

#ifdef USE_FULL_ASSERT

/**

 * @brief Reports the name of the source file and the source line number

 *     where the assert_param error has occurred.

 * @param file: pointer to the source file name

 * @param line: assert_param error line source number

 * @retval None

 */

void assert_failed(uint8_t *file, uint32_t line)

{

 /* USER CODE BEGIN 6 */

 /* User can add his own implementation to report the file name and line number,

   ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

 /* USER CODE END 6 */

}

#endif /* USE_FULL_ASSERT */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

8 REPLIES 8
Imen GH
ST Employee

Hello @chinmaydixit​,

Welcome to STM32 Community!

I recommend you to have a look to the working application available under STM32CubeL0 package which can help you as an implementation example: STM32Cube_FW_L0_V1.12.0\Projects\NUCLEO-L053R8\Examples\ADC\ADC_RegularConversion_Polling

You can compare your own project with the one available in the cube package;

Imen

The method really should be using DMA

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Thank you for the Reply!!

I downloaded the Firmware Package for STM32L0 but it doesn't have ADC Example. It contains only I2C example. I Downloaded from below link:

https://www.st.com/en/embedded-software/stm32cubel0.html

If you have other links particularly for STM32L053 , please provide it.

Can you suggest me the flow that how can we read multichannels? And convey me whether we can use multichannel read without DMA or interrupt.

Thank you.

Sorry . I found it in other folder just now. But it has only single channel example. Got the example of ADC Sequencer. cant we read multichannels with Polling Method?

Thank you.

Imen GH
ST Employee

Hello @chinmaydixit​ ,

As said by @Community member​ , For multi-channels you need to use DMA

You can refer to RM0367:

  • Section 14.5.5 “Managing converted data using the DMA�?
  • Section 11.3.2 “DMA request mapping�?

            Table 51 presents the DMA requests for each channel

 You can find also the example “ ADC_DMA_Transfer�?  in the cube package that can help you.

Imen

chinmaydixit
Associate II

Hello Imen , Thank you for the reference. I successfully read 2 channels but could not read third channel and 4th channel. The results are showing zero for 3rd and 4th channels. Any suggestions?

Thank you in advance.

chinmaydixit
Associate II

Any Suggestions?

AbidSulaiman
Associate III

Hi,

I assume that your GPIO and Clock configurations are correct.

I think you need to add line that calibrate the ADC.

HAL_ADCEx_Calibration_Start(&hadc, ADC_SINGLE_ENDED);

If you still having wrong values, maybe increase the sample time.

Note: You would want to increase the sample time first before using oversampling. If the voltage sampled is wrong, oversampling does not make it better.

Regards