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
}
'초보의 아웅다웅 설계하기 > STM32' 카테고리의 다른 글
[DMA 매핑] STM32F42X, STM32F43X (0) | 2024.08.19 |
---|---|
74HC595(시프트 레지스터) 테스트 (4) | 2023.12.05 |
치과용 초음파 세척 (0) | 2023.06.30 |
SSD1362 (0) | 2023.05.18 |
[STM32]PCF8575 I/O 확장 칩 테스트 프로그램 (0) | 2023.03.15 |