cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F427: Trouble getting OCx to work with TIM8

pacman
Associate III
Posted on January 19, 2015 at 21:22

The complete project is

https://my.st.com//public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Attachments/49654/TIM8_OC.zip

.

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.

&sharpinclude ''stm32f4xx_hal_conf.h''

&sharpdefine CPU_FREQUENCY 168 MHz

&sharpdefine MHz * 1000000

&sharpdefine ms * ((CPU_FREQUENCY / 1000) / 5)

void

setupTimer(

void

);

//&sharpdefine 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 */

&sharpifdef PC8_GPO

GPIOC->MODER = (GPIOC->MODER &

0xfffcffff

) |

0x00010000

;

/* change PC8 to plain output (mode 1) - this works, LED blinks when toggled manually. */

&sharpendif

/* 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

)

{

&sharpifdef PC8_GPO

GPIOC->ODR ^=

0x0100

;

/* toggle PC8 (only when configured as output, this works) */

&sharpendif

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 */

&sharpif 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 */

&sharpendif

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 */

}

#solved-bdtr-moe-tim_bdtr_moe #tim8-oc3-ccr3-toggle-output
2 REPLIES 2
Posted on January 19, 2015 at 21:32

TIM1 and TIM8 are special, they have more registers to correctly configure.

/**
* @brief Enables or disables the TIM peripheral Main Outputs.
* @param TIMx: where x can be 1 or 8 to select the TIMx peripheral.
* @param NewState: new state of the TIM peripheral Main Outputs.
* This parameter can be: ENABLE or DISABLE.
* @retval None
*/
void TIM_CtrlPWMOutputs(TIM_TypeDef* TIMx, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_TIM_LIST4_PERIPH(TIMx));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable the TIM Main Output */
TIMx->BDTR |= TIM_BDTR_MOE;
}
else
{
/* Disable the TIM Main Output */
TIMx->BDTR &= (uint16_t)~TIM_BDTR_MOE;
}
}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
pacman
Associate III
Posted on January 19, 2015 at 21:48

Thank you so much, Clive.

This was exactly what was wrong. After adding ...

TIM8->BDTR |= TIM_BDTR_MOE;

/* enable main output */

... it works the way I intended it to work.