Untuk mendapatkan timer sebesar 1ms formulanya begini:
Time = SystemCoreClock \ ((TIM_Period+1) * (TIM_Prescaler+1))
1ms = 72MHz \ ((35999+1) * (1+1))
with prescaler 1 and TIM_CounterClock 24MHz:
1us = 24MHz \ ((23+1) * (0 + 1))
1ms = 24MHz \ ((23999+1) * (0+1))
with prescaler 999 and TIM_CounterClock 24KHz:
500ms = 24MHz \ ((1199+1) * (999+1))
1s = 24MHz \ ((23999+1) * (999+1))
or another formula is:
prescaler = (SystemCoreClock \ TIM_CounterClock) - 1;
prescaler = (24MHz \ 1MHz) - 1
prescaler = 23
1uS = 1MHz
1MHz = TIM_CounterClock \ (TIM_Period + 1)
1MHz = 1MHz \ (0 + 1)
with prescler 23 and TIM_CounterClock 1MHz:
to get 1us timer TIM_Period is 0
to get 1ms timer TIM_Period is 999
Note: cara lain untuk mendapatkan timer adalah menggunakan systick timer.
Source Code menggunakan STM32F100 Valueline discovery kit.
Hasil: Led hijau (PC9) akan toggle setiap 1s dan led biru (PC8) toggle setiap 500ms
main.c
/* Includes */
#include
#include "stm32f10x.h"
void setupHardware(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* TIM2 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM3, ENABLE);
/* GPIOC clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
/* Enable green led PC9 and blue led PC8 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/* Enable the TIM2 gloabal Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Enable the TIM3 gloabal Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void setupTimer()
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
/*------------------------------------------
SystemCoreClock
Time = -----------------------------
(TIM_Period+1) * (TIM_Prescaler+1)
1ms = 72MHz \ ((35999+1) * (1+1))
with prescaler 1 and TIM_CounterClock 24MHz:
1us = 24MHz \ ((23+1) * (0 + 1))
1ms = 24MHz \ ((23999+1) * (0+1))
with prescaler 999 and TIM_CounterClock 24KHz:
500ms = 24MHz \ ((1199+1) * (999+1))
1s = 24MHz \ ((23999+1) * (999+1))
or another formula is:
prescaler = (SystemCoreClock \ TIM_CounterClock) - 1;
prescaler = (24MHz \ 1MHz) - 1
prescaler = 23
1uS = 1MHz
1MHz = TIM_CounterClock \ (TIM_Period + 1)
1MHz = 1MHz \ (0 + 1)
with prescler 23 and TIM_CounterClock 1MHz:
to get 1us timer TIM_Period is 0
to get 1ms timer TIM_Period is 999
------------------------------------------------*/
/* Enable Timer2 for every 1s
* This will blink green led*/
TIM_TimeBaseStructure.TIM_Period = 23999;
TIM_TimeBaseStructure.TIM_Prescaler = 999;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, & TIM_TimeBaseStructure);
/*Enable Auto reload */
TIM_ARRPreloadConfig(TIM2, ENABLE);
TIM_UpdateRequestConfig(TIM2, TIM_UpdateSource_Regular);
/* TIM IT Enable */
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
/* TIM2 Enable counter */
TIM_Cmd(TIM2, ENABLE);
/*Enable Timer 3 for every 500ms
* This will blink blue led */
TIM_TimeBaseStructure.TIM_Period = 11999;
TIM_TimeBaseInit(TIM3, & TIM_TimeBaseStructure);
/*Enable Auto reload */
TIM_ARRPreloadConfig(TIM3, ENABLE);
TIM_UpdateRequestConfig(TIM3, TIM_UpdateSource_Regular);
/* TIM IT Enable */
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
/* TIM3 Enable counter */
TIM_Cmd(TIM3, ENABLE);
}
/**
**===========================================================================
**
** Abstract: main program
**
**===========================================================================
*/
int main(void)
{
/* TODO - Add your application code here */
setupHardware();
setupTimer();
/* Infinite loop */
while (1)
{
}
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* Infinite loop */
while (1)
{
}
}
#endif
/*
* Minimal __assert_func used by the assert() macro
* */
void __assert_func(const char *file, int line, const char *func, const char *failedexpr)
{
while(1)
{}
}
/*
* Minimal __assert() uses __assert__func()
* */
void __assert(const char *file, int line, const char *failedexpr)
{
__assert_func (file, line, NULL, failedexpr);
}
Jangan lupa tambah ini di file stm32f10x_it.c
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
GPIO_WriteBit(GPIOC, GPIO_Pin_9, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_9)));
}
}
void TIM3_IRQHandler(void)
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
GPIO_WriteBit(GPIOC, GPIO_Pin_8, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_8)));
}
}