907 views|2 replies

6827

Posts

11

Resources
The OP
 

[ST NUCLEO-U5A5ZJ-Q development board review] ADC experience 1 [Copy link]

【Foreword】

The stm32U5 series has relatively excellent ADC peripherals, and U5A5 has ADC12 and ADC4.

It is described in the user manual "RM0456":

In addition to the 14-bit ADC12, the STM32U5A5 also has a 12-bit ADC4, which can support a total of 45 channels of input.

This experience is just a preliminary experience:

【Software environment】STM32CubeIDE1.14.0

【Implementation steps】

1. Create a new development board project based on NOCLE-U5A5ZJ-Q.

2. Use the default generation environment, which initializes the basic operating environment of the development board, such as the serial port.

3. The development board project has initialized the AN3 channel (PC2) of ADC1. Its basic configuration parameters are as follows:

Convert to single conversion, conversion time is 5 clocks, 14-bit conversion.

After generating the code, you can see the configured code as follows:

/* ADC1 init function */
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 */

  /** Common config
  */
  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
  hadc1.Init.Resolution = ADC_RESOLUTION_14B;
  hadc1.Init.GainCompensation = 0;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc1.Init.LowPowerAutoWait = DISABLE;
  hadc1.Init.ContinuousConvMode = DISABLE;
  hadc1.Init.NbrOfConversion = 1;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc1.Init.DMAContinuousRequests = DISABLE;
  hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
  hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  hadc1.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
  hadc1.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DR;
  hadc1.Init.OversamplingMode = DISABLE;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_3;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_5CYCLE;
  sConfig.SingleDiff = ADC_SINGLE_ENDED;
  sConfig.OffsetNumber = ADC_OFFSET_NONE;
  sConfig.Offset = 0;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC1_Init 2 */

  /* USER CODE END ADC1_Init 2 */

}

Add the following test code to the main program:

int main(void)
{
  /* USER CODE BEGIN 1 */
	uint16_t adc_val;
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* Configure the System Power */
  SystemPower_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_ADC1_Init();
  MX_ICACHE_Init();
  MX_UCPD1_Init();
  MX_USART1_UART_Init();
  MX_USB_OTG_HS_HCD_Init();
  /* USER CODE BEGIN 2 */
  printf("start\r\n");
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  HAL_ADC_Start(&hadc1);
	  adc_val = HAL_ADC_GetValue(&hadc1);
	  printf("ADC VaL:%d voltage:%.3f \r\n   ", adc_val, (float)adc_val*3.3/16384);
	  HAL_Delay(500);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

The code adds a variable adc_val to store the ADC conversion value, uses HAL_ADC_Start(&hadc1); to start the ADC conversion, and uses adc_val = HAL_ADC_GetValue(&hadc1); to read the conversion result.

Use printf to output the print results to the serial port.

[Experimental results]

1. Connect an adjustable potentiometer to the development board and adjust the electrical position to see the real-time conversion results.

2. At the same time, connect the multimeter to the output port of the potentiometer for comparative testing.

We can see by comparing the output values of the multimeter and the serial port that the difference is at the mV level.

ADC测试

This post is from stm32/stm8
 

6827

Posts

11

Resources
2
 

Extending the conversion time to 814 cycles, we can see that the stability of the conversion is much better than that of 5 cycles:

This post is from stm32/stm8
 
 

6827

Posts

11

Resources
3
 

【Experience oversampling】

stm32U5 can use the oversampling function of ADC to achieve higher acquisition accuracy.

1. Set the ADC oversampling and displacement:

I set a 6-bit left shift here to achieve 20-bit acquisition. At the same time, the sampled data is also set to a 6-bit left shift. After generating the code, the print function is corrected to:

printf("ADC VaL:%d voltage:%.4f \r\n ", adc_val, (float)adc_val*3.3/1048576);

[Experimental results]

The effect is not too obvious.

image.png (1.26 MB, downloads: )

image.png
This post is from stm32/stm8
 
 

Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list