0
\$\begingroup\$

I've been messing around with going back and forth from datasheet, programming manual, and reference manual trying to better understand how to use the STM32F4 Cortex-M4 micro controller. I don't like the way that the pre-defined libraries lay everything out for you, so I'm doing it the more manual way - it's a personal preference which greatly helps me understand the inner mechanisms of the micro controllers.

My problem is that the PD12 output isn't doing anything at all, though the timer is counting and resetting.

Here is my code:

#include "stm32f4xx.h"

volatile unsigned int i;
int main(void)
{
    SystemInit();

    RCC -> AHB1ENR |= RCC_AHB1ENR_GPIODEN;                  // Enable usage of GPIOD
    RCC -> APB1ENR |= RCC_APB1ENR_TIM4EN;                   // Enable usage of TIM4

    GPIOD -> MODER = (0x10 << 24);                          // Alternate function for PWM on PD12
    GPIOD -> OSPEEDR = (0xFF << 24);                        // High Speed on PD12
    GPIOD -> AFR[1] |= (0x2 << 16);                         // AFRH selected AF2 (TIM4; CH1) for PB6

    TIM4 -> CCMR1 |= (0x7 << 4) | (0x1 << 3);               // PWM Mode 2, channel 1 output compare preload enabled
    TIM4 -> CCR1 = 0x0199;                                  // 10% duty cycle (arbitrary)
    TIM4 -> PSC = 0x0000;                                   // No pre-scaler
    TIM4 -> ARR = 0x1000;                                   // Reload at 0x1000


    (*TIM4).CCER |= TIM_CCER_CC1E;                          // Enable CH1 output
    (*TIM4).CR1 |= (0x2 << 8) | TIM_CR1_ARPE | TIM_CR1_CEN; // Divide clock by 4, auto-reload, and start timer

    while(1) {
        // Do nothing, used for debug
        i++;
    }
}

Here is the debug output during the "Do nothing" state in the while loop - note that the TIM4_CNT is constantly counting.

debug output

For reference, I used the following tutorials:

\$\endgroup\$
2
  • \$\begingroup\$ just a random thought, did you init the clock for that peripheral? ARM processors have strange power-saving techniques by having each peripheral clock-controlled. - oh maybe that's what the RCC thing is, and the "enable" part. \$\endgroup\$
    – KyranF
    Commented May 19, 2015 at 3:43
  • \$\begingroup\$ I was silly and mistook 0x10 for binary 10. Shouldn't try to debug in the middle of the night, thanks though! \$\endgroup\$
    – bastinka
    Commented May 19, 2015 at 5:08

1 Answer 1

1
\$\begingroup\$

Oh wow I'm an idiot. I did "0x10" instead of "0b10", which in hex would actually be "0x2" or just 2. It's fixed now!

\$\endgroup\$
4
  • 1
    \$\begingroup\$ By refusing to use the libraries, you are missing a couple very useful things: 1) The header files contain pre-defined aliases that will make your code much more readable and much less prone to errors like this silly mistake. If you won't use the library, at least use the aliases in the header files. 2) You can download the source-code for the Standard Peripherals Library which is very well commented with instructions on how to setup the various peripherals for the various modes. IMO, every bit as useful as the reference manual. \$\endgroup\$
    – Tut
    Commented May 19, 2015 at 10:47
  • \$\begingroup\$ In learning I'd rather do it the way I'm doing it now. I probably will end up using the HAL library or similar ones. I do use some of the pre-defined aliases from header files and make my own when I see fit. Could you post the link to the standard peripherals library? I found it on STs website, but did not find links to documentation. \$\endgroup\$
    – bastinka
    Commented May 19, 2015 at 18:40
  • \$\begingroup\$ The documentation I was referring to is the comments in the source code files (.c files). You can find them in the "src" directory when you install the standard peripherals library. I think these comments on usage should have been in the header files, but they chose to put them in the source files where they are harder to get to (since your typical project would include the header files and the library file already compiled from the source). I typically look at the source code mainly for the documentation. \$\endgroup\$
    – Tut
    Commented May 19, 2015 at 18:56
  • \$\begingroup\$ ... STM32 Standard Peripherals Libraries \$\endgroup\$
    – Tut
    Commented May 19, 2015 at 18:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.