AnsweredAssumed Answered

Cannot for the life of me get TIM2 to trigger ADC1

Question asked by jer on Apr 3, 2012
Hi all,

Bit at my wits end here. I have been trying for quite some time to get ADC1 to trigger on TIM2 CC2. To start with, I tried to use TIM3 TRGO with about the same amount of luck (ie none). Everything works fine if I put ADC->CR2 = ADC_CR2_ADON in the timer interrupt, so that I have at least done something right. The DAC is just in there so I can see the counter value on my oscilloscope. Does anyone have any idea what on earth I am doing wrong? Any help at all would be very much appreciated!

I am using an STM32VLDiscovery (STM32F100) with GCC.

01.#define CPU_SPEED 24000000
02. 
03.#include "stm32f10x.h"
04. 
05.void TIM2_IRQHandler(void) {
06.  if (TIM2->SR & TIM_SR_UIF) {
07.    TIM2->SR &= ~TIM_SR_UIF;
08.  }
09.   
10.  if (TIM2->SR & TIM_SR_CC2IF) {
11.    TIM2->SR &= ~TIM_SR_CC2IF;
12.    GPIOC->ODR |= (1<<9);
13.  }
14.}
15. 
16.void adc1_init() {
17.  RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; // clock on
18.  ADC1->CR1 = ADC_CR1_EOCIE; // eoc interrupt, channel 0
19.  ADC1->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_EXTSEL_1 | ADC_CR2_EXTSEL_0; // external trigger, tim2 cc2 trigger
20.  ADC1->CR2 = ADC_CR2_ADON; // wake up ADC (needs to be done with its own write)
21.  NVIC->ISER[0] |= (1 << (ADC1_IRQn & 0x1F)); // IRQ enable
22.}
23. 
24.void ADC1_IRQHandler(void) {
25.  if (ADC1->SR & ADC_SR_EOC) {
26.    ADC1->SR &= ~ADC_SR_EOC;
27.    GPIOB->ODR = ADC1->DR;
28.  }
29.}
30. 
31.int main(void)
32.{
33.  int j = 0;
34.  RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN;
35. 
36.  adc1_init();
37.  // configure portc lower to be output
38.  GPIOC->CRL = 0x11111111; // all general purpose push-pull output
39.  GPIOC->CRH = 0x11111111;
40.  GPIOC->ODR = 0x00000000;
41.   
42.  GPIOB->CRL = 0x11111111;
43.  GPIOB->CRH = 0x11111111; // GPIOB too!
44.   
45.  // enable tim2 (general purpose timer)
46.  RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
47.   
48.  NVIC->ISER[0] |= (1 << (TIM2_IRQn & 0x1F)); // enable position 28 interrupt (TIM2)
49.  TIM2->PSC = 0xFFFF; // huge prescaler
50.  TIM2->DIER = TIM_DIER_UIE | TIM_DIER_CC2IE; // compare 2 interrupt enable
51.  TIM2->ARR = 0xF; // count up to 0xF
52.  TIM2->CCR2 = 0x6; // trigger at 0x6
53.  TIM2->CR1 = TIM_CR1_CEN; // enable the clock
54. 
55.  TIM2->EGR = 1; // update the shadow registers
56.   
57.  // init dac
58.  RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
59.  GPIOA->CRL = 0;
60.  RCC->APB1ENR |= RCC_APB1ENR_DACEN;
61.  DAC->CR |= DAC_CR_EN1;
62.   
63.  while(1) {
64.    if (TIM2->CNT != 0x6) GPIOC->ODR &= ~(1<<9);
65.    DAC->DHR12R1 = TIM2->CNT*256; // output the counter value
66.  }
67.}

Outcomes