en.radzio.dxp.pl

Lesson 5. Blinking with timer hardware
After we succesfully blink LED with interrupt from TIM3 we can do next step : blink LED only with hardware - even without any single line of code! Of course, code for timer initialization will be required, but blinking will be realized only by hardware. For do this, we use compare units of timer TIM3. Now, go to section 13.3.8 of RM0041 document. There is described output compare functionality of timer.

As You remember from previous lesson, two of discovery board LEDs can be connected to TIM3 channel 3 and 4. To connect LEDs to this channels we must configure PC8 and PC9 pin as alternate function outputs. On PC8 and PC9 timer outputs are available only after remap. So we need do full remap of TIM3 outputs. Now, go to section 7.4.2 of RM0041 document. There are descirbed register MAPR. As You see, to do full remap of TIM3 we need set both bits TIM3_REMAP :

AFIO->MAPR = AFIO_MAPR_TIM3_REMAP; // Full TIM3 remap

To configure channel output for toggling on CH3 and CH4 output :

TIM3->CCMR2 = TIM_CCMR2_OC4M_0 | TIM_CCMR2_OC4M_1 |
              TIM_CCMR2_OC3M_0 | TIM_CCMR2_OC3M_1; // Toggle output 3 & 4 on compare match

Now, we must enable compare on 3 & 4 channel :

TIM3->CCER  = TIM_CCER_CC4E | TIM_CCER_CC3E;

and set compare values :

TIM3->CCR3 = 250;   // Compare 4 with 250
TIM3->CCR4 = 500;   // Compare 4 with 500

Complete source code :

//=============================================================================
// STM32VLDISCOVERY tutorial
// Lesson 5. Blinking with timer hardware
// Copyright : Radoslaw Kwiecien
// http://en.radzio.dxp.pl
// e-mail : radek(at)dxp.pl
//=============================================================================
#include "stm32f10x.h"
#include "antilib_gpio.h"
//=============================================================================
// Defines
//=============================================================================
#define LED_BLUE_GPIO GPIOC
#define LED_BLUE_PIN 8

#define LED_GREEN_GPIO GPIOC
#define LED_GREEN_PIN 9
//=============================================================================
// main function
//=============================================================================
int main(void)
{
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_AFIOEN;
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;

#if (LED_BLUE_PIN > 7)
  LED_BLUE_GPIO->CRH = (LED_BLUE_GPIO->CRH & CONFMASKH(LED_BLUE_PIN)) | GPIOPINCONFH(LED_BLUE_PIN,    GPIOCONF(GPIO_MODE_OUTPUT2MHz, GPIO_CNF_AFIO_PUSHPULL));
#else
  LED_BLUE_GPIO->CRL = (LED_BLUE_GPIO->CRL & CONFMASKL(LED_BLUE_PIN)) | GPIOPINCONFL(LED_BLUE_PIN,     GPIOCONF(GPIO_MODE_OUTPUT2MHz, GPIO_CNF_AFIO_PUSHPULL));
#endif

#if (LED_GREEN_PIN > 7)
  LED_GREEN_GPIO->CRH = (LED_GREEN_GPIO->CRH & CONFMASKH(LED_GREEN_PIN)) |     GPIOPINCONFH(LED_GREEN_PIN, GPIOCONF(GPIO_MODE_OUTPUT2MHz, GPIO_CNF_AFIO_PUSHPULL));
#else
  LED_GREEN_GPIO->CRL = (LED_GREEN_GPIO->CRL & CONFMASKL(LED_GREEN_PIN)) |     GPIOPINCONFL(LED_GREEN_PIN, GPIOCONF(GPIO_MODE_OUTPUT2MHz, GPIO_CNF_AFIO_PUSHPULL));
#endif

AFIO->MAPR = AFIO_MAPR_TIM3_REMAP; // Full TIM3 remap

TIM3->PSC  = 23990; // Set prescaler to 24 000 (PSC + 1)
TIM3->ARR  = 500;   // Auto reload value 500
TIM3->CCR3 = 250;   // Compare 4 with 250
TIM3->CCR4 = 500;   // Compare 4 with 500

TIM3->CCMR2 = TIM_CCMR2_OC4M_0 | TIM_CCMR2_OC4M_1 |
              TIM_CCMR2_OC3M_0 | TIM_CCMR2_OC3M_1; // Toggle output 3 & 4 on compare match

TIM3->CCER  = TIM_CCER_CC4E | TIM_CCER_CC3E; // Enable compare output 3 & 4
TIM3->CR1   = TIM_CR1_CEN; // Enable timer

while (1) {}
}
//=============================================================================
// End of file
//=============================================================================

After flashing MCU both LEDs will be blinking with 500ms period with 250ms delay between blue and green. And no code in enldess loop and no interrupts!

 

 

 
(c) Radosław Kwiecień