AnsweredAssumed Answered

STM32F427: Trouble getting OCx to work with TIM8

Question asked by Pac-Man on Jan 19, 2015
Latest reply on Jan 19, 2015 by Pac-Man
The complete project is attached.

I've made a simple test-program, which toggles some LEDs.
I'd like PC6-PC9 to toggle automatically when a compare/match occurs.
On the STM32F407 Discovery board, I had similar code working for TIM3, but even on my third try, I can't seem to get TIM8 to update the OC1...OC4 pins.

#include "stm32f4xx_hal_conf.h"

#define CPU_FREQUENCY     168 MHz

#define MHz * 1000000

#define ms * ((CPU_FREQUENCY / 1000) / 5)

void setupTimer(void);

//#define PC8_GPO

int main(void)

{

     /* Set up GPIOC for our Output Compare pins on PC6..PC9: */

     RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN;               /* enable Port C clock power for OC output */

     GPIOC->MODER = (GPIOC->MODER & 0xfff00fff) | 0x000AA000;     /* PC6, PC7, PC8 and PC9 are using alternate functions (mode 2) */

     GPIOC->AFR[0] = (GPIOC->AFR[0] & 0x00ffffff) | 0x33000000;     /* set PC6 and PC7 to AF3 */

     GPIOC->AFR[1] = (GPIOC->AFR[1] & 0xffffff00) | 0x00000033;     /* set PC8 and PC9 to AF3 */

#ifdef PC8_GPO

     GPIOC->MODER = (GPIOC->MODER & 0xfffcffff) | 0x00010000;     /* change PC8 to plain output (mode 1) - this works, LED blinks when toggled manually. */

#endif

     /* Set up GPIOD for our 4 LEDs on PD12..PD15 */

     RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN;                    /* enable Port D clock power */

     GPIOD->MODER = (GPIOD->MODER & 0x00ffffff) | 0x55000000;     /* PD12, PD13, PD14 and PD15 are outputs */

     GPIOD->ODR = (GPIOD->ODR & 0x0fff) | 0x8000;               /* set PD15 high, set PD14, PD13 and PD12 low */

     setupTimer();

     while(1)

     {

#ifdef PC8_GPO

          GPIOC->ODR ^= 0x0100;                         /* toggle PC8 (only when configured as output, this works) */

#endif

          for(uint32_t k = 0; k < 450 ms; k++){ volatile uint32_t dummy; (void) dummy; }

          GPIOD->ODR ^= 0xc000;                         /* toggle PD14 and PD15 */

          for(uint32_t k = 0; k < 50 ms; k++){ volatile uint32_t dummy; (void) dummy; }

          GPIOD->ODR ^= 0xc000;                         /* toggle PD14 and PD15 */

//          __WFI();                              /* (temporarily disabled) */

     }

     return(0);

}

void setupTimer(void)

{

     __TIM8_CLK_ENABLE();                              /* enable TIM8 clock power */

     TIM8->CR1 = 0;                                   /* stop timer, while we're configuring it. */

     TIM8->PSC = 16800 - 1;                              /* set prescaler to divide by 16800, so we get a 168 MHz / 16800 = 10.0 kHz counter frequency */

     TIM8->CCMR2 = TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_1;          /* OC2REF is active as long as TIM8->CNT < TIM8->CCR3, otherwise it's inactive. */

     TIM8->ARR = 10000;                              /* set the frame length (one second) */

     TIM8->CCR3 = 10000 / 4;                              /* a short on pulse and a long off pulse */

     TIM8->CCER = TIM_CCER_CC3E | TIM_CCER_CC3P;               /* enable output for pulse, set polarity negative */

#if 01

     TIM8->CCR1 = 10000 / 4;                              /* a short on pulse and a long off pulse */

     TIM8->CCER |= TIM_CCER_CC1E | TIM_CCER_CC1P;               /* enable output for pulse, set polarity negative */

     TIM8->CCR2 = 10000 / 4;                              /* a short on pulse and a long off pulse */

     TIM8->CCER |= TIM_CCER_CC2E;                         /* enable output for pulse, set polarity positive */

     TIM8->CCR4 = 10000 / 4;                              /* a short on pulse and a long off pulse */

     TIM8->CCER |= TIM_CCER_CC4E;                         /* enable output for pulse, set polarity positive */

#endif

     TIM8->DIER = TIM_DIER_UIE | TIM_DIER_CC3IE;               /* enable Interrupt on Update Event and Compare 3. (Interrupt is invoked) */

     NVIC_EnableIRQ(TIM8_CC_IRQn);                         /* enable Timer8 Capture Compare interrupt */

     TIM8->CR1 = TIM_CR1_URS | TIM_CR1_CEN;                    /* enable timer. Only generate update on counter overflow. */

}

void TIM8_CC_IRQHandler(void)                              /* Capture and Compare interrupt */

{

     TIM8->SR = ~(TIM_SR_CC1IF | TIM_SR_CC2IF | TIM_SR_CC3IF | TIM_SR_CC4IF);     /* Clear interrupt pending bits. */

     GPIOD->ODR ^= 0x1000;                              /* toggle PD12 */

}


Attachments

Outcomes