0
\$\begingroup\$

i recently started my internship using embedded C and i'm having some trouble with one of the tasks: Two leds should be blinking at 1Hz, one using the hardware timer, and the other one using the RTX RTOS os_dly_wait() function. The led using the RTX RTOS task is working fine, meanwhile the other led is blinking at a higher frequency (i estimate around every ~0.9 seconds). The microcontroller is operating at 72 MHz, so i'm using the prescaler value of 7200 and using a period of 10000. I'm using the TIM2 timer. I will also include a Clock tree of the microcontroller. What could be causing this? enter image description here

#include <RTL.h>
#include "stm32f10x.h"
#include "stm32f10x_gpio.h"   
#include <rtl.h>

#define     GPS_LED_PIN  GPIO_Pin_9
#define     NAV_LED_PIN  GPIO_Pin_2

__task void task1 (void);
__task void task3 (void);

void InitLED(void) {                
    GPIO_InitTypeDef  GPIO_InitStructure;           

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE | RCC_APB2Periph_GPIOB 
                            | RCC_APB2Periph_GPIOD, ENABLE);                
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;                                 
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;       
    GPIO_Init(GPIOD, &GPIO_InitStructure);                                            
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;               
    GPIO_Init(GPIOE, &GPIO_InitStructure);                                            
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;               
    GPIO_Init(GPIOB, &GPIO_InitStructure);                      
    GPIO_SetBits(GPIOE, GPIO_Pin_2);
}    

void TurnOnLeds (void) {
    GPIO_SetBits(GPIOD, NAV_LED_PIN);
    GPIO_ResetBits(GPIOB, GPS_LED_PIN);
}           
void InitializeTimer()
{
        TIM_TimeBaseInitTypeDef timerInitStructure; 
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    timerInitStructure.TIM_Prescaler = 7200;
    timerInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    timerInitStructure.TIM_Period = 10000;
    timerInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    timerInitStructure.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM2, &timerInitStructure);
    TIM_Cmd(TIM2, ENABLE);
        TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
}
__task void task1 (void) {
    os_tsk_create(task3, 1);
    for (;;) {
        os_dly_wait(5);
        GPIO_SetBits(GPIOB, GPS_LED_PIN);
        os_dly_wait(95);
        GPIO_ResetBits(GPIOB, GPS_LED_PIN);
  }
}
__task void task3 (void) {
    for(;;)
    {
        int timerValue = TIM_GetCounter(TIM2);
       if (timerValue == 0)
             GPIO_SetBits(GPIOD, NAV_LED_PIN);
       else if (timerValue == 1000)
          GPIO_ResetBits(GPIOD, NAV_LED_PIN);
    }
}
/*-----------------------------MAIN---------------------------------------------*/  
int main(void) { 

    InitLED();
    TurnOnLeds();
    InitializeTimer();  
    os_sys_init (task1);
}
\$\endgroup\$
  • 2
    \$\begingroup\$ How do you know it's operating at 72MHz? \$\endgroup\$ – Hearth May 7 at 14:48
  • \$\begingroup\$ @Hearth it says so in the description from the datasheet. You reckon it's different? Datasheet: eu.mouser.com/datasheet/2/389/stm32f103rc-956261.pdf \$\endgroup\$ – lastkai May 7 at 14:56
  • 1
    \$\begingroup\$ 72 MHz is the maximum frequency. Go through the initialization code and figure out: Which clock source is selected (HSI or HSE) and what is it's frequency? Is the PLL enabled and what multiple? What is the AHB Prescaler set to? What is the APB1 Prescaler set to? \$\endgroup\$ – kkrambo May 7 at 15:53
  • \$\begingroup\$ If you're still unsure you can enable SYSCLK to be output through the MCO pin and then probe it with an oscilloscope and measure what the frequency really is. \$\endgroup\$ – kkrambo May 7 at 16:00
  • \$\begingroup\$ Thank you for the comments, i will try to fix the issue when i get to work tomorrow. \$\endgroup\$ – lastkai May 7 at 16:17
0
\$\begingroup\$

Just because it says it says 72MHz on the datasheet does not mean it will always run at 72MHz, it is the maximum it can run at. You don't show any initialization code so we can't tell if it has been correctly set to run at 72MHz. Inside the chip it uses much lower internal or external frequency source, which may be inaccurate.

But since you are using some kind of real-time OS, and using the delay function it provides, the delays are not exact. It just waits until the current millisecond count has been increased by the amount you requested. As the thing is completely asynchronous, assuming that you have 1ms system timer tick, there can be anything between 0 to 1ms before the next tick happens, so requesting 5ms will be in the range of 4-5 ms, so statistically speaking delay is always 0.5ms less.

I don't see why the led driven by TIMER2 counter even works. It will be awfully hard with a RTOS to hit to a point when counter is exactly 0 or exactly 1000. One count being 72MHz divided by the 7200 prescaler, so it's 0.1ms !

\$\endgroup\$

Your Answer

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

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