cancel
Showing results for 
Search instead for 
Did you mean: 

Stm32 ADC trigger at certain time

Bud
Associate III

Hello friends, i want to read ADC value for particular time. That is, to read the analog value during the middle time of every pwm signal. Triggering ADC via timer.

  • I had generated pwm signal with 50% duty cycle in center align mode so that we could easily capture the middle(Ton middle) of the pwm.
  • I also called ISR for timer 1 for every overflow and underflow of the ARR value.

Used....

--> Stm32f103xx as micro controller.

--> Pin A8 is set as pwm output.

--> ADC2 with pin A1 is used to sense analog voltage.

--> GPIOB pin12 is set as a indication of middle pwm time.

--> And i have coding using register level language.

#include "stm32f10x.h"
#include "Pwm.h"
 
 
int read;
int main()
{
 
////////    GPIO setting    /////////
 
// Enable gpiob clock...
	RCC->APB2ENR|=RCC_APB2ENR_IOPBEN;
// Set gpiob 12pin as output... 
	GPIOB->CRH|=GPIO_CRH_MODE12;
        GPIOB->CRH|=GPIO_CRH_CNF12_0;
 
 
////////  ADC setting     //////////
	
// Enable ADC1 clock...
	RCC->APB2ENR |=RCC_APB2ENR_ADC2EN;		
// Enable Continuous mode... 
	ADC2->CR2 = ADC_CR2_CONT;             
 
// Channel and sampling...		
        ADC2->SMPR2 |=ADC_SMPR2_SMP0;  	       // Setting sampling rate as 111 (slow sampling) for analog 'A1'
	ADC2->SQR3  |=ADC_SQR3_SQ1_0;                 // First convretion as 'A1'
 
// ADC calibration...
	ADC2->CR2|=(ADC_CR2_ADON);
        ADC2->CR2|=ADC_CR2_CAL;
	while((ADC2->CR2 & ADC_CR2_CAL)!=0){}
 
		
///////     Timer setting   /////////
		
// Timer library sets 'A8'pin as output in center align mode(TIM1)... 	    
// Prescaler = 2, ARR_value = 2400, Duty_cycle = 1200...
        PwmSetupfortimer1(1,2400,1200);    
 
// Enabling tim1 interrupt...
	TIM1->DIER = TIM_DIER_UIE;	
	NVIC_EnableIRQ(TIM1_UP_IRQn);
 
 
while(1)
 {
   ADC2->CR2|=(ADC_CR2_ADON);
   while((ADC2->SR & ADC_SR_EOC)==0)
   {}
   read=ADC2->DR;	  	    // Reads adc data
 }
}
	
 
 
 
// Interrupt service routine // This will raise for for every overflow and underflow of counter
void TIM1_UP_IRQHandler(void)
{
	
	if(TIM1->SR & TIM_SR_UIF)
	{
		if(TIM1->CNT<=TIM1->CCR1)   // compare when counter reaches ARR value
		{
		GPIOB->BSRR|=(1<<12);       // Set B12 as high  
        
	   }
	 GPIOB->BRR|=(1<<12);	        // Set B12 as low
	 TIM1->SR&=~TIM_SR_UIF;
    }
	
}

I have created my own timer library which sets frequency = 7.5 kHz, duty cycle=50% and in center align mode.

But i am confused how to use ADC trigger during the middle of pwm cycle. Guide me friends.

Green signal is the pwm pulse and the yellow one is PB12. Which finds the center portion pwm.

0693W000003RYOXQA4.png I want to trigger adc using timer and also to transfer adc using dma. In order to offload the cpu. Because I am going to use this in motor control application.

4 REPLIES 4
TDK
Guru

I don't see a question here. Seems like you just need to start the conversion in your interrupt handler.

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

Yes TDK I had tried that also. Which work ok, But I want to trigger the adc using timer as well as in dma. That will the efficient right.​ Thank you for response. Could you help and give a solution.

TDK
Guru

You can trigger the ADC on a timer event by setting the appropriate bits in EXTEN and EXTSEL.

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

I have tried that TDK but cant able to get the output at the middle of the pwm. Because by using External trigger the adc will measure at the beginning.