[HELP] Configuring the ADC to run at a higher sample rate.
Posted: Wed Jan 15, 2020 8:44 pm
Hi,
I'm working on a project where i need to sample a microphone at a sample rate of >16,000Hz. Using the built in analogRead() i can manage a sample rate of ~9000Hz. See below is the sequence of commands i'm using to try to configure the ADC prescaler to DIV1 to increase its speed, i have used this exact same code on an STM32L452RE-P and it worked, however, i'm now trying to port this code to a STM32L452RE.
This code was VERY buggy any relied on the analogRead() function to set up the GPIO, it doesn't work at all on the L452RE. The program executes until "HAL_ADC_Init()" and then the MCU halts?
Any ideas on how to get this working again?
Note: The microphone is on PA1.
Thanks,
Richard
I'm working on a project where i need to sample a microphone at a sample rate of >16,000Hz. Using the built in analogRead() i can manage a sample rate of ~9000Hz. See below is the sequence of commands i'm using to try to configure the ADC prescaler to DIV1 to increase its speed, i have used this exact same code on an STM32L452RE-P and it worked, however, i'm now trying to port this code to a STM32L452RE.
This code was VERY buggy any relied on the analogRead() function to set up the GPIO, it doesn't work at all on the L452RE. The program executes until "HAL_ADC_Init()" and then the MCU halts?
Any ideas on how to get this working again?
Note: The microphone is on PA1.
Code: Select all
#include "stm32l4xx_hal_adc.h"
const int CONFIG_MIC_PIN = PA0;
unsigned long lastTick;
unsigned long timeNow;
unsigned long numberOfLoopIterations = 0;
ADC_HandleTypeDef adcConfiguration;
void SetupADC()
{
/*
// GPIO config
__GPIOC_CLK_ENABLE();
GPIO_InitTypeDef gpioConfiguration;
gpioConfiguration.Pin = GPIO_PIN_0; // PC1
gpioConfiguration.Mode = GPIO_MODE_ANALOG;
gpioConfiguration.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &gpioConfiguration);
pinMode(CONFIG_MIC_PIN, INPUT);
*/
analogRead(CONFIG_MIC_PIN);
// ADC peripheral
adcConfiguration.Instance = ADC1;
adcConfiguration.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV1;
adcConfiguration.Init.Resolution = ADC_RESOLUTION_12B;
adcConfiguration.Init.ScanConvMode = DISABLE;
adcConfiguration.Init.ContinuousConvMode = ENABLE;
adcConfiguration.Init.DiscontinuousConvMode = ENABLE;
adcConfiguration.Init.NbrOfDiscConversion = 0;
adcConfiguration.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
adcConfiguration.Init.ExternalTrigConv = ADC_EXTERNALTRIG_T1_CC1;
adcConfiguration.Init.DataAlign = ADC_DATAALIGN_RIGHT;
adcConfiguration.Init.NbrOfConversion = 1;
adcConfiguration.Init.DMAContinuousRequests = ENABLE;
adcConfiguration.Init.EOCSelection = ADC_EOC_SEQ_CONV;
HAL_StatusTypeDef result = HAL_ADC_Init(&adcConfiguration);
// 0 = ok
// 1 = error
// 2 = busy
// 3 = timeout
Serial.print("ADC Peripheral init: ");
Serial.println(result); // returns 1
// ADC channel
ADC_ChannelConfTypeDef adcChannelConfiguration;
adcChannelConfiguration.Channel = ADC_CHANNEL_6;
adcChannelConfiguration.Rank = 1;
adcChannelConfiguration.SamplingTime = ADC_SAMPLETIME_2CYCLES_5;
adcChannelConfiguration.Offset = 0;
adcChannelConfiguration.SingleDiff = ADC_SINGLE_ENDED;
adcChannelConfiguration.OffsetNumber = ADC_OFFSET_NONE;
Serial.print("ADC Channel init: ");
Serial.println(HAL_ADC_ConfigChannel(&adcConfiguration, &adcChannelConfiguration));
}
void setup()
{
Serial.begin(9600);
SetupADC();
lastTick = millis();
}
void loop()
{
// start the conversion process
HAL_ADC_Start(&adcConfiguration);
//wait for the conversion to finish
if (HAL_ADC_PollForConversion(&adcConfiguration, 100000) == HAL_OK)
{
// conversion completed successfully.
uint16_t sample = HAL_ADC_GetValue(&adcConfiguration);
//Serial.print("Value:");
Serial.println(sample);
}
HAL_ADC_Stop(&adcConfiguration);
timeNow = millis();
// every 1 second.
if ( (timeNow - lastTick) >= 1000)
{
//Serial.println(numberOfLoopIterations);
numberOfLoopIterations = 0;
lastTick = timeNow;
}
numberOfLoopIterations++;
}
Thanks,
Richard