초보의 아웅다웅 설계하기/STM32

STM32F103 PWM 주파수 설정

로망와니 2023. 7. 8. 15:44

PWM 주파수 설정

 

/* 40kHz */
Set_US_CTRLDuty(40000, 50);

 

 

/*******************************************************************************
* Function Name : 
* Parameters    : None
* Return        : None
* Description   : 
*******************************************************************************/
void TIM3_Init(u8 a_chOption, u32 a_nPrescaler, u32 a_nPeriod, u16 a_nDuty)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  TIM_OCInitTypeDef  TIM_OCInitStructure;

if(a_chOption == 1){
/* TIM Disable */
TIM3->CR1 &= (uint16_t)~TIM_CR1_CEN;
/* Init TIM Status */
TIM3->CNT = 0;
TIM3->SR = 0;

TIM3->CCR1 = 0;

/* CH1 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

if(a_nDuty == 0)
GPIO_ResetBits(GPIOA, GPIO_Pin_6);
else
GPIO_SetBits(GPIOA, GPIO_Pin_6);

/* GPIOA Configuration:TIM1 Channel 1 alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
else{
/* TIM Disable */
TIM3->CR1 &= (uint16_t)~TIM_CR1_CEN;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

/* CH1 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

/* GPIOA Configuration:TIM1 Channel 1 alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);

/* Time base configuration */
/* TIM3 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
#if 0 /* 1us */
TIM_TimeBaseStructure.TIM_Prescaler =  72-1;//72Mhz
#else
TIM_TimeBaseStructure.TIM_Prescaler =  a_nPrescaler-1;
#endif
TIM_TimeBaseStructure.TIM_Period = a_nPeriod - 1; //(72MHz/72)/a_nPeriod = x Hz
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

/* Init TIM Status */
TIM3->CNT = 0;
TIM3->SR = 0;

/* PWM1 Mode configuration: Channel 1 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_Pulse = a_nDuty;//a_nDuty;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
#if 0
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
#else
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
#endif
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; 
TIM_OC1Init(TIM3, &TIM_OCInitStructure);

TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM3, ENABLE);

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

#define TIMPRESCLER_1 1
#define TIMPRESCLER_2 2
#define TIMPRESCLER_10 10
#define TIMPRESCLER_20 20
#define TIMPRESCLER_100 100
#define TIMPRESCLER_200 200
#define TIMPRESCLER_1000 1000
#define TIMPRESCLER_10000 10000
#define TIMPRESCLER_20000 20000

#define TIM3CLOCK 72000000

#define MAXDUTY 100
#define MAXFREQ 50000
#define MINFREQ 0
/*******************************************************************************
* Function Name : 
* Description   : 
* Parameters    : None
* Return        : None
* Description   : 
*******************************************************************************/
void Set_US_CTRLDuty(u16 Frequency, u8 a_chLD_CTRLPWM)
{
__IO uint16_t Prescler = 0;
__IO uint32_t Period = 0;
__IO uint32_t Duty = 0;

if(Frequency > MAXFREQ)
Frequency = MAXFREQ;

if(a_chLD_CTRLPWM >= MAXDUTY)
a_chLD_CTRLPWM = MAXDUTY;

#if defined(PRINTLD)
DEBUGPRINT("Frequency %d\r\n", Frequency);
DEBUGPRINT("Pulse %d\r\n", a_chLD_CTRLPWM);
#endif
if(Frequency > MINFREQ){
if(Frequency >= 1400){
Prescler = TIMPRESCLER_1;
Period = (TIM3CLOCK/(TIMPRESCLER_1))/Frequency;
Duty = (Period * a_chLD_CTRLPWM)/MAXDUTY;
}
else if(Frequency < 1400 && Frequency >= 140){
Prescler = TIMPRESCLER_10;
Period = (TIM3CLOCK/(TIMPRESCLER_10))/Frequency;
Duty = (Period * a_chLD_CTRLPWM)/MAXDUTY;
}
else if(Frequency < 140 && Frequency >= 14){
Prescler = TIMPRESCLER_100;
Period = (TIM3CLOCK/(TIMPRESCLER_100))/Frequency;
Duty = (Period * a_chLD_CTRLPWM)/MAXDUTY;
}
else{
Prescler = TIMPRESCLER_10000;
Period = (TIM3CLOCK/(TIMPRESCLER_10000))/Frequency;
Duty = (Period * a_chLD_CTRLPWM)/MAXDUTY;
}
/* TIM3 */
TIM3_Init(0, (u16)Prescler, Period, Duty);
}
else{
TIM3_Init(1, 0, 0, a_chLD_CTRLPWM);
}
#if 1
DEBUGPRINT("Prescler %d, Period %d, Duty %d\r\n", Prescler, Period, Duty);
#endif
}