Vous êtes sur la page 1sur 5

EM MICROELECTRONIC - MARIN SA

RAISONANCE OPEN4
TUTORIAL TIMER

RAISONANCE OPEN4 TUTORIAL


TIMER: CONTROL THE TIME
The main goal of this tutorial is to experiment the user to the TIMER utilization from the OPEN4 Board using the ST Library and Circle OS.

1- Objectives:
To Begin, lets speak about the equipment used for this tutorial: OPEN4 BASE Board Primer and his Target Board STM32L152VBT6 :

The ST LIBRARY See the tutorial for ST Library Circle OS version 4.32 Ride7 Environment 7.42.12.0305 Standard Version Rkit-ARM for Ride7 1.48.13.0029 As an introduction, we will speak about the Circle OS involvement in the STM32L Plateform. Using this Illustration of STM32L Peripherals, we can see the resources used by Circle OS :

Let us focus on TIMERx use; we can see that TIM2 and TIM3 are by default used by Circle OS for MEMS and Backlight Management. By the way, lots of TIMER are unused, for example, we can use TIMER4 in upcounter mode for control the TIME (number the time spent during an operation) or control an ext source timing

This document is the property of EM MICROELECTRONIC-MARIN SA and is furnished in confidence and upon the condition that all rights originating in the information, whether patented or not, will be respected.

Page 1 of 5

EM MICROELECTRONIC - MARIN SA

RAISONANCE OPEN4
TUTORIAL TIMER

In this tutorial, you will learn how to create a handler which operates your TIMER interruption.

2-Manage your Library


In your library named: stm32lxx_tim.c or stm32nameofyourtargetboard xx_tim.c, you can access the timer initialization function and operation. By example: How to use this driver Topic which explain the function group and how to configure your Timer, but it is not exhaustive and this tutorial will complete this. void TIM_TimeBaseInit() which initialize the TIMx Time Base Unit peripheral etc just read the function description Lets begin with an example, we will create a TIMER which create an interruption every 1 ms counted by an software counter (variable incremented).

3-Timer initialization for upcounting counter.


I will bring to you my method of configuration and handler. We will focus on the TIMER4. To recall, a TIMER can create few interruption which can help you for handle some function or preemption. In our case, we will create an interruption every 1 ms by controlling the overflow of the TIMER. TIMERs have various kinds of interruption who handles specific case or state of your TIMER.

TIM_FLAG_CC1: TIM Capture Compare 1 TIM_FLAG_Trigger: TIM Trigger Flag Etc The CC1 Flag is using to compare the value of the upcounter with the Threshold value loaded in a specific register. A TIMER just increments his counter each clock cycle of the clock of your platform. If you need more information about this, head for the STM32xxx Reference Manual, Section: TIMER.

For begin, you must create a variable with the structure type TIM_TimeBaseInitTypeDef and another with TIM_OCInitTypeDef

TIM_TimeBaseInitTypeDef TIM4_InitStructure; TIM_OCInitTypeDef TIM4_OCInitStruct; These structure will contain few elements of configuration

typedef struct { uint16_t TIM_Prescaler; /*!< Specifies the prescaler value used to divide the TIM clock. This parameter can be a number between 0x0000 and 0xFFFF */ uint16_t TIM_CounterMode; /*!< Specifies the counter mode. This parameter can be a value of @ref TIM_Counter_Mode */ uint16_t TIM_Period; /*!< Specifies the period value to be loaded into the active Auto-Reload Register at the next update event. This parameter must be a number between 0x0000 and 0xFFFF. */

} TIM_TimeBaseInitTypeDef;
This document is the property of EM MICROELECTRONIC-MARIN SA and is furnished in confidence and upon the condition that all rights originating in the information, whether patented or not, will be respected.

Page 2 of 5

EM MICROELECTRONIC - MARIN SA

RAISONANCE OPEN4
TUTORIAL TIMER

For other structure or function details, please refer to the stm32lxx_tim.c and stm32lxx_tim.h. So, we configure the TIMER as below:

