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!
|