2020-07-06 10:03 AM
I am trying to use the ADC without using HAL (except for in the setup) on a STM32F031K6, using cubeIDE. Im using the ADC in discontinuous mode - as far as I can tell, the sequence of events should be
- ADC is setup, then enabled with ADEN
- ADC start conversion by setting the ADSTART
- check the EOC flag to see when the conversion is finished
- when the data is read from the DR register, the EOC flag is cleared
here's where I'm confused - do I then have to set the ADSTART again? in continuous modes the reference manual seems to indicate the next conversion would automatically take place, but in discontinuos mode states the next conversion needs to be manually started - Im assuming this is done by the ADSTART? In simulation this doesn't seem to work. The datasheet says ADSTART is set by software, does this mean you can't write it directly?
My code is as follows, if I click through step by step it doesn't seem to work properly, if i set it running I can see the ADC1_data variable change as I change the pot on the board, but it works intermittently, changing between 0 and the correct value
the HAL setup is
static void MX_ADC_Init(void)
{
ADC_ChannelConfTypeDef sConfig = {0};
hadc.Instance = ADC1;
hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
hadc.Init.Resolution = ADC_RESOLUTION_12B;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc.Init.LowPowerAutoWait = DISABLE;
hadc.Init.LowPowerAutoPowerOff = DISABLE;
hadc.Init.ContinuousConvMode = DISABLE;
hadc.Init.DiscontinuousConvMode = DISABLE;
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc.Init.DMAContinuousRequests = DISABLE;
hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
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;
sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
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();
}
}
The code within the program reads
ADC1->CR |= ADC_CR_ADEN; // enable ADC
ADC1 ->SMPR = 0b11;// speed divider select
ADC1 ->CHSELR |= 1<<0 | 1<<1; // set sequence to adc0, adc1
ADC1 ->CFGR1 |= ADC_CFGR1_DISCEN; //discontinuous mode
ADC1 ->CR |= 1<<2; // start conversion
while (1)
{
if((ADC1->ISR) & 0b00000100) //if EOC flag is on
{
ADC1_data = ADC1->DR; //store data
ADC1 ->CR |= 1<<2; // start new conversion
}
}
can anyone confirm if I am making a mistake or not?
any help much appreciated