//CONFIGURATION TIMER 4 TIM_TimeBaseStructInit(&TIM4_InitStructure); Initialization of your structure typedef variable TIM4_InitStructure.TIM_Period = 32000; Load the Threshold of your Counter (the counter will count up to this value) In my case, I am using a 32 MHz clock, so for 1 ms timing, I must wait 32000 cycles >> 32 MHz / 32000 = 1 ms TIM4_InitStructure.TIM_Prescaler = 0x0; If you need a Prescaler, to divide the TIM Clock TIM4_InitStructure.TIM_ClockDivision = 0x0; TIM4_InitStructure.TIM_CounterMode = TIM_CounterMode_Up; Choose your mode, Upcounting here TIM_TimeBaseInit(TIM4,&TIM4_InitStructure); Use this function for integrate your choice into the structure. /* Output Compare Timing Mode configuration: Channel1 */ Configuration of the Compare register of your TIMER, refer to library TIM4_OCInitStruct.TIM_OCMode = TIM_OCMode_Timing; TIM4_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable; TIM4_OCInitStruct.TIM_Pulse = 32000; TIM4_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM4, &TIM4_OCInitStruct); TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Disable); Choose the Interruption source, here, we chose the CC1 which correspond to the Compare Register 1 TIM_ITConfig(TIM4, TIM_IT_CC1,ENABLE);

When the timer reaches the limit value (32000) the CC1 FLAG is set. Finally, you just have to launch your timer by using the function:

TIM_Cmd(TIM4,ENABLE);

In theory, this is sufficient to configure your TIMER4 but we will see that we must use other peripherals to handle interruption.

4- NVIC and External interrupt Source


You must tell to your platform that you are using a TIMER4 interruption, otherwise, the interruption will be disabled and you cant detect it. So, we must configure the preemption level of your Interruption (IRQ). For instance, the Circle OS already use the TIM2_IRQ for manage the MEMS interruption and timing. You can find in some example like the Weather Application for circle OS this code :

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); /* DISABLE the TIM2 Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; /* Mems priority */ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

Similarly to this example, we have chosen to create an Interrupt Line for TIMER4:

This document is the property of EM MICROELECTRONIC-MARIN SA and is furnished in confidence and upon the condition that all rights originating in the information, whether patented or not, will be respected.

Page 3 of 5

EM MICROELECTRONIC - MARIN SA

RAISONANCE OPEN4
TUTORIAL TIMER

/*ENABLE The TIM4 Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 4; Preemption priority maximum NVIC_InitStructure.NVIC_IRQChannelSubPriority = 4; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init( &NVIC_InitStructure ); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); Refer to stm32lxx_exti.c, stm32lxx_exti.h.; misc.c and misc.h for detail about ext LINE and NVIC configuration

5- Timer interrupt handler.


The Circle OS hosts a Task Manager with few functions for handle App and event In the library circle_api.h, you can access all the function compatible for your Circle OS. Among them, you will find the set of function UTIL_xxxx. In our example, the UTIL_SetIrqHandler function is the most interesting. Each interrupt are referenced by a tag and each Tag has an Address. For further details, refer to the STM32L15xx_reference_manual.pdf and go page 149 in the Section : Interrupts and events Or go in the "stm32l1xx.h" to the paragraph : STM32L specific Interrupt Numbers. You will find : TIM4_IRQn = 30, /*!< TIM4 global Interrupt The tag of the TIM4 global interrupt is 30, but the Address is 0x0000_00B8. So to redirect your IRQ Handler to the TIM4 IRQ Global interrupt, you just have to use the function as described below :

UTIL_SetIrqHandler( 184,(tHandler)TIM4_IT_Handler); 184 is the decimal value of 0xB8, TIM4_IT_Handler is the function launched for the Handling of the interrupt.

In our case, I have built a function who just counts the overflow of the Timer (When the counter reaches 32000, interrupt preemption).

IRQ TIM4_IT_Handler(void)
{ if (TIM_GetITStatus(TIM4, TIM_IT_CC1) != RESET) if the interruption is set { TIM_ClearITPendingBit(TIM4,TIM_IT_CC1); Reset of interrupt TIM_ClearFlag(TIM4,TIM_FLAG_Update); Reset of Flag TIM_SetCompare1(TIM4,32000); Count ++; } }

This document is the property of EM MICROELECTRONIC-MARIN SA and is furnished in confidence and upon the condition that all rights originating in the information, whether patented or not, will be respected.

Page 4 of 5

EM MICROELECTRONIC - MARIN SA

RAISONANCE OPEN4
TUTORIAL TIMER

6- In a nutshell
Activate Peripheral Clock : RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); Configure GPIO if needed Configure NVIC and EXTI Line Configure Time Base Struct Configure Timing Mode Configration Create a Handler function for your Timer (using UTIL_SetIrqHandler) Launch TIMER

This document is the property of EM MICROELECTRONIC-MARIN SA and is furnished in confidence and upon the condition that all rights originating in the information, whether patented or not, will be respected.

Page 5 of 5

Vous aimerez peut-être aussi