As sampling frequency plays such a critical role in determining the quality of the digital representation of the analog signal input, and to avoid aliasing artifacts, it is preferable to use a timer to trigger the conversion rather than to enable continuous conversions as we did in the previous recipe. This recipe, adcTimerISR_c5v0
, illustrates this technique. The aim of this recipe is to configure TIM2 _CH2
in output compare mode so that it toggles every 100 ms and then use this timing signal to trigger the ADC.
adcTimerISR.uvprojx
and use the RTE manager to configure it as we did for the folder adcISR_c5v0
for the Setting up the ADC recipe.timer.c
and Custom_ADC.c
from the previous recipes and add these to the project. Copy adcISR.c
and rename it adcTimerISR.c
. Add this to the project.#include timer.h
to adcTimerISR.c
and call TIM2_Initialize()
in main()
. Check whether the project successfully builds.TIM2_Initialize()
function so that it no longer produces an update interrupt flag (UIF) by deleting the following statements:TIM2->DIER = (1UL << 0); NVIC_EnableIRQ(TIM2_IRQn);
TIM2_CH2
to toggle channel 2 capture/compare output by writing to the appropriate fields of Capture/Compare Mode Register 1 (CCMR1
) and Capture/Compare Enable Register (CCER
):TIM2->CCMR1 |= ( 3UL << 12 ); TIM2->CCER |= ( 1UL << 4 );
/*************************************************** * TIM2_Initialize ( ) *************************************************** * Initializes TIM2 * Capture Compare 2 Interrupt Flag (CC2IF) * generates interrupts every 100ms (0.1s) * SystemCoreClock = 168 MHz - set by SystemInit ( ) * Refer to Figure 134 of STM Reference Manual * TIMxCLK = SystemCoreClock/2 * Hence ticks = 0.1 * 168,000,000 / 2 = 8,400,000 * Prescaler = 8400-1; ARR = 1000-1; * Note: Capture Compare Register is left in Reset ***************************************************/ void TIM2_Initialize (void) { const uint16_t PSC_val = 8400; const uint16_t ARR_val = 1000; /* En. clk for TIM2 */ RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; TIM2->PSC = PSC_val - 1; /* set prescaler */ TIM2->ARR = ARR_val - 1; /* set auto-reload */ TIM2->CR1 = ( 1UL << 0 ); /* set Ctr. En. (CEN) */ TIM2->CCMR1 |= ( 3UL << 12 ); /* OC1REF toggles when TIMx_CNT=TIMx_CCR1*/ TIM2->CCER |= ( 1UL << 4 ); /* CC2E set */ }
adc_Initialize_and_Set_IRQ ( )
function to trigger conversions on both the rising and falling edge of TIM2_CH2
by writing to Control Register 2:ADC3->CR2 |= ( 3UL << 28); ADC3->CR2 |= ( 3UL << 24);
void ADC_Initialize_and_Set_IRQ (void) { /* Setup potentiometer pin PF9 (ADC3_7) and ADC3 */ RCC->APB2ENR |= (1UL << 10); /* En. ADC3 clk */ RCC->AHB1ENR |= (1UL << 5); /* En. GPIOF clk */ GPIOF->MODER |= (3UL << 2*9);/* PF9 = Analog mode */ ADC3->SQR1 = 0; ADC3->SQR2 = 0; ADC3->SQR3 = (7UL << 0); /* SQ1 = chan. 7 */ ADC3->SMPR1 = 0; /* Chan. 7 sample */ ADC3->SMPR2 = (7UL << 18); /* time = 480 cyc. */ ADC3->CR1 = (1UL << 8); /* Scan mode on */ ADC3->CR1 |= ( 1UL << 5); /* En. EOC IRQ */ ADC3->CR2 |= ( 3UL << 28); /* Trig on both edg */ ADC3->CR2 |= ( 3UL << 24); /* of TIM2_CC2 */ ADC3->CR2 |= ( 1UL << 0); /* ADC enable */ NVIC_EnableIRQ( ADC_IRQn ); /* Enable IRQ */ ADC3->CR2 |= (1 << 30); /* Start 1st conversion */ }
In addition to the update event interrupt, each timer also allows interrupts to be generated by up to four capture compare channels (TIMx_CH1-TIMx_CH4). Each Capture/Compare channel comprises a Capture/Compare register, an input stage for capture (with digital filter, multiplexing, and prescaler), and an output stage (with comparator and output control). Each can be configured as the input capture, PWM input, forced output, output compare, PWM, or one-pulse modes. The output compare mode can be used to provide timing signals that can be used to start A-D conversions.
One of 16 possible start conversion triggers can be selected for the regular group of channels by writing to the ADC control register 2 (ADC_CR2
) bit field, EXTSEL[3:0]. The following table shows how the trigger sources are encoded
CH1-CH4 and TRGO refer to timer channels. For further information, refer to STM's RM0090 Reference manual (http://www.st.com), Chapters 17 and 18.
EXTSEL[3:0] |
Start Trigger |
EXTSEL[3:0] |
Start Trigger |
---|---|---|---|
0000 |
TIM1_CH1 |
1000 |
TIM3_TRGO |
0001 |
TIM1_CH2 |
1001 |
TIM4_CH4 |
0010 |
TIM1_CH3 |
1010 |
TIM5_CH1 |
0011 |
TIM2_CH2 |
1011 |
TIM5_CH2 |
0100 |
TIM2_CH3 |
1100 |
TIM5_CH3 |
0101 |
TIM2_CH4 |
1101 |
TIM8_CH1 |
0110 |
TIM2_TRGO |
1110 |
TIM8_TRGO |
0111 |
TIM3_CH1 |
1111 |
EXT11 |
The polarity of the trigger is determined by EXTEN, as shown in the following table:
EXTEN |
Trigger Polarity |
---|---|
00 |
Trigger detection disabled |
01 |
Trigger detection on the rising edge |
10 |
Trigger detection on the falling edge |
11 |
Trigger detection on both the rising and falling edges |
3.128.79.88