이번엔 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 추가
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은 포기 해야되네요.