CPU/STM32F103

STM32 TIM3 PWM MODE

멋진 고파 2013. 2. 8. 21:14

이번엔 TIMER3를 이용해서 PWM모드를 실험해 보겠씁니다.

Example description

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

This example shows how to configure the TIM peripheral in PWM (Pulse Width Modulation) mode.

The TIMxCLK frequency is set to 36 MHz, the Prescaler is 0 so the TIM3 counter clock is 36 MHz. 


The TIM3 is running at 36 KHz: TIM3 Frequency = TIM3 counter clock/(ARR + 1) 


The TIM3 CCR1 register value is equal to 500, so the TIM3 Channel 1 generates a 

PWM signal with a frequency equal to 36 KHz and a duty cycle equal to 50%:

TIM3 Channel1 duty cycle = (TIM3_CCR1/ TIM3_ARR + 1)* 100 = 50%


The TIM3 CCR2 register value is equal to 375, so the TIM3 Channel 2 generates a 

PWM signal with a frequency equal to 36 KHz and a duty cycle equal to 37.5%:

TIM3 Channel2 duty cycle = (TIM3_CCR2/ TIM3_ARR + 1)* 100 = 37.5%


The TIM3 CCR3 register value is equal to 250, so the TIM3 Channel 3 generates a 

PWM signal with a frequency equal to 36 KHz and a duty cycle equal to 25%:

TIM3 Channel3 duty cycle = (TIM3_CCR3/ TIM3_ARR + 1)* 100 = 25%


The TIM3 CCR4 register value is equal to 125, so the TIM3 Channel 4 generates a 

PWM signal with a frequency equal to 36 KHz and a duty cycle equal to 12.5%:

TIM3 Channel4 duty cycle = (TIM3_CCR4/ TIM3_ARR + 1)* 100 = 12.5%


The PWM waveform can be displayed using an oscilloscope.


이전에 Timer Overflow와 비슷합니다.

1. stm32f10x_conf.h 추가
#define _TIM3

2. 프로젝트에 stm32f10x_tim.c를 추가 한다.

3. 클럭관련 설정
void TIM3_Configuration_RCC(void)
{
  /* TIM3 clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
  
}
4. PWM 출력 GPIO를 설정합니다.
void GPIO_Configuration_TIM3(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

  /*GPIOA Configuration: TIM3 channel 1 and 2 as alternate function push-pull */
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /*GPIOB Configuration: TIM3 channel 3 and 4 as alternate function push-pull */
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_0 | GPIO_Pin_1;

  GPIO_Init(GPIOB, &GPIO_InitStructure);
}

위의 내용같이 PORT A 6,7 / PORT B 3,4 번 입니다. PP모드네요.

5. 초기화
void TIM3_Configuration(void)
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  TIM_OCInitTypeDef  TIM_OCInitStructure;

  TIM3_Configuration_RCC();
  /* -----------------------------------------------------------------------
    TIM3 Configuration: generate 4 PWM signals with 4 different duty cycles:
    TIM3CLK = 36 MHz, Prescaler = 0x0, TIM3 counter clock = 36 MHz
    TIM3 ARR Register = 999 => TIM3 Frequency = TIM3 counter clock/(ARR + 1)
    TIM3 Frequency = 36 KHz.
    TIM3 Channel1 duty cycle = (TIM3_CCR1/ TIM3_ARR)* 100 = 50%
    TIM3 Channel2 duty cycle = (TIM3_CCR2/ TIM3_ARR)* 100 = 37.5%
    TIM3 Channel3 duty cycle = (TIM3_CCR3/ TIM3_ARR)* 100 = 25%
    TIM3 Channel4 duty cycle = (TIM3_CCR4/ TIM3_ARR)* 100 = 12.5%
  ----------------------------------------------------------------------- */

  /* Time base configuration */
  1> TIM_TimeBaseStructure.TIM_Period = 999;
  2>TIM_TimeBaseStructure.TIM_Prescaler = 0;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

  /* PWM1 Mode configuration: Channel1 */
  3>TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  4>TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  5>TIM_OCInitStructure.TIM_Pulse = CCR1_Val;
  6>TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;    // MATCH 시 HIGH
   // TIM_OCPlarity_Low는 반대

  7>TIM_OC1Init(TIM3, &TIM_OCInitStructure);

  8>TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);

  /* PWM1 Mode configuration: Channel2 */
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = CCR2_Val;

  9>TIM_OC2Init(TIM3, &TIM_OCInitStructure);

  10>TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);

  /* PWM1 Mode configuration: Channel3 */
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = CCR3_Val;

  11>TIM_OC3Init(TIM3, &TIM_OCInitStructure);

  12>TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);

  /* PWM1 Mode configuration: Channel4 */
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = CCR4_Val;

  13>TIM_OC4Init(TIM3, &TIM_OCInitStructure);

  14>TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);

  15>TIM_ARRPreloadConfig(TIM3, ENABLE);

  /* TIM3 enable counter */
  16> TIM_Cmd(TIM3, ENABLE);
}

1> 에서 999로 설정하니 1000개 마다 반복이 되겠네요.
2> 0분주하니 36MHZ입력되서 36KHZ가 주기가 되겠네요.
3> PWM 모드를 설정합니다ㅏ.
4> OUTPUT MODE를 설정
5> PWM %를 설정하네요.
7> OC1 레지스터에 적용합니다.
8> 타이머 모드 ENABLE합니다.
9> 10>은 OC2 레지스터 설정후 타이머 ENABLE합니다.
11> 12>은 OC3 레지스터 설정후 타이머 ENABLE합니다.
13> 14>은 OC4 레지스터 설정후 타이머 ENABLE합니다.
15> TIM ARRPreload설정
16> TIM3 ENABLE

6. Main함수
u16 CCR1_Val3 = 500;
u16 CCR2_Val3 = 375;
u16 CCR3_Val3 = 250;
u16 CCR4_Val3 = 125;

main()
{
......
TIM3_Configuration();

while(1);
}

이렇게 해서 PWM를 해 보았습니다.

STM32는 TIM2,3,4가 같으므로 PWM3 *4 = 12개를 만들어 낼수 있네요.
TIM1은 지원될랑가 모르겠네요? 되면 16개를 만들어 낼수 있는데..해당 포트가 되는가 모르겠네요.
TIM2-3는 출력 포트가 있는데 TIM1은 표시가 좀 틀리네요.
어째든 12개는 기본적으로 사용할수 있습니다. 다만 UART2와 I2C1은 포기 해야되네요.