cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H753ZI ADC+DMAで高速サンプリングできない。(解決方法の相談)

ko_mi
Associate II

I am using NUCLEO-H753ZI (STM32H753ZITxLQFP144).
Using ADC1_IN3 Single-ended (PA6) and DMA (Mode:Circular),
I want to perform high-speed sampling. (1MSa/s or more)
Calculated: 3.125MSa/s = 50MHz / 4 * (1.5 + 6.5) (Supplement: clockPrescaler=4, 1.5Cycles, 6.5ADC clock cycles)
*The clock uses 50MHz of PLL2.
However, it seems that the speed is only around 500kSa/s.

Please advise if there are any possible causes or places where the settings may be incorrect.

1 ACCEPTED SOLUTION

Accepted Solutions

Take a look at the reference manual at the 25.4.3 ADC clocks section to see how the ADC clock is derived. This is the clock figure for the V revision. The Y revision does not have this divisor.

TDK_0-1698113252469.png

To find out what hardware revision you have, you can read the REV_ID field from the device.

TDK_1-1698113320270.png

You can read this field with the HAL_GetREVID() function and adjust your ADC prescaler accordingly.

if (HAL_GetREVID() == REV_ID_V) {
  // prescaler 2
} else {
  // prescaler 4
}

CubeMX also has a setting you're supposed to set based on the revision. Not sure how this plays into code generation.

TDK_2-1698113618453.png

 

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

6 REPLIES 6
TDK
Guru

Probably your code can't keep up with the rate of data generation and/or your methods of calculating how long it takes are flawed (e.g. have too much overhead).

Show some code, show how you're arriving at the 500kSa/s value.

If you feel a post has answered your question, please click "Accept as Solution".
ko_mi
Associate II

The settings are done according to the attached contents.
The sampling time is confirmed as follows.

1. Prepare a 100 point buffer
2. Hit GPIO
3.Start ADC

 CubeIDE_1.pngCubeIDE_2.pngCubeIDE_3.png→ HAL_ADC_Start_DMA(&hadc1, &adc1_data, SIZE)
4.Callback function that occurs when ADC completes

 → void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
*Hit GPIO here
*Estimate the sampling time from the time between GPIOs using an oscilloscope.

You calculated duration includes a lot of overhead. There is setup in HAL_ADC_Start_DMA and it takes a bit for HAL_ADC_ConvCpltCallback to be called.

Perhaps change your calculation method to offset for this amount of overhead:

  • Use the same methodology, but increase the number of points from 100 to 1000 or so to improve accuracy.
  • Measure the duration between the GPIO signals as you've done above. This is duration_1.
  • Change the number of points to 2000, and measure the duration again. This is duration_2.
  • Calculate the difference in the durations (duration_2 - duration_1). That is the time it takes for 1000 samples to be taken. It should match the theoretical value of 3.125 Msps very closely.

> 3.125MSa/s = 50MHz / 4 * (1.5 + 6.5)

I don't think this math checks out. 50e6/4/8 = 1.5625 Msps

Note that revision V devices have an additional /2 ADC clock scaling.

 

If you feel a post has answered your question, please click "Accept as Solution".
ko_mi
Associate II

Thank you for your advice. It's a big help.
When I actually measured it, it turned out as follows.
duration_1: 1303us
duration_2: 2575us

duration_2 - duration_1 = 1272us

sampling frequency
1 / 1.272us ≒ 786kSa/s

(Theoretical value: 50e6/4/8 = 1.5625 Msps)

The sampling frequency is almost half of the theoretical value.
I think this is probably related to the comment below that you pointed out last time.

comment
[Note that revision V devices have an additional /2 ADC clock scaling.]

I'd like to know more about this, but what does it mean that Revision V devices have an additional /2 ADC clock scaling? On the Cube MX's Clock Configuration screen, it is 50MHz, but will the frequency be further divided from here?

Take a look at the reference manual at the 25.4.3 ADC clocks section to see how the ADC clock is derived. This is the clock figure for the V revision. The Y revision does not have this divisor.

TDK_0-1698113252469.png

To find out what hardware revision you have, you can read the REV_ID field from the device.

TDK_1-1698113320270.png

You can read this field with the HAL_GetREVID() function and adjust your ADC prescaler accordingly.

if (HAL_GetREVID() == REV_ID_V) {
  // prescaler 2
} else {
  // prescaler 4
}

CubeMX also has a setting you're supposed to set based on the revision. Not sure how this plays into code generation.

TDK_2-1698113618453.png

 

If you feel a post has answered your question, please click "Accept as Solution".
ko_mi
Associate II

I understand that the device I am using is V revision and it is working as configured.
Thank you for your detailed explanation. Thank you very much for helping me.