STM32 Timer - FabLabSeoul/WingProject GitHub Wiki
STM32 value line discovery ๋ณด๋ ์ ์ฉ ๊ธ์ด๋ค.
์์ ๋ STM32\stm32vldiscovery_package\Project\Examples\Timer ๊ฒฝ๋ก์ ์๋ค.
baseflight ๋ฅผ ์ด์ฉํด์ millisecond ๋จ์ ์๊ฐ์ ์ถ๋ ฅํ๋ ์์ ๋ STM32\stm32vldiscovery_package\Project\Examples\Timer_Baseflight ๊ฒฝ๋ก์ ์๋ค.
Stm32 ์์ ํ์ด๋จธ๋ฅผ ์ธ ๋ ์ฃผ์ํด์ผ ๋ ์ ์, ๋งค์ธ ํด๋ญ์ผ๋ก ํ์ด๋จธ๋ฅผ ์ฒ๋ฆฌํด์ผ ํ๋ค๋ ์ ์ด๋ค. ๊ทธ๋ฆฌ๊ณ ์ธํฐ๋ฝํธ๋ฅผ ์ด์ฉํ ๊ฒฝ์ฐ, ์ธํฐ๋ฝํธ๊ฐ ๋ฐ์๋ ํ์ ํ๋๊ทธ๋ฅผ ์ด๊ธฐํํด์ผ ์ ์์ ์ผ๋ก ์ ์๋ํ๋ค๋ ์ ์ด๋ค.
๋งค์ธ ํด๋ญ๊ณผ ํ์ด๋จธ ํด๋ญ์ ์ฐจ์ด์ ์ ์๋ ์ฐธ๊ณ ์ ์๋ ๋์์ ๊ฐ์๋ฅผ ํตํด ํ์ธํ์.
๊ฐ๋จํ๊ฒ ์ดํด๋ณด๋ฉด, Stm32vldiscovery๋ 24MHz MCU ๋ค. 1์ด์ 24,000,000๋ฒ ํ์ค๊ฐ ๋ฐ์ํ๋ค๋ ์๋ฏธ๋ค. ๋ง์ฝ ์ด ํ์ค๋ฅผ ํตํด ๋ฐ๋ฆฌ์ธ์ปจ๋ ๋จ์๋ก ์นด์ดํ ์ ํ๊ณ ์ถ๋ค๋ฉด 24MHz์ 24000 ์ ๋๋ ์ฃผ๋ฉด ๋๋ค. ๋ค์๋งํ๋ฉด, 24,000๋ฒ ํ์ค๋ง๋ค ํ๋ฒ์ฉ ์นด์ดํฐ๋ฅผ ์ฆ๊ฐ์ํค๋ฉด ๋๋ค๋ ์๋ฏธ๋ค. ์ด ๋ 24,000 ๊ฐ์ prescaler ์ด๋ผ๊ณ ๋งํ๋ค. ์ ํํ๋ 24000-1 ์ ํ ๊ฐ, 23999 ๊ฐ์ prescale ๊ฐ์ผ๋ก ๋ฃ์ด์ฃผ๋ฉด, ํ์ด๋จธ ์นด์ดํฐ๋ ์ ํํ ๋ฐ๋ฆฌ์ธ์ปจ๋ ๋จ์๋ก ์นด์ดํฐ๊ฐ ์ฌ๋ผ๊ฐ๊ฒ ๋๋ค.
๊ทธ๋ ๋ค๋ฉด 4์ด๋ง๋ค ํ ๋ฒ์ฉ ์ด๋ฒคํธ๋ฅผ ๋ฐ๊ณ ์ถ๋ค๋ฉด ์ด๋ป๊ฒ ํด์ผํ ๊น? ์์ ์ค๋ช ํ๋๋ก ๊ณ์ฐํด์ํ๋ฉด ๋์ง๋ง, ๋ณต์กํ๋ค. ๊ทธ๋์ ๋์จ๊ฒ period ๋ค. ๋ฏธ๋ฆฌ prescaler ๊ฐ์ ์ ํ ํ, ํ์ด๋จธ ์นด์ดํฐ์ ๋ง๊ฒ period๋ฅผ ์ค์ ํ๋ฉด ๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ๋ฐ๋ฆฌ์ธ์ปจ๋ ๋จ์๋ก ํ์ด๋จธ ์นด์ดํฐ๊ฐ ์ฌ๋ผ๊ฐ๊ฒ prescaler๊ฐ์ ์ค์ ํ๋ค. ๊ทธ ํ, period ๊ฐ์ผ๋ก ์ฃผ๊ธฐ๋ฅผ ์ ํ๋ค. 4์ด ํ์ ์ธํฐ๋ฝํธ๋ฅผ ๋ฐ๊ณ ์ถ๋ค๋ฉด, period๋ฅผ 4000 ์ผ๋ก ์ค์ ํ๋ฉด ๋๋ค. prescaler๋ฅผ 24,000 ์ผ๋ก ์ค์ ํ์ ๋์ ์๊ธฐ๋ค.
Stm32F100 ์ด์์ 72MHz MCU๋ ๋ง์ฐฌ๊ฐ์ง๋ค. ๋๊ฐ์ ๊ณ์ฐ๋ฒ์ ํตํด ํ์ด๋จธ ์ธํฐ๋ฝํธ๋ฅผ ๋ฐ์ ์ ์๋ค.
TIM3 ๋ฅผ ๋์ํ๊ฒ ํ๋ ํด๋ญ ์ค์
TIM3๋ APB1์ ์ํ๋ค. TIM1,2,3,4 ~ ์ ๋ฐ๋ผ APB ์ข ๋ฅ๊ฐ ๋ฌ๋ผ์ง๋ค. APB์ข ๋ฅ๊ฐ ๋ฌ๋ผ์ง๋ ํด๋ญ๋ ๋ฌ๋ผ์ง๋ค. Stm32vldiscovery๋ณด๋๋ APB1,2 ํด๋ญ์๋๋ ๋์ผํ๋ค. ์์ธํ ๋ด์ฉ์ ๋งค๋ด์ผ์ ์ฐธ๊ณ ํ์.
- APB1 : TIM2,3,4
- APB2 : TIM1
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
ํ์ด๋จธ๋ฅผ ์ด๊ธฐํํ๋ ์ฝ๋.
TIM_TimeBaseStructure.TIM_Prescaler = 24000 - 1; // 1 milli second ๋ง๋ค clock ์ด ๋ฐ์ํ๋ค. (24MHz / 24K)
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = 1000; // 1000 millisecond ๊ฐ ๋๋ฉด ์ธํฐ๋ฝํธ๋ฅผ ๋ฐ์ํ๊ฒ ํ๋ค.
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 5; // ์๋ฏธ ์์.
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
ํ์ด๋จธ ์นด์ดํฐ๊ฐ period ๋งํผ ์ฑ์์ง ๋, ์ธํฐ๋ฝํธ ๋ฐ์์ํค๊ธฐ
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
ํ์ด๋จธ ์์๊ณผ ๋์์ ์ธํฐ๋ฝํธ ์ค์ ๋ ํ๋ค.
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM3, ENABLE);
์ธํฐ๋ฝํธ๊ฐ ๋ฐ์๋๋ฉด, ํ๋๊ทธ๋ฅผ ์ด๊ธฐํ ํด์ผ ํ๋ค.
๊ณ์ ์ธํฐ๋ฝํธ๋ฅผ ๋ฐ๊ณ ์ถ๋ค๋ฉด TIM_ClearITPendingBit() ํจ์๋ฅผ ํตํด ํ๋๊ทธ๋ฅผ ์ด๊ธฐํ ํด์ผ ํ๋ค. ๊ทธ๋ ์ง ์์ผ๋ฉด ์ธํฐ๋ฝํธ๊ฐ ๊ณ์๋ฐ์๋์ด์ main() ํจ์๊ฐ ์๋ํ์ง ์๋๋ค. ์ธํฐ๋ฝํธ๋ฅผ ์ข ๋ฃํ๊ณ ์ถ๋ค๋ฉด, TIM_Cmd() ํจ์๋ฅผ ํตํด ํ์ด๋จธ๋ฅผ ๋๋ฉด ๋๋ค.
void TIM3_IRQHandler(void)
{
// TIM3 ์ด๋ฒคํธ ํธ์ถ.
if(TIM_GetITStatus(TIM3,TIM_IT_Update) != RESET)
{
g_timerCount++;
g_ledToggle = !g_ledToggle;
TIM_ClearITPendingBit(TIM3, TIM_IT_Update); // Clear the interrupt flag
}
}
์ ์ฒด ์์ค์ฝ๋
1์ด ๋ง๋ค ํ ๋ฒ์ฉ LED3,4๊ฐ ๊น๋นก๊ฑฐ๋ฆฐ๋ค.
#include "stm32f10x.h"
#include "STM32vldiscovery.h"
#include "stm32f10x_tim.h"
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
void RCC_Configuration(void);
int g_timerCount = 0;
bool g_ledToggle = FALSE;
int main()
{
RCC_Configuration();
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_TimeBaseStructure.TIM_Prescaler = 24000 - 1; // 1 milli second ๋ง๋ค clock ์ด ๋ฐ์ํ๋ค. (24MHz / 24K)
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = 1000; // 1000 millisecond ๊ฐ ๋๋ฉด ์ธํฐ๋ฝํธ๋ฅผ ๋ฐ์ํ๊ฒ ํ๋ค.
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 5; // ์๋ฏธ ์์.
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM3, ENABLE);
STM32vldiscovery_LEDInit(LED3);
STM32vldiscovery_LEDInit(LED4);
STM32vldiscovery_LEDOn(LED3);
STM32vldiscovery_LEDOn(LED4);
while (1)
{
if (g_ledToggle)
{
STM32vldiscovery_LEDOff(LED3);
STM32vldiscovery_LEDOff(LED4);
}
else
{
STM32vldiscovery_LEDOn(LED3);
STM32vldiscovery_LEDOn(LED4);
}
if (g_timerCount > 1000)
{
g_timerCount = 0;
}
}
}
void TIM3_IRQHandler(void)
{
// TIM3 ์ด๋ฒคํธ ํธ์ถ.
if(TIM_GetITStatus(TIM3,TIM_IT_Update) != RESET)
{
g_timerCount++;
g_ledToggle = !g_ledToggle;
TIM_ClearITPendingBit(TIM3, TIM_IT_Update); // Clear the interrupt flag
}
}
/**
* @brief Configures the different system clocks.
* @param None
* @retval None
*/
void RCC_Configuration(void)
{
/* TIM1, GPIOA and GPIOB clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOE |
RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
/* TIM3 and TIM4 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3 | RCC_APB1Periph_TIM4, ENABLE);
}
======================================
์ฐธ๊ณ
-
๋ฐํ์๋์ ๋์์ ๊ฐ์๊ฐ ๋์์ด ๋์๋ค.
-
ํ๊ธ๋ก ๋ ๋ํ ์ผํ ์ค๋ช