2020-01-16 01:40 PM
Hi,
I use internal ADC of the STM32F767 microprocessor. I set the ADC parameters like this,
static void MX_ADC2_Init(void)
{
/* USER CODE BEGIN ADC2_Init 0 */
/* USER CODE END ADC2_Init 0 */
ADC_ChannelConfTypeDef sConfig = {0};
/* USER CODE BEGIN ADC2_Init 1 */
/* USER CODE END ADC2_Init 1 */
/** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/
hadc2.Instance = ADC2;
hadc2.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc2.Init.Resolution = ADC_RESOLUTION_12B;
hadc2.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc2.Init.ContinuousConvMode = ENABLE;
hadc2.Init.DiscontinuousConvMode = DISABLE;
hadc2.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc2.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc2.Init.NbrOfConversion = 1;
hadc2.Init.DMAContinuousRequests = DISABLE;
hadc2.Init.EOCSelection = ADC_EOC_SEQ_CONV;
if (HAL_ADC_Init(&hadc2) != HAL_OK)
{
Error_Handler();
}
/** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ADC2_Init 2 */
/* USER CODE END ADC2_Init 2 */
}
Based on these parameters, sampling rate is 1.6MHz. PCLK2 is 96MHz. Prescaler is 4, so I get ADC Clock as 24MHz (96MHz/4). Then 24MHz/(12bit+3 cycle) = 1.6MHz (1.6MSPS).
For verification this calculation, I wrote a toggle function in call back function like this,
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
ADC_data = HAL_ADC_GetValue(&hadc2);
volt = (float)(ADC_data * (3.3 / 4096.0)); //
testdata_in[i++]=volt;
i %= 16;
HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
}
Then I measure the LED toggling pin on the oscilloscope. I got 2.78us pulse width and 5.66us period. So based on toggling, I collected 16 samples in 5.66 us toggling period. Hence, each sample time is 5.66 us/16=0.35375us. Then the sampling rate is 1/0.35375us= 2.82 MHz (MSPS).
So what is the true sampling rate, 2.82MSPS or 1.6 MSPS?
Thank you,
FYI, may target is 1MSPS.
2020-01-16 01:58 PM
Don't interrupt in this fashion, use a DMA buffer, say 100 samples, circular, and toggle in DMA completion interrupt. This way you won't saturate the processor.
For exact rates, trigger ADC with a TIM
2020-01-16 02:17 PM
Ok, I try DMA mode. But I didn't get any reading and toggling. What did I miss?
uint16_t ADC_data[100];
float volt;
float testdata_in[16];
int i=0;
int main(void)
{
...
HAL_ADC_Start_DMA(&hadc2, (uint32_t*)&ADC_data,100);
}
/* USER CODE BEGIN 4 */
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
for(i=0;i<100;i++)
{
ADC_data[i] = HAL_ADC_GetValue(&hadc2);
testdata_in[i] = (float)(ADC_data[i] * (3.3 / 4096.0)); //
}
HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
}
/* USER CODE END 4 */
By the way, new ADC setting is
static void MX_ADC2_Init(void)
{
/* USER CODE BEGIN ADC2_Init 0 */
/* USER CODE END ADC2_Init 0 */
ADC_ChannelConfTypeDef sConfig = {0};
/* USER CODE BEGIN ADC2_Init 1 */
/* USER CODE END ADC2_Init 1 */
/** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/
hadc2.Instance = ADC2;
hadc2.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc2.Init.Resolution = ADC_RESOLUTION_12B;
hadc2.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc2.Init.ContinuousConvMode = ENABLE;
hadc2.Init.DiscontinuousConvMode = DISABLE;
hadc2.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc2.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc2.Init.NbrOfConversion = 1;
hadc2.Init.DMAContinuousRequests = ENABLE;
hadc2.Init.EOCSelection = ADC_EOC_SEQ_CONV;
if (HAL_ADC_Init(&hadc2) != HAL_OK)
{
Error_Handler();
}
/** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADC_CHANNEL_1;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_15CYCLES;
if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ADC2_Init 2 */
/* USER CODE END ADC2_Init 2 */
}