cancel
Showing results for 
Search instead for 
Did you mean: 

ADC sampling time issue while external trigger with TIMER2 TRGO Update to send over USART

ARehm.1
Associate

I am using ADC2 Channel 10 with external trigger TIMER 2 TRGO Update. Although I am viewing the ADC values over USART and it is sampled but the sampling time is not 2Hz. Which I set in TIMER 2 just to make sure that I can control the sampling time via TIMER 2. But this is not the case. It is being sampled too fast. I am not able to figure it out why it is not being sampled the same way my LED is blinking in TIMER2_IRQ

Here is the configuration functions which I used in KEIL VU5 using CMSIS Core.

void init_ADC(void)
{
	RCC->AHB1ENR|=RCC_AHB1ENR_GPIOCEN;	//GPIOC clock enable
	GPIOC->MODER|=(3u<<(2*0));	//ADC input pin is analogue mode	
	RCC->APB2ENR|=RCC_APB2ENR_ADC1EN;		//ADC clock enable
	ADC1->SQR1&=~ADC_SQR1_L;						//set number of conversions per sequence to 1
	ADC1->SQR3&=~ADC_SQR3_SQ1;					//clear channel select bits
	ADC1->SQR3|=10;						//set channel
	ADC1->CR1 &= ~ADC_CR1_SCAN;	//SCAN mode disabled	
	ADC1->CR2 &= ~ADC_CR2_CONT;	//Disable continuous conversion
	
	ADC1->CR2 &=  ~(1<<29);
	ADC1->CR2 |= (1<<28);	//Trigger on Rising edge
	
	//External Event TIM2 TRGO
	ADC1->CR2 &= ~(1<<3);	
	ADC1->CR2 |= (1<<2);
	ADC1->CR2 |= (1<<1);
	ADC1->CR2 &= ~(1<<0);
	
	
	ADC1->SMPR1 |= ADC_SMPR1_SMP10;
	
	
	
	ADC1->CR2|=ADC_CR2_ADON;						//enable ADC	
	ADC1->CR2|=ADC_CR2_SWSTART;		
}
 
unsigned short read_adc(void)
{
	ADC1->CR2|=ADC_CR2_SWSTART;				//start ADC conversion
	while((ADC1->SR&ADC_SR_EOC)==0){__NOP();}	//wait for ADC conversion complete
	return ADC1->DR;									//return converted value
}
 
void TIM2_Configuration(void){
	// enable TIM2 clock (bit0)
    RCC->APB1ENR |= (1 << 0);
    //TIM2->PSC = 1749;	//FOR DISCOVERY
		//TIM2->PSC = 1874;	//FOR NECLUEO
 
		TIM2->PSC = 8199;	//For 82Mhz
    TIM2->ARR = 10000; //it will get one second delay
	
	 /* Reset the MMS Bits */
  TIM2->CR2 &= (uint16_t)~TIM_CR2_MMS;
  /* Select the TRGO source */
  TIM2->CR2 |=  TIM_CR2_MMS_1; //UPDATE EVENT
	
	
 
    // Update Interrupt Enable
    TIM2->DIER |= (1 << 0);
 
    // enable TIM2 IRQ from NVIC
    NVIC_EnableIRQ(TIM2_IRQn);
 
    // Enable Timer 2 module (CEN, bit0)
    TIM2->CR1 |= (1 << 0);
	
	
}
/*************************************************
* timer 2 interrupt handler
*************************************************/
void TIM2_IRQHandler(void)
{
   
 
	// clear interrupt status
	if (TIM2->DIER & 0x01) {
		if (TIM2->SR & 0x01) {
			TIM2->SR &= ~(1U << 0);
		}
	}
 
    GPIOD->ODR ^= (1 << 13);
 
    
}

and this is how I am reading in while(True) loop

    while(1)
    {
			char str[10];	
			while((ADC1->SR&ADC_SR_EOC)==0){__NOP();}		
			//unsigned int volts = read_adc();			
				unsigned int volts = ADC1->DR;	
     // GPIOD->ODR ^= (1 << 13);  // Toggle LED
			uart_tx(((volts/10000)%10)+48);
			uart_tx(((volts/1000)%10)+48);
			uart_tx(((volts/100)%10)+48);
			uart_tx(((volts/10)%10)+48);
			uart_tx(((volts)%10)+48);
			uart_tx('\r');
			uart_tx('\n');
			 // slow down
            //
			 delay(300);
        
    }

Also the Next thing is I want to send this data automatically via Usart Interrupt and DMA. But I am not sure where to go from this point? How to use DMA with both the ADC and the USART so that It circularly transfer data automatically. Any suggestions? or any CMSIS examples related to this?

1 REPLY 1

Which STM32?

Write a minimal but complete compilable code exhibiting the problem, and post. Also read out and post the relevant ADC and TIM registers content.

 JW

PS.

> TIM2->SR &= ~(1U << 0);

Not the problem here, but don't RMW TIMx_SR.