2023-04-28 04:59 AM
Hello guys, I'm new to the ST controllers. My question would be how can I initialize an ADC that is waiting for an external signal from a timer. I have initialized a timer interrupt that is triggered every 1 ms at 170 Mhz clock frequency. The timer also works, but there is no ADC conversion, the conversion should be triggered each time via a timer. I work with direct access to the registers without using the hal library because I want to save memory. I've looked through the St examples a bit, but they're all made with the HAL library. I want to use Timer 2 and ADC channel 0 on GPIOA PA0. The timer is only running, my ADC(adc_value is empty) is not working can someone help me with what I have initialized incorrectly here or what is still missing. Thanks for your help guys, I'll post the code here.
Kind regards, Markus
void initADC()
{
// Enable ADC clock
RCC->AHB2ENR |= RCC_AHB2ENR_ADC12EN;
// Configure GPIO pin as analog input
GPIOA->MODER |= (0b11<<(0 * 2U));
// Disable ADC deep power-down mode and enable ADC voltage regulator
ADC1->CR &= ~ADC_CR_DEEPPWD;
ADC1->CR |= ADC_CR_ADVREGEN;
//wait for voltage 2ms
for(uint32_t i = 0;i < 340000;i++); //170Mhz ->340000 2ms
// Configure ADC trigger source and mode
ADC1->CFGR |= (ADC_CFGR_EXTEN_0 | ADC_CFGR_EXTSEL_0 | ADC_CFGR_EXTSEL_1 | ADC_CFGR_EXTSEL_3); // Trigger on rising edge + Trigger TIM2_TRGO
ADC2->CFGR |= (ADC_CFGR_EXTEN_0 | ADC_CFGR_EXTSEL_0 | ADC_CFGR_EXTSEL_1 | ADC_CFGR_EXTSEL_3); // Trigger on rising edge + Trigger TIM2_TRGO
ADC1->SQR1 |= (ADC_SQR1_SQ1_0 | ADC_SQR1_L_0 );
// Enable ADC
ADC1->CR |= ADC_CR_ADEN;
// Start ADC conversion on Timer 2 TRGO event
ADC1->CR |= ADC_CR_ADSTART;
}
void initCPU_Timer1()
{
RCC->APB1ENR1 |= RCC_APB1ENR1_TIM2EN;
TIM2->PSC = 169;
TIM2->ARR = 999;
TIM2->CR1 = TIM_CR1_ARPE | TIM_CR1_URS;
TIM2->DIER = TIM_DIER_UIE; // Enable Interrupt
TIM2->EGR = TIM_EGR_UG; // Update Event
TIM2->CR2 |= TIM_CR2_MMS_2;
// Interrupt-Config
NVIC_SetPriority(TIM2_IRQn, 0);
NVIC_EnableIRQ(TIM2_IRQn);
// Timer-start
TIM2->CR1 |= TIM_CR1_CEN;
}
int main(void)
{
HAL_Init();
SystemClock_Config();
initADC();
initCPU_Timer1();
while (1)
{
}
}
volatile uint16_t adc_value = 0;
void TIM2_IRQHandler(void)
{
if (TIM2->SR & TIM_SR_UIF) // Timer Overflow Event
{
ADC1->CR |= ADC_CR_ADSTART; // start ADC
TIM2->SR &= ~TIM_SR_UIF; // Clear Timer Overflow Flag
adc_value = ADC1->DR;
}
}
2023-04-28 09:54 AM
Hmmm in timer handler you start adc again before read data from DR register
2023-05-02 01:56 AM
Hello Kamil,
i removed line 79 from my timer handler but it doesn't work. I dont know whats wrong there no ADC conversion.
2023-05-02 02:22 AM
Remove or move as last?
2023-05-02 02:38 AM
I tried both but without success. The timer handler works. Only no conversion is carried out. I think it's up to the ADC configuration, because if I just want to initialize the ADC and then set a software trigger, no conversion works for me either. I don't know how to properly configure the ADC.
2023-05-02 02:40 AM
do you have an example code how i have to configure the adc? I can't find any sample code with direct access to the registers on the STM controller
2023-05-02 03:12 AM
You must wait for ADRDY flag after enable ADC. Its mandatory. This flag is ADC_ISR register
2023-05-02 03:12 AM
After line 24
2023-05-02 03:50 AM
Look at this:
/* Set timer the trigger output (TRGO) */
LL_TIM_SetTriggerOutput(TIM2, LL_TIM_TRGO_UPDATE)
Need set trigger output in your timer.
2023-05-02 03:51 AM