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);
}

======================================

์ฐธ๊ณ