2
\$\begingroup\$

I'm learning to program the STM32F103C8 Cortex-M3 (on a BluePill board) and was playing around with the general purpose timers (TIM2 to TIM5) because I wanted to time some routines.

In my simple program I just set up the timer, set TIMx_CNT to 0 and loop until TIMx_CNT exceeds my target delay and blink a LED accordingly, to have a visible output. The relevant code is the following:

void setup() {
    /**********************************************************************
     ************************ Set up mcu clock ***************************/
    FLASH->ACR  |= FLASH_ACR_LATENCY_1;     // Set latency to 2 wait states
    RCC->CR     &= ~RCC_CR_HSEBYP;
    RCC->CR     |= RCC_CR_HSEON;            // Enable HSE
    while (!(RCC->CR & RCC_CR_HSERDY));     // Wait for HSE to be ready

    RCC->CFGR   |= RCC_CFGR_PLLSRC_HSE;     // HSE as PLL source
    RCC->CFGR   |= RCC_CFGR_PLLMULL10;      // PLL clock multiplier
    RCC->CR     |= RCC_CR_PLLON;            // Enable PLL
    while (!(RCC->CR & RCC_CR_PLLRDY));     // Wait for PLL to be ready
    RCC->CFGR   |= RCC_CFGR_SW_PLL;         // Select PLL as SYSCLK


    /**********************************************************************
     ***************************** Set up GPIO ***************************/
    // GPIOC configuration PC13, PC15
    RCC->APB2ENR    |= RCC_APB2ENR_IOPCEN;
    GPIOC->CRH  = 0x28200000;
    GPIOC->BRR  = 1 << 13;
    GPIOC->BRR  = 1 << 15;

    /**********************************************************************
     ***************************** Set up TIM3 ***************************/
    RCC->APB1ENR    |= RCC_APB1ENR_TIM3EN;
    TIM3->PSC       |= 1 << 11;               // PSC = 2048
    TIM3->CR1       |= TIM_CR1_CEN;


    /**********************************************************************
     ***************************** Call main() ***************************/
    main();
}

const uint32_t CYCLES = 39062;    // For 1sec on 1sec off blink

void main() {
    while (1) {
        GPIOC->BSRR |= 1 << 13;
        TIM3->CNT = 0;
        while(TIM3->CNT < CYCLES) {}

        GPIOC->BSRR |= 1 << (13 + 16);
        TIM3->CNT = 0;
        while(TIM3->CNT < CYCLES) {}
    }
}

To flash the board I am using the texane stlink utility.

After I flash the chip, the program runs fine, i.e. the observed blink frequency is the expected 0.5Hz. However if I then push the reset button, the LED no longer blinks (it is PWMing), and checking with the oscilloscope the blink frequency becomes 1kHz. Running the command "st-flash reset" returns everything to normal.

I've tried many things to no avail. I have also printed the TIMx_PSC register to a small GLCD and confirmed that even after the hardware reset the value is still 2048.

Also I know the APB1 bus is overclocked, but running it within spec doesn't change the observed behaviour.

Any help in understanding what is happening is greatly appreciated.

\$\endgroup\$
  • 1
    \$\begingroup\$ I suspect your sense of "normal" is actually backwards: the hardware reset button would be the usual case and what you'd probably get on power on, if it is behaving differently after the soft attempt at reset, that would be the odd case. \$\endgroup\$ – Chris Stratton Jul 29 '19 at 1:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.