/** * @brief Main program. * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f0xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f0xx.c file */ /* TIM Configuration */ TIM_Config(); TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_OCStructInit(&TIM_OCInitStructure); /* --------------------------------------------------------------------------- TIM3 Configuration: Output Compare Active Mode: In this example TIM3 input clock (TIM3CLK) is set to APB1 clock (PCLK1) TIM3CLK = PCLK1 PCLK1 = HCLK => TIM3CLK = HCLK = SystemCoreClock To get TIM3 counter clock at 1 KHz, the prescaler is computed as follows: Prescaler = (TIM3CLK / TIM3 counter clock) - 1 Prescaler = (SystemCoreClock /1 KHz) - 1 Generate 4 signals with 4 different delays: TIM3_CH1 delay = CCR1_Val/TIM3 counter clock = 1000 ms TIM3_CH2 delay = CCR2_Val/TIM3 counter clock = 500 ms TIM3_CH3 delay = CCR3_Val/TIM3 counter clock = 250 ms TIM3_CH4 delay = CCR4_Val/TIM3 counter clock = 125 ms Note: SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f0xx.c file. Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate() function to update SystemCoreClock variable value. Otherwise, any configuration based on this variable will be incorrect. --------------------------------------------------------------------------- */ /*Compute the prescaler value */ PrescalerValue = (uint16_t) (SystemCoreClock / 1000) - 1; /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 65535; TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); /* Output Compare Active Mode configuration: Channel1 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Active; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_Pulse = CCR1_Val; TIM_OC1Init(TIM3, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Disable); TIM_ARRPreloadConfig(TIM3, DISABLE); /* Output Compare Active Mode configuration: Channel2 */ TIM_OCInitStructure.TIM_Pulse = CCR2_Val; TIM_OC2Init(TIM3, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Disable); /* Output Compare Active Mode configuration: Channel3 */ TIM_OCInitStructure.TIM_Pulse = CCR3_Val; TIM_OC3Init(TIM3, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Disable); /* Output Compare Active Mode configuration: Channel4 */ TIM_OCInitStructure.TIM_Pulse = CCR4_Val; TIM_OC4Init(TIM3, &TIM_OCInitStructure); TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Disable); /* TIM3 enable counter */ TIM_Cmd(TIM3, ENABLE); TIM_GenerateEvent(TIM3, TIM_EventSource_Update); /* Turn on LED1 */ STM_EVAL_LEDOn(LED1); /* Infinite loop */ while (1) { } }
/******************************************************************************* * Function Name : main * Description : Main program * Input : None * Output : None * Return : None *******************************************************************************/ int main(void) { #ifdef DEBUG debug(); #endif /* System Clocks Configuration */ RCC_Configuration(); /* NVIC Configuration */ NVIC_Configuration(); /* GPIO Configuration */ GPIO_Configuration(); /* --------------------------------------------------------------- TIM2 Configuration: Output Compare Inactive Mode: TIM2CLK = 36 MHz, Prescaler = 35999, TIM2 counter clock = 1 KHz TIM2_CH1 delay = CCR1_Val/TIM2 counter clock = 1000 ms TIM2_CH2 delay = CCR2_Val/TIM2 counter clock = 500 ms TIM2_CH3 delay = CCR3_Val/TIM2 counter clock = 250 ms TIM2_CH4 delay = CCR4_Val/TIM2 counter clock = 125 ms --------------------------------------------------------------- */ /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 65535; TIM_TimeBaseStructure.TIM_Prescaler = 35999; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); /* Output Compare Active Mode configuration: Channel1 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Inactive; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR1_Val; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM2, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Disable); /* Output Compare Active Mode configuration: Channel2 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR2_Val; TIM_OC2Init(TIM2, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Disable); /* Output Compare Active Mode configuration: Channel3 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR3_Val; TIM_OC3Init(TIM2, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Disable); /* Output Compare Active Mode configuration: Channel4 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR4_Val; TIM_OC4Init(TIM2, &TIM_OCInitStructure); TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Disable); TIM_ARRPreloadConfig(TIM2, ENABLE); /* TIM IT enable */ TIM_ITConfig(TIM2, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, ENABLE); /* Set PC.06, PC.07, PC.08 and PC.09 pins */ GPIO_SetBits(GPIOC, GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9); /* TIM2 enable counter */ TIM_Cmd(TIM2, ENABLE); while (1) {} }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f10x_xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f10x.c file */ /* System Clocks Configuration */ RCC_Configuration(); /* NVIC Configuration */ NVIC_Configuration(); /* GPIO Configuration */ GPIO_Configuration(); /* --------------------------------------------------------------------------- TIM3 Configuration: Output Compare Toggle Mode: TIM3CLK = SystemCoreClock / 2, The objective is to get TIM3 counter clock at 12 MHz: - Prescaler = (TIM3CLK / TIM3 counter clock) - 1 CC1 update rate = TIM3 counter clock / CCR1_Val = 366.2 Hz CC2 update rate = TIM3 counter clock / CCR2_Val = 732.4 Hz CC3 update rate = TIM3 counter clock / CCR3_Val = 1464.8 Hz CC4 update rate = TIM3 counter clock / CCR4_Val = 2929.6 Hz ----------------------------------------------------------------------------*/ /* Compute the prescaler value */ PrescalerValue = (uint16_t) (SystemCoreClock / 24000000) - 1; /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 65535; TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); /* Output Compare Toggle Mode configuration: Channel1 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR1_Val; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OC1Init(TIM3, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Disable); /* Output Compare Toggle Mode configuration: Channel2 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR2_Val; TIM_OC2Init(TIM3, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Disable); /* Output Compare Toggle Mode configuration: Channel3 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR3_Val; TIM_OC3Init(TIM3, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Disable); /* Output Compare Toggle Mode configuration: Channel4 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR4_Val; TIM_OC4Init(TIM3, &TIM_OCInitStructure); TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Disable); /* TIM enable counter */ TIM_Cmd(TIM3, ENABLE); /* TIM IT enable */ TIM_ITConfig(TIM3, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, ENABLE); while (1) {} }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f10x_xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f10x.c file */ /* System Clocks Configuration */ RCC_Configuration(); /* NVIC Configuration */ NVIC_Configuration(); /* GPIO Configuration */ GPIO_Configuration(); /* --------------------------------------------------------------- TIM2 Configuration: TIM2CLK = SystemCoreClock / 2, The objective is to get TIM2 counter clock at 1 KHz: - Prescaler = (TIM2CLK / TIM2 counter clock) - 1 And generate 4 signals with 4 different delays: TIM2_CH1 delay = CCR1_Val/TIM2 counter clock = 1000 ms TIM2_CH2 delay = CCR2_Val/TIM2 counter clock = 500 ms TIM2_CH3 delay = CCR3_Val/TIM2 counter clock = 250 ms TIM2_CH4 delay = CCR4_Val/TIM2 counter clock = 125 ms * SystemCoreClock is set to 72 MHz for Low-density, Medium-density, High-density and Connectivity line devices and to 24 MHz for Low-Density Value line and Medium-Density Value line devices --------------------------------------------------------------- */ /* Compute the prescaler value */ PrescalerValue = (uint16_t) (SystemCoreClock / 2000) - 1; /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 65535; TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); /* Output Compare Active Mode configuration: Channel1 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Inactive; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR1_Val; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM2, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Disable); /* Output Compare Active Mode configuration: Channel2 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR2_Val; TIM_OC2Init(TIM2, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Disable); /* Output Compare Active Mode configuration: Channel3 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR3_Val; TIM_OC3Init(TIM2, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Disable); /* Output Compare Active Mode configuration: Channel4 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR4_Val; TIM_OC4Init(TIM2, &TIM_OCInitStructure); TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Disable); TIM_ARRPreloadConfig(TIM2, ENABLE); /* TIM IT enable */ TIM_ITConfig(TIM2, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, ENABLE); /* Set PC.06, PC.07, PC.08 and PC.09 pins */ GPIO_SetBits(GPIOC, GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9); /* TIM2 enable counter */ TIM_Cmd(TIM2, ENABLE); while (1) {} }
static void Timer_OC_Config(TIM_TypeDef* TIMn,uint8_t Channel,uint32_t SET_PrescalerValue,uint32_t Period) { uint16_t CCR_Val = 0; uint16_t PrescalerValue = 0; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; if(TIMn == TIM2) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); else if(TIMn == TIM3) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); else if(TIMn == TIM4) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE); else if(TIMn == TIM5) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE); else if(TIMn == TIM12) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM12,ENABLE); else if(TIMn == TIM13) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM13,ENABLE); else { if(TIMn == TIM14) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE); } // TIM_DeInit(TIMn); if(CCR_Val < Period) { /* Compute the prescaler value */ PrescalerValue = (uint16_t) ((60000000) / SET_PrescalerValue) - 1; //config the input frequency 20K /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period =Period; TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIMn, &TIM_TimeBaseStructure); // // TIM_ClearFlag(TIMn,TIM_FLAG_Update); // TIM_ITConfig(TIMn,TIM_IT_Update,ENABLE); /* PWM1 Mode configuration: Channel2 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR_Val; //CCR的值,设置占空比 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; if(Channel == 1) { TIM_OC1Init(TIMn, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIMn, TIM_OCPreload_Enable); } else if(Channel == 2) { TIM_OC2Init(TIMn, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIMn, TIM_OCPreload_Enable); } else if(Channel == 3) { TIM_OC3Init(TIMn, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIMn, TIM_OCPreload_Enable); } else { if(Channel == 4) { TIM_OC4Init(TIMn, &TIM_OCInitStructure); TIM_OC4PreloadConfig(TIMn, TIM_OCPreload_Enable); } } TIM_ARRPreloadConfig(TIMn, ENABLE); //自动重装载寄存器 TIM_Cmd(TIMn, ENABLE); } }
/** * Initialize the three phase (6outputs) PWM peripheral and internal state. */ void pwm_init(void) { NVIC_InitTypeDef nvic; GPIO_InitTypeDef gpio; TIM_TimeBaseInitTypeDef tim_base; TIM_OCInitTypeDef tim_oc; TIM_BDTRInitTypeDef tim_bdtr; (void)gpc_setup_reg(GPROT_PWM_OFFSET_REG_ADDR, &pwm_offset); /* Enable clock for TIM1 subsystem */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE); /* Enable TIM1 interrupt */ nvic.NVIC_IRQChannel = TIM1_TRG_COM_IRQn; nvic.NVIC_IRQChannelPreemptionPriority = 0; nvic.NVIC_IRQChannelSubPriority = 1; nvic.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&nvic); /* Enable TIM1 interrupt */ nvic.NVIC_IRQChannel = TIM1_CC_IRQn; nvic.NVIC_IRQChannelPreemptionPriority = 0; nvic.NVIC_IRQChannelSubPriority = 1; nvic.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&nvic); /* GPIOA: TIM1 channel 1, 2 and 3 as alternate function push-pull */ gpio.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10; gpio.GPIO_Mode = GPIO_Mode_AF_PP; gpio.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &gpio); /* GPIOB: TIM1 channel 1N, 2N and 3N as alternate function * push-pull */ gpio.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; GPIO_Init(GPIOB, &gpio); /* Time base configuration */ tim_base.TIM_Period = PWM__BASE_CLOCK / PWM__FREQUENCY; tim_base.TIM_Prescaler = 0; tim_base.TIM_ClockDivision = 0; tim_base.TIM_CounterMode = TIM_CounterMode_Up; tim_base.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM1, &tim_base); /* TIM1 channel 1, 2 and 3 settings */ tim_oc.TIM_OCMode = TIM_OCMode_Timing; tim_oc.TIM_OutputState = TIM_OutputState_Enable; tim_oc.TIM_OutputNState = TIM_OutputNState_Enable; tim_oc.TIM_Pulse = pwm_val; tim_oc.TIM_OCPolarity = TIM_OCPolarity_High; tim_oc.TIM_OCNPolarity = TIM_OCNPolarity_High; tim_oc.TIM_OCIdleState = TIM_OCIdleState_Set; tim_oc.TIM_OCNIdleState = TIM_OCNIdleState_Set; TIM_OC1Init(TIM1, &tim_oc); TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); TIM_OC2Init(TIM1, &tim_oc); TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable); TIM_OC3Init(TIM1, &tim_oc); TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable); /* TIM1 configure channel 4 as adc trigger source */ tim_oc.TIM_OCMode = TIM_OCMode_PWM2; tim_oc.TIM_Pulse = pwm_offset; TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable); TIM_OC4Init(TIM1, &tim_oc); /* Automatic Output enable, break, dead time and lock configuration */ tim_bdtr.TIM_OSSRState = TIM_OSSRState_Enable; tim_bdtr.TIM_OSSIState = TIM_OSSIState_Enable; tim_bdtr.TIM_LOCKLevel = TIM_LOCKLevel_OFF; tim_bdtr.TIM_DeadTime = 10; tim_bdtr.TIM_Break = TIM_Break_Disable; tim_bdtr.TIM_BreakPolarity = TIM_BreakPolarity_High; tim_bdtr.TIM_AutomaticOutput = TIM_AutomaticOutput_Disable; TIM_BDTRConfig(TIM1, &tim_bdtr); TIM_CCPreloadControl(TIM1, ENABLE); /* Enable COM and CC interrupt */ TIM_ITConfig(TIM1, TIM_IT_COM, ENABLE); //TIM_ITConfig(TIM1, TIM_IT_COM | TIM_IT_CC4, ENABLE); /* TIM1 enable counter */ TIM_Cmd(TIM1, ENABLE); /* Main output enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); /* Setting default state of pwm to pwm_off */ pwm_off(); }
OSStatus platform_pwm_init( const platform_pwm_t* pwm, uint32_t frequency, float duty_cycle ) { TIM_TimeBaseInitTypeDef tim_time_base_structure; TIM_OCInitTypeDef tim_oc_init_structure; RCC_ClocksTypeDef rcc_clock_frequencies; uint16_t period = 0; float adjusted_duty_cycle = ( ( duty_cycle > 100.0f ) ? 100.0f : duty_cycle ); OSStatus err = kNoErr; require_action_quiet( pwm != NULL, exit, err = kParamErr); platform_mcu_powersave_disable(); RCC_GetClocksFreq( &rcc_clock_frequencies ); if ( pwm->tim == TIM1 || pwm->tim == TIM8 || pwm->tim == TIM9 || pwm->tim == TIM10 || pwm->tim == TIM11 ) { RCC_APB2PeriphClockCmd( pwm->tim_peripheral_clock, ENABLE ); if( rcc_clock_frequencies.PCLK2_Frequency == rcc_clock_frequencies.HCLK_Frequency ) period = (uint16_t)( rcc_clock_frequencies.PCLK2_Frequency / 20 / frequency - 1 ); /* Auto-reload value counts from 0; hence the minus 1 */ else period = (uint16_t)( rcc_clock_frequencies.PCLK2_Frequency * 2 / 20 / frequency - 1 ); /* Auto-reload value counts from 0; hence the minus 1 */ } else { RCC_APB1PeriphClockCmd( pwm->tim_peripheral_clock, ENABLE ); if( rcc_clock_frequencies.PCLK1_Frequency == rcc_clock_frequencies.HCLK_Frequency ) period = (uint16_t)( rcc_clock_frequencies.PCLK1_Frequency / 20 / frequency - 1 ); /* Auto-reload value counts from 0; hence the minus 1 */ else period = (uint16_t)( rcc_clock_frequencies.PCLK1_Frequency * 2 / 20 / frequency - 1 ); /* Auto-reload value counts from 0; hence the minus 1 */ } /* Set alternate function */ platform_gpio_set_alternate_function( pwm->pin->port, pwm->pin->pin_number, GPIO_OType_PP, GPIO_PuPd_UP, pwm->gpio_af ); /* Time base configuration */ tim_time_base_structure.TIM_Period = (uint32_t) period; tim_time_base_structure.TIM_Prescaler = (uint16_t) 19; /* Divide clock by 19 + 1 to enable a count of high cycle + low cycle = 1 PWM cycle */ tim_time_base_structure.TIM_ClockDivision = 0; tim_time_base_structure.TIM_CounterMode = TIM_CounterMode_Up; tim_time_base_structure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit( pwm->tim, &tim_time_base_structure ); /* PWM1 Mode configuration */ tim_oc_init_structure.TIM_OCMode = TIM_OCMode_PWM1; tim_oc_init_structure.TIM_OutputState = TIM_OutputState_Enable; tim_oc_init_structure.TIM_OutputNState = TIM_OutputNState_Enable; tim_oc_init_structure.TIM_Pulse = (uint16_t) ( adjusted_duty_cycle * (float) period / 100.0f ); tim_oc_init_structure.TIM_OCPolarity = TIM_OCPolarity_High; tim_oc_init_structure.TIM_OCNPolarity = TIM_OCNPolarity_High; tim_oc_init_structure.TIM_OCIdleState = TIM_OCIdleState_Reset; tim_oc_init_structure.TIM_OCNIdleState = TIM_OCIdleState_Set; switch ( pwm->channel ) { case 1: { TIM_OC1Init( pwm->tim, &tim_oc_init_structure ); TIM_OC1PreloadConfig( pwm->tim, TIM_OCPreload_Enable ); break; } case 2: { TIM_OC2Init( pwm->tim, &tim_oc_init_structure ); TIM_OC2PreloadConfig( pwm->tim, TIM_OCPreload_Enable ); break; } case 3: { TIM_OC3Init( pwm->tim, &tim_oc_init_structure ); TIM_OC3PreloadConfig( pwm->tim, TIM_OCPreload_Enable ); break; } case 4: { TIM_OC4Init( pwm->tim, &tim_oc_init_structure ); TIM_OC4PreloadConfig( pwm->tim, TIM_OCPreload_Enable ); break; } default: { break; } } exit: platform_mcu_powersave_enable(); return err; }
/****************************************************************************** * タイトル : PWM初期設定 * 関数名 : Init_PWM * 戻り値 : int型 0:設定できた 1:設定できない * 引数1 : TIM_TypeDef *型 TIMx TIMx TIMのポインタ * 引数2 : GPIO_TypeDef型 *GPIOx GPIOx GPIOのポインタ * 引数3 : uint16_t型 pin GPIO_Pin_x PINの設定 * 引数4 : int型 frequency PWM周波数[Hz](整数) * 作成者 : 永谷 智貴 * 作成日 : 2014/11/10 ******************************************************************************/ int Init_PWM(TIM_TypeDef * TIMx,GPIO_TypeDef *GPIOx,uint16_t pin,int frequency)//エラーがあれば1、なければ0をreturnする { long TIM_clock=0; int prescaler=0; int period=0; int calc_retry_flag=1; //float error_ratio=0; unsigned short i = 0; Pin_t pin_state;// //システムクロックをRCC_Clocksで取得 SystemCoreClockUpdate(); RCC_ClocksTypeDef RCC_Clocks; RCC_GetClocksFreq(&RCC_Clocks); //TIMのクロックの取得 if((TIM2<=TIMx&&TIMx<=TIM7)||(TIM12<=TIMx&&TIMx<=TIM14)){ TIM_clock=RCC_Clocks.PCLK1_Frequency*((RCC_TIMPRE+1)*2); //PCLK1のTIMプリスケーラ倍したらTIM2-7,12-14のクロックが出てくる }else{ TIM_clock=RCC_Clocks.PCLK2_Frequency*((RCC_TIMPRE+1)*2); //PCLK2のTIMプリスケーラ倍したら上のやつ以外のクロックが出てくる } #ifdef PRINTF_AVAILABLE printf("Init_PWM() start.\nTIM_clock:%d,\n",TIM_clock); #endif //上下の設定可能な周波数の中に納まっているか確認 if(frequency<FREQUENCY_UNDER_LIMIT || frequency>TIM_clock/PRESCALER_UNDER_LIMIT/PERIOD_UNDER_LIMIT) { #ifdef PRINTF_AVAILABLE printf("Error. Frequency value out of range. '%d' - '%d' Requested frequency '%d'\n",FREQUENCY_UNDER_LIMIT,TIM_clock/PRESCALER_UNDER_LIMIT/PERIOD_UNDER_LIMIT,frequency); #endif return 1; //おかしければエラー返して終了 } //prescaler,periodを計算 while(calc_retry_flag) //periodが制限内の最大になるまでprescalerを上げているだけ。計算でも出せるけど、見た目だけはこっちのほうがきれい。 { prescaler++; period=TIM_clock/prescaler/frequency; if(period<=PERIOD_LIMIT) calc_retry_flag=0; if(prescaler>=PRESCALER_LIMIT){ //prescalerが上の制限を超しちゃったらエラーを履くけどそうはならない。 #ifdef PRINTF_AVAILABLE printf("Error. Prescaler value out of range. '%d'-'%d' \n",PRESCALER_UNDER_LIMIT,PRESCALER_LIMIT); #endif return 1; //おかしければエラー返して終了 } } // error_ratio=fabs(((float)TIM_clock/prescaler/period-(float)frequency)/(float)frequency)*100;//周波数の誤差をパーセントで計算。1%以内には納まる。 frequency=TIM_clock/prescaler/period; //設定した数値から算出される周波数 大体同じ。 #ifdef PRINTF_AVAILABLE printf("Result: \n period:%d,\n prescaler:%d,\n frequency:%d,\n\n",period,prescaler,frequency); #endif //ここから普通のPWM設定 //設定に使用する構造体の宣言 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //TIM設定用構造体宣言 TIM_OCInitTypeDef TIM_OCInitStructure; //OC設定用構造体宣言 TIM_BDTRInitTypeDef TIM_BDTRInitStructure; //クロック供給 RCC_PeriphClock_TIM(TIMx);//TIMクロック供給 //クロック供給とGPIO設定 Init_port(GPIO_Mode_AF,GPIOx,pin,GPIO_PuPd_NOPULL,GPIO_OType_PP); //TIM設定 TIM_TimeBaseStructure.TIM_Period = period-1; //計算したperiod-1 TIM_TimeBaseStructure.TIM_Prescaler = prescaler-1; //計算したprescaler-1 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //なんかここ変えても周波数変わらなかったんだよね ナニコレ TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //カウンターモードアップ設定 TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; //高機能タイマー用 基本0 TIM_TimeBaseInit(TIMx,&TIM_TimeBaseStructure); //設定書き込み TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //PWMモード1 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //アクティブレベル時の極性をHighレベルにセット TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //タイマ出力を有効化 TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set; TIM_OC1Init(TIMx,&TIM_OCInitStructure); //初期化 TIM_OC1PreloadConfig(TIMx,TIM_OCPreload_Disable); //プリロード不許可 TIM_OC2Init(TIMx,&TIM_OCInitStructure); //初期化 TIM_OC2PreloadConfig(TIMx,TIM_OCPreload_Disable); //プリロード不許可 TIM_OC3Init(TIMx,&TIM_OCInitStructure); //初期化 TIM_OC3PreloadConfig(TIMx,TIM_OCPreload_Disable); //プリロード不許可 TIM_OC4Init(TIMx,&TIM_OCInitStructure); //初期化 TIM_OC4PreloadConfig(TIMx,TIM_OCPreload_Disable); //プリロード不許可 //使用するピンをTIMの出力として設定 // GPIO_PinAFConfig(GPIOx,Pin_select_source(pin),Tim_select_af(TIMx));//AF設定 /*TIM1とTIM8はSTM32の中でも高機能タイマに分類され、 モータ制御用に使用されるBREAK入力機能がついている このBREAK機能の中でoutputの有効化という機能があり、デフォルトの設定で タイマー出力ごとにoutputが無効に設定されているためPWM信号が止まる。 そのため、 タイマの更新イベントごとにoutputが自動的に再有効になるように設定する。*/ if(TIMx == TIM1 || TIMx == TIM8){ TIM_BDTRStructInit(&TIM_BDTRInitStructure); TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; TIM_BDTRConfig(TIMx, &TIM_BDTRInitStructure); TIM_CtrlPWMOutputs(TIMx, ENABLE); } Analysis_GPIO_Pin(pin, &pin_state); for (i = 0; i < 16; i++){ if (pin_state.user_pin[i] == 1){ GPIO_PinAFConfig(GPIOx, Pin_select_source(pin_state.pin_address[i]), Tim_select_af(TIMx));//AF設定 } } //ミニMDではしない方が良さげ TIMx->CCR1=0;TIMx->CCR2=0;TIMx->CCR3=0;TIMx->CCR4=0; //一応duty全部0%にしておく TIM_ARRPreloadConfig(TIMx,ENABLE);//プリロード設定の適用 TIM_Cmd(TIMx,ENABLE);//タイマー有効化 return 0; }
void Motor_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; GPIO_StructInit(&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOC, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOB, &GPIO_InitStructure); //GPIO_WriteBit(GPIOB, GPIO_Pin_14, (BitAction)(0)); GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_TIM8); GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_TIM8); GPIO_PinAFConfig(GPIOC, GPIO_PinSource8, GPIO_AF_TIM8); GPIO_PinAFConfig(GPIOC, GPIO_PinSource9, GPIO_AF_TIM8); TIM_TimeBaseStructure.TIM_Prescaler = 2 - 1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = 10000; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure); TIM_OCStructInit(&TIM_OCInitStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_Pulse = 2500; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; /*TIM_OC1Init(TIM8, &TIM_OCInitStructure); TIM_OC2Init(TIM8, &TIM_OCInitStructure); TIM_OC3Init(TIM8, &TIM_OCInitStructure); TIM_OC4Init(TIM8, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM8, TIM_OCPreload_Enable); TIM_OC2PreloadConfig(TIM8, TIM_OCPreload_Enable); TIM_OC3PreloadConfig(TIM8, TIM_OCPreload_Enable); TIM_OC4PreloadConfig(TIM8, TIM_OCPreload_Enable);*/ TIM_OC1Init(TIM8, &TIM_OCInitStructure); TIM_OC2Init(TIM8, &TIM_OCInitStructure); TIM_OC3Init(TIM8, &TIM_OCInitStructure); TIM_OC4Init(TIM8, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM8, TIM_OCPreload_Enable); TIM_OC2PreloadConfig(TIM8, TIM_OCPreload_Enable); TIM_OC3PreloadConfig(TIM8, TIM_OCPreload_Enable); TIM_OC4PreloadConfig(TIM8, TIM_OCPreload_Enable); //TIM_ARRPreloadConfig(TIM8, ENABLE); TIM_Cmd(TIM8, ENABLE); /* TIM1 Main Output Enable */ TIM_CtrlPWMOutputs(TIM8, ENABLE); }
void pwmInit(void) { // config structs GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; /* TIM3 clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); /* GPIOC clock enable */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); /* GPIOC Configuration: TIM3 CH1 (PC6), TIM3 CH2 (PC7), TIM3 CH3 (PC8) and TIM3 CH4 (PC9) */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ; GPIO_Init(GPIOC, &GPIO_InitStructure); /* Connect TIM3 pins to AF2 */ GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_TIM3); GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_TIM3); GPIO_PinAFConfig(GPIOC, GPIO_PinSource8, GPIO_AF_TIM3); GPIO_PinAFConfig(GPIOC, GPIO_PinSource9, GPIO_AF_TIM3); // prescale the TIM clock by 84 for a Timer_Freq of 1MHz uint16_t PrescalerValue = (uint16_t) 84; /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 1999; //standard 20ms period for servos TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); /* PWM1 Mode configuration: Channel1 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; //inital duty cycle TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM3, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); /* PWM1 Mode configuration: Channel2 */ TIM_OC2Init(TIM3, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); /* PWM1 Mode configuration: Channel3 */ TIM_OC3Init(TIM3, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable); /* PWM1 Mode configuration: Channel4 */ TIM_OC4Init(TIM3, &TIM_OCInitStructure); TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM3, ENABLE); /* TIM3 enable counter */ TIM_Cmd(TIM3, ENABLE); }
void RmBatholicTIM8_Config(){ TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; /* Compute the prescaler value */ uint16_t PrescalerValue = (uint16_t) (SystemCoreClock / 160000000) - 1; GPIO_InitTypeDef GPIO_InitStructure; /* TIM4 clock enable */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE); /* GPIOD clock enable */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ; GPIO_Init(GPIOC, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_ResetBits(GPIOB,GPIO_Pin_0); GPIO_ResetBits(GPIOB,GPIO_Pin_1); GPIO_PinAFConfig(GPIOC, GPIO_PinSource8, GPIO_AF_TIM8); GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_TIM8); RCC_TIMCLKPresConfig(RCC_TIMPrescActivated); TIM_DeInit(TIM8); /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 9999; TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState=TIM_OutputNState_Disable; TIM_OCInitStructure.TIM_Pulse = 0; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OCNPolarity=TIM_OCPolarity_Low; TIM_OCInitStructure.TIM_OCIdleState=TIM_OCIdleState_Reset; TIM_OCInitStructure.TIM_OCNIdleState=TIM_OCNIdleState_Set; TIM_OC2Init(TIM8, &TIM_OCInitStructure); TIM_OC3Init(TIM8, &TIM_OCInitStructure); TIM_ARRPreloadConfig(TIM8, ENABLE); TIM_OC2PreloadConfig(TIM8, TIM_OCPreload_Enable); TIM_OC3PreloadConfig(TIM8, TIM_OCPreload_Enable); }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32l1xx_xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32l1xx.c file */ /* --------------------------- System Clocks Configuration ---------------------*/ /* PCLK1 = HCLK/4 */ RCC_PCLK1Config(RCC_HCLK_Div4); /* TIM3 clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); /* GPIOA and GPIOB clock enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA|RCC_AHBPeriph_GPIOB, ENABLE); /*--------------------------------- GPIO Configuration -------------------------*/ /* GPIOA Configuration: Pin 6 and 7 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_TIM3); GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_TIM3); /* GPIOB Configuration: Pin 0 and 1 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOB, GPIO_PinSource0, GPIO_AF_TIM3); GPIO_PinAFConfig(GPIOB, GPIO_PinSource1, GPIO_AF_TIM3); /*--------------------------------- NVIC Configuration -------------------------*/ /* Enable the TIM3 global Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* --------------------------------------------------------------------------- TIM3 Configuration: Output Compare Toggle Mode: TIM3CLK = SystemCoreClock / 2, The objective is to get TIM3 counter clock at 16 MHz: - Prescaler = (TIM3CLK / TIM3 counter clock) - 1 CC1 update rate = TIM3 counter clock / CCR1_Val = 488.281 Hz CC2 update rate = TIM3 counter clock / CCR2_Val = 976.562 Hz CC3 update rate = TIM3 counter clock / CCR3_Val = 1953.125 Hz CC4 update rate = TIM3 counter clock / CCR4_Val = 3906.25 Hz ----------------------------------------------------------------------------*/ /* Compute the prescaler value */ PrescalerValue = (uint16_t) (SystemCoreClock / 32000000) - 1; /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 65535; TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); /* Output Compare Toggle Mode configuration: Channel1 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR1_Val; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OC1Init(TIM3, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Disable); /* Output Compare Toggle Mode configuration: Channel2 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR2_Val; TIM_OC2Init(TIM3, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Disable); /* Output Compare Toggle Mode configuration: Channel3 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR3_Val; TIM_OC3Init(TIM3, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Disable); /* Output Compare Toggle Mode configuration: Channel4 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR4_Val; TIM_OC4Init(TIM3, &TIM_OCInitStructure); TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Disable); /* TIM enable counter */ TIM_Cmd(TIM3, ENABLE); /* TIM IT enable */ TIM_ITConfig(TIM3, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, ENABLE); while (1) {} }
void ws2811_init(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; GPIO_InitTypeDef GPIO_InitStructure; DMA_InitTypeDef DMA_InitStructure; // Default LED values int i, bit; for (i = 0;i < LED_BUFFER_LEN;i++) { RGBdata[i] = 0; } for (i = 0;i < LED_BUFFER_LEN;i++) { uint32_t tmp_color = rgb_to_local(RGBdata[i]); for (bit = 0;bit < 24;bit++) { if(tmp_color & (1 << 23)) { bitbuffer[bit + i * 24] = WS2811_ONE; } else { bitbuffer[bit + i * 24] = WS2811_ZERO; } tmp_color <<= 1; } } // Fill the rest of the buffer with zeros to give the LEDs a chance to update // after sending all bits for (i = 0;i < BITBUFFER_PAD;i++) { bitbuffer[BITBUFFER_LEN - BITBUFFER_PAD - 1 + i] = 0; } // GPIOB clock enable RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); // GPIOB Configuration: Channel 3 as alternate function push-pull GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 ; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_TIM4); // DMA clock enable RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1 , ENABLE); DMA_DeInit(DMA1_Stream7); DMA_InitStructure.DMA_Channel = DMA_Channel_2; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&TIM4->CCR3; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)bitbuffer; DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; DMA_InitStructure.DMA_BufferSize = BITBUFFER_LEN; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA1_Stream7, &DMA_InitStructure); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); // Time Base configuration TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = TIM_PERIOD; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); // Channel 3 Configuration in PWM mode TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = bitbuffer[0]; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC3Init(TIM4, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable); // TIM4 counter enable TIM_Cmd(TIM4, ENABLE); // DMA enable DMA_Cmd(DMA1_Stream7, ENABLE); // TIM4 Update DMA Request enable TIM_DMACmd(TIM4, TIM_DMA_CC3, ENABLE); // Main Output Enable TIM_CtrlPWMOutputs(TIM4, ENABLE); }
//arr:自动重装值 //psc:时钟预分频数 void PWM_Init(u16 arr,u16 psc) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;//初始化TIMx的时间基数 TIM_OCInitTypeDef TIM_OCInitStructure;//初始化外设TIMx TIM_BDTRInitTypeDef TIM_BDTRInitStructure;//死区设置 /*************1、引脚io设置*************************/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC, ENABLE);//使能GPIO外设时钟使能 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);//使能复用功能 //设置该引脚为复用输出功能 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_8; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //端口频率可设为2,10,50 GPIO_Init(GPIOA, &GPIO_InitStructure);//启动A端口 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_13; GPIO_Init(GPIOB, &GPIO_InitStructure);//启动B端口 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8; GPIO_Init(GPIOC, &GPIO_InitStructure);//启动C端口 /*****************2、通道设置*****************/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1|RCC_APB2Periph_TIM8, ENABLE);//使能外设时钟TIMx,TIM8 TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值80K TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 不分频 TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式 TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位 TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure); TIM_ARRPreloadConfig(TIM1, ENABLE); //使能TIMx在ARR上的预装载寄存器 TIM_ARRPreloadConfig(TIM8, ENABLE); //使能TIMx在ARR上的预装载寄存器 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //TIM脉冲宽度调制模式1:小于设定值则为高;2反之 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能 TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; //选择互补输出比较状态 TIM_OCInitStructure.TIM_Pulse = 0; //设置待装入捕获比较寄存器的脉冲值 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高 TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCPolarity_High; //TIM互补输出极性为高 TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; //选择空闲状态 TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; //重置互补输出的输出比较状态 TIM_OC1Init(TIM1, &TIM_OCInitStructure); //TIMx通道1设置 TIM_OC1Init(TIM8, &TIM_OCInitStructure); TIM_OC2Init(TIM8, &TIM_OCInitStructure); TIM_OC3Init(TIM8, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); //预装载使能,为了让控制更精准,更改不是立马改变,在本次波形执行完之后 TIM_OC1PreloadConfig(TIM8, TIM_OCPreload_Enable); //不用也可以 TIM_OC2PreloadConfig(TIM8, TIM_OCPreload_Enable); // TIM_OC3PreloadConfig(TIM8, TIM_OCPreload_Enable); // //死区设置 TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;//设置在运行模式下非工作状态选项 TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;//设置空闲状态下的非工作状态 TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF;//设置锁电平参数,不锁定任何位 TIM_BDTRInitStructure.TIM_DeadTime = 100;//死区时间,0-0xff,设置了输出打开和关闭之间的延时 TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;//刹车功能使能 TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;//自动输出使能 TIM_BDTRConfig(TIM1,&TIM_BDTRInitStructure); // TIM_BDTRConfig(TIM8,&TIM_BDTRInitStructure); // TIM_Cmd(TIM1, ENABLE); //使能TIMx TIM_CtrlPWMOutputs(TIM1,ENABLE); //MOE 主输出使能 TIM_Cmd(TIM8, ENABLE); //使能TIM8 TIM_CtrlPWMOutputs(TIM8,ENABLE); //MOE 主输出使能 pwm_set_off(TIM8, TIM_Channel_1); pwm_set_off(TIM8, TIM_Channel_2); pwm_set_off(TIM8, TIM_Channel_3); pwm_set_off(TIM1, TIM_Channel_1); }
/* * @brief Should take an integer 0-255 and create a PWM signal with a duty cycle from 0-100%. * TIM_PWM_FREQ is set at 500 Hz */ void analogWrite(uint16_t pin, uint8_t value) { if (pin >= TOTAL_PINS || PIN_MAP[pin].timer_peripheral == NULL) { return; } // SPI safety check if (SPI.isEnabled() == true && (pin == SCK || pin == MOSI || pin == MISO)) { return; } // I2C safety check if (Wire.isEnabled() == true && (pin == SCL || pin == SDA)) { return; } // Serial1 safety check if (Serial1.isEnabled() == true && (pin == RX || pin == TX)) { return; } if(PIN_MAP[pin].pin_mode != OUTPUT && PIN_MAP[pin].pin_mode != AF_OUTPUT_PUSHPULL) { return; } TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; //PWM Frequency : 500 Hz uint16_t TIM_Prescaler = (uint16_t)(SystemCoreClock / 24000000) - 1;//TIM Counter clock = 24MHz uint16_t TIM_ARR = (uint16_t)(24000000 / TIM_PWM_FREQ) - 1; // TIM Channel Duty Cycle(%) = (TIM_CCR / TIM_ARR + 1) * 100 uint16_t TIM_CCR = (uint16_t)(value * (TIM_ARR + 1) / 255); // AFIO clock enable RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); pinMode(pin, AF_OUTPUT_PUSHPULL); // TIM clock enable if(PIN_MAP[pin].timer_peripheral == TIM2) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); else if(PIN_MAP[pin].timer_peripheral == TIM3) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); else if(PIN_MAP[pin].timer_peripheral == TIM4) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); // Time base configuration TIM_TimeBaseStructure.TIM_Period = TIM_ARR; TIM_TimeBaseStructure.TIM_Prescaler = TIM_Prescaler; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(PIN_MAP[pin].timer_peripheral, &TIM_TimeBaseStructure); // PWM1 Mode configuration TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_Pulse = TIM_CCR; if(PIN_MAP[pin].timer_ch == TIM_Channel_1) { // PWM1 Mode configuration: Channel1 TIM_OC1Init(PIN_MAP[pin].timer_peripheral, &TIM_OCInitStructure); TIM_OC1PreloadConfig(PIN_MAP[pin].timer_peripheral, TIM_OCPreload_Enable); } else if(PIN_MAP[pin].timer_ch == TIM_Channel_2) { // PWM1 Mode configuration: Channel2 TIM_OC2Init(PIN_MAP[pin].timer_peripheral, &TIM_OCInitStructure); TIM_OC2PreloadConfig(PIN_MAP[pin].timer_peripheral, TIM_OCPreload_Enable); } else if(PIN_MAP[pin].timer_ch == TIM_Channel_3) { // PWM1 Mode configuration: Channel3 TIM_OC3Init(PIN_MAP[pin].timer_peripheral, &TIM_OCInitStructure); TIM_OC3PreloadConfig(PIN_MAP[pin].timer_peripheral, TIM_OCPreload_Enable); } else if(PIN_MAP[pin].timer_ch == TIM_Channel_4) { // PWM1 Mode configuration: Channel4 TIM_OC4Init(PIN_MAP[pin].timer_peripheral, &TIM_OCInitStructure); TIM_OC4PreloadConfig(PIN_MAP[pin].timer_peripheral, TIM_OCPreload_Enable); } TIM_ARRPreloadConfig(PIN_MAP[pin].timer_peripheral, ENABLE); // TIM enable counter TIM_Cmd(PIN_MAP[pin].timer_peripheral, ENABLE); }
// ---------------------------------------------------------------------------- void HwInit( void ) { SystemCoreClockUpdate( ); // Make sure SysTick is running at a 1ms rate. if ( SysTick_Config( SystemCoreClock / 1000 ) ) { /* Capture error */ while ( 1 ); } // SysTick_CLKSourceConfig( SysTick_CLKSource_HCLK_Div8 ); /* Initialize Leds mounted on STM32F4-Discovery board */ STM_EVAL_LEDInit(LED4); STM_EVAL_LEDInit(LED3); STM_EVAL_LEDInit(LED5); STM_EVAL_LEDInit(LED6); /* Turn on LED4 and LED5 */ STM_EVAL_LEDOn(LED4); STM_EVAL_LEDOn(LED5); /* TIM Configuration */ TIM3_Config(); TIM4_Config(); /* ----------------------------------------------------------------------- TIM3 Configuration: generate 4 PWM signals with 4 different duty cycles. In this example TIM3 input clock (TIM3CLK) is set to 2 * APB1 clock (PCLK1), since APB1 prescaler is different from 1. TIM3CLK = 2 * PCLK1 PCLK1 = HCLK / 4 => TIM3CLK = HCLK / 2 = SystemCoreClock /2 To get TIM3 counter clock at 28 MHz, the prescaler is computed as follows: Prescaler = (TIM3CLK / TIM3 counter clock) - 1 Prescaler = ((SystemCoreClock /2) /28 MHz) - 1 To get TIM3 output clock at 30 KHz, the period (ARR)) is computed as follows: ARR = (TIM3 counter clock / TIM3 output clock) - 1 = 665 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% Note: SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f4xx.c file. Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate() function to update SystemCoreClock variable value. Otherwise, any configuration based on this variable will be incorrect. ----------------------------------------------------------------------- */ /* Compute the prescaler value */ PrescalerValue = (uint16_t) ((SystemCoreClock /2) / 28000000) - 1; /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 665; TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit( TIM3, &TIM_TimeBaseStructure ); TIM_TimeBaseInit( TIM4, &TIM_TimeBaseStructure ); /* PWM1 Mode configuration: Channel1 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR1_Val; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init( TIM3, &TIM_OCInitStructure ); TIM_OC1Init( TIM4, &TIM_OCInitStructure ); TIM_OC1PreloadConfig( TIM3, TIM_OCPreload_Enable ); TIM_OC1PreloadConfig( TIM4, TIM_OCPreload_Enable ); /* PWM1 Mode configuration: Channel2 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR2_Val; TIM_OC2Init( TIM3, &TIM_OCInitStructure ); TIM_OC2Init( TIM4, &TIM_OCInitStructure ); TIM_OC2PreloadConfig( TIM3, TIM_OCPreload_Enable ); TIM_OC2PreloadConfig( TIM4, TIM_OCPreload_Enable ); /* PWM1 Mode configuration: Channel3 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR3_Val; TIM_OC3Init( TIM3, &TIM_OCInitStructure ); TIM_OC3Init( TIM4, &TIM_OCInitStructure ); TIM_OC3PreloadConfig( TIM3, TIM_OCPreload_Enable ); TIM_OC3PreloadConfig( TIM4, TIM_OCPreload_Enable ); /* PWM1 Mode configuration: Channel4 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR4_Val; TIM_OC4Init( TIM3, &TIM_OCInitStructure ); TIM_OC4Init( TIM4, &TIM_OCInitStructure ); TIM_OC4PreloadConfig( TIM3, TIM_OCPreload_Enable ); TIM_OC4PreloadConfig( TIM4, TIM_OCPreload_Enable ); TIM_ARRPreloadConfig( TIM3, ENABLE ); TIM_ARRPreloadConfig( TIM4, ENABLE ); /* TIM3 enable counter */ TIM_Cmd( TIM3, ENABLE ); TIM_Cmd( TIM4, ENABLE ); vUSART2_Init(); // Start up UART2 }
// User defined analogWrite() to gain control of PWM initialization void IRsend::analogWrite2(uint16_t pin, uint8_t value) { TIM_OCInitTypeDef TIM_OCInitStructure; if (pin >= TOTAL_PINS || PIN_MAP[pin].timer_peripheral == NULL) { return; } // SPI safety check if (SPI.isEnabled() == true && (pin == SCK || pin == MOSI || pin == MISO)) { return; } // I2C safety check if (Wire.isEnabled() == true && (pin == SCL || pin == SDA)) { return; } // Serial1 safety check if (Serial1.isEnabled() == true && (pin == RX || pin == TX)) { return; } if (PIN_MAP[pin].pin_mode != OUTPUT && PIN_MAP[pin].pin_mode != AF_OUTPUT_PUSHPULL) { return; } // Don't re-init PWM and cause a glitch if already setup, just update duty cycle and return. if (PIN_MAP[pin].pin_mode == AF_OUTPUT_PUSHPULL) { TIM_OCInitStructure.TIM_Pulse = (uint16_t)(value * (TIM_ARR + 1) / 255); if (PIN_MAP[pin].timer_ch == TIM_Channel_1) { PIN_MAP[pin].timer_peripheral-> CCR1 = TIM_OCInitStructure.TIM_Pulse; } else if (PIN_MAP[pin].timer_ch == TIM_Channel_2) { PIN_MAP[pin].timer_peripheral-> CCR2 = TIM_OCInitStructure.TIM_Pulse; } else if (PIN_MAP[pin].timer_ch == TIM_Channel_3) { PIN_MAP[pin].timer_peripheral-> CCR3 = TIM_OCInitStructure.TIM_Pulse; } else if (PIN_MAP[pin].timer_ch == TIM_Channel_4) { PIN_MAP[pin].timer_peripheral-> CCR4 = TIM_OCInitStructure.TIM_Pulse; } return; } TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //PWM Frequency : PWM_FREQ (Hz) uint16_t TIM_Prescaler = (uint16_t)(SystemCoreClock / 24000000) - 1; //TIM Counter clock = 24MHz // TIM Channel Duty Cycle(%) = (TIM_CCR / TIM_ARR + 1) * 100 uint16_t TIM_CCR = (uint16_t)(value * (TIM_ARR + 1) / 255); // AFIO clock enable RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //pinMode(pin, AF_OUTPUT_PUSHPULL); // we need to do this manually else we get a glitch // TIM clock enable if (PIN_MAP[pin].timer_peripheral == TIM2) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); else if (PIN_MAP[pin].timer_peripheral == TIM3) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); else if (PIN_MAP[pin].timer_peripheral == TIM4) RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); // Time base configuration TIM_TimeBaseStructure.TIM_Period = TIM_ARR; TIM_TimeBaseStructure.TIM_Prescaler = TIM_Prescaler; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(PIN_MAP[pin].timer_peripheral, & TIM_TimeBaseStructure); // PWM1 Mode configuration TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_Pulse = TIM_CCR; if (PIN_MAP[pin].timer_ch == TIM_Channel_1) { // PWM1 Mode configuration: Channel1 TIM_OC1Init(PIN_MAP[pin].timer_peripheral, & TIM_OCInitStructure); TIM_OC1PreloadConfig(PIN_MAP[pin].timer_peripheral, TIM_OCPreload_Enable); } else if (PIN_MAP[pin].timer_ch == TIM_Channel_2) { // PWM1 Mode configuration: Channel2 TIM_OC2Init(PIN_MAP[pin].timer_peripheral, & TIM_OCInitStructure); TIM_OC2PreloadConfig(PIN_MAP[pin].timer_peripheral, TIM_OCPreload_Enable); } else if (PIN_MAP[pin].timer_ch == TIM_Channel_3) { // PWM1 Mode configuration: Channel3 TIM_OC3Init(PIN_MAP[pin].timer_peripheral, & TIM_OCInitStructure); TIM_OC3PreloadConfig(PIN_MAP[pin].timer_peripheral, TIM_OCPreload_Enable); } else if (PIN_MAP[pin].timer_ch == TIM_Channel_4) { // PWM1 Mode configuration: Channel4 TIM_OC4Init(PIN_MAP[pin].timer_peripheral, & TIM_OCInitStructure); TIM_OC4PreloadConfig(PIN_MAP[pin].timer_peripheral, TIM_OCPreload_Enable); } TIM_ARRPreloadConfig(PIN_MAP[pin].timer_peripheral, ENABLE); // TIM enable counter TIM_Cmd(PIN_MAP[pin].timer_peripheral, ENABLE); }
/******************************************************************************* ** Function name: PWM_Init( PWM_typedef * PWM) ** Description : The function shall be initialize Independent PWM channel ** Parameter : None ** Return value : None ** Remarks : PWM_FAIL - Init unsuccessful ** PWM_OK - Init successful *******************************************************************************/ int PWM_Init( PWM_typedef * PWM ) { int Retval = PWM_FAIL; GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; uint16_t PrescalerValue = 0; if(PWM != NULL) { /* TIM3 clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); /* GPIOC clock enable */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); /* GPIOC Configuration: TIM3 CH1 (PC6), TIM3 CH2 (PC7), TIM3 CH3 (PC8) and TIM3 CH4 (PC9) */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ; GPIO_Init(GPIOC, &GPIO_InitStructure); /* Connect TIM3 pins to AF2 */ GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_TIM3); GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_TIM3); GPIO_PinAFConfig(GPIOC, GPIO_PinSource8, GPIO_AF_TIM3); GPIO_PinAFConfig(GPIOC, GPIO_PinSource9, GPIO_AF_TIM3); /* ----------------------------------------------------------------------- TIM3 Configuration: generate 4 PWM signals with 4 different duty cycles. In this example TIM3 input clock (TIM3CLK) is set to 2 * APB1 clock (PCLK1), since APB1 prescaler is different from 1. TIM3CLK = 2 * PCLK1 PCLK1 = HCLK / 4 => TIM3CLK = HCLK / 2 = SystemCoreClock /2 To get TIM3 counter clock at 21 MHz, the prescaler is computed as follows: Prescaler = (TIM3CLK / TIM3 counter clock) - 1 Prescaler = ((SystemCoreClock /2) /21 MHz) - 1 To get TIM3 output clock at 30 KHz, the period (ARR)) is computed as follows: ARR = (TIM3 counter clock / TIM3 output clock) - 1 = 665 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% Note: SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f4xx.c file. Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate() function to update SystemCoreClock variable value. Otherwise, any configuration based on this variable will be incorrect. ----------------------------------------------------------------------- */ /* Compute the prescaler value */ PrescalerValue = (uint16_t) ((SystemCoreClock /2) / 21000000) - 1; /* Time base configuration */ /* * PWM 20KHz = 1000 * PWM 10KHz = 2000 * PWM 7.5KHz = 3000 * PWM 5KHz = 4000 */ TIM_TimeBaseStructure.TIM_Period = 1000; /* PWM */ TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); /* PWM1 Mode configuration: Channel1 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM3, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); /* PWM1 Mode configuration: Channel2 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; TIM_OC2Init(TIM3, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); /* PWM1 Mode configuration: Channel3 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; TIM_OC3Init(TIM3, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable); /* PWM1 Mode configuration: Channel4 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; TIM_OC4Init(TIM3, &TIM_OCInitStructure); TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM3, ENABLE); Retval = PWM_OK; } else { /* do nothing */ } return Retval; }
/** * @brief Configure the TIM3 pins. * @param None * @retval None */ static void TIM_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; uint16_t CCR1_Val = 1000; uint16_t CCR2_Val = 500; uint16_t CCR3_Val = 250; uint16_t CCR4_Val = 125; uint16_t PrescalerValue = 0; /* TIM3 clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); /* GPIOA clock enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA |RCC_AHBPeriph_GPIOB, ENABLE); /* GPIOC Configuration: TIM3 CH1 (PA6), TIM3 CH2 (PA7), TIM3 CH3 (PB0) and TIM3 CH4 (PB1) */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 ; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 ; GPIO_Init(GPIOB, &GPIO_InitStructure); /* Connect TIM Channels to AF2 */ GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_2); GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_2); GPIO_PinAFConfig(GPIOB, GPIO_PinSource0, GPIO_AF_2); GPIO_PinAFConfig(GPIOB, GPIO_PinSource1, GPIO_AF_2); TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_OCStructInit(&TIM_OCInitStructure); /* --------------------------------------------------------------------------- TIM3 Configuration: Output Compare Active Mode: In this example TIM3 input clock (TIM3CLK) is set to 2 * APB1 clock (PCLK1) TIM3CLK = 2*PCLK1 PCLK1 = HCLK/2 => TIM3CLK = HCLK = SystemCoreClock To get TIM3 counter clock at 10 KHz, the prescaler is computed as follows: Prescaler = (TIM3CLK / TIM3 counter clock) - 1 Prescaler = (SystemCoreClock /10 KHz) - 1 Generate 4 signals with 4 different delays: TIM3_CH1 delay = CCR1_Val/TIM3 counter clock = 100 ms TIM3_CH2 delay = CCR2_Val/TIM3 counter clock = 50 ms TIM3_CH3 delay = CCR3_Val/TIM3 counter clock = 25 ms TIM3_CH4 delay = CCR4_Val/TIM3 counter clock = 12.5 ms Note: SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f30x.c file. Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate() function to update SystemCoreClock variable value. Otherwise, any configuration based on this variable will be incorrect. --------------------------------------------------------------------------- */ /* Compute the prescaler value */ PrescalerValue = (uint16_t) (SystemCoreClock / 10000) - 1; /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 65535; TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); /* Output Compare Active Mode configuration: Channel1 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Active; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR1_Val; TIM_OC1Init(TIM3, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Disable); TIM_ARRPreloadConfig(TIM3, DISABLE); /* Output Compare Active Mode configuration: Channel2 */ TIM_OCInitStructure.TIM_Pulse = CCR2_Val; TIM_OC2Init(TIM3, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Disable); /* Output Compare Active Mode configuration: Channel3 */ TIM_OCInitStructure.TIM_Pulse = CCR3_Val; TIM_OC3Init(TIM3, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Disable); /* Output Compare Active Mode configuration: Channel4 */ TIM_OCInitStructure.TIM_Pulse = CCR4_Val; TIM_OC4Init(TIM3, &TIM_OCInitStructure); TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Disable); /* TIM3 enable counter */ TIM_Cmd(TIM3, ENABLE); TIM_GenerateEvent(TIM3, TIM_EventSource_Update); }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f4xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f4xx.c file */ /* TIM Configuration */ TIM_Config(); /* ----------------------------------------------------------------------- TIM3 Configuration: generate 4 PWM signals with 4 different duty cycles. In this example TIM3 input clock (TIM3CLK) is set to 2 * APB1 clock (PCLK1), since APB1 prescaler is different from 1. TIM3CLK = 2 * PCLK1 PCLK1 = HCLK / 4 => TIM3CLK = HCLK / 2 = SystemCoreClock /2 To get TIM3 counter clock at 28 MHz, the prescaler is computed as follows: Prescaler = (TIM3CLK / TIM3 counter clock) - 1 Prescaler = ((SystemCoreClock /2) /28 MHz) - 1 To get TIM3 output clock at 30 KHz, the period (ARR)) is computed as follows: ARR = (TIM3 counter clock / TIM3 output clock) - 1 = 665 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% Note: SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f4xx.c file. Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate() function to update SystemCoreClock variable value. Otherwise, any configuration based on this variable will be incorrect. ----------------------------------------------------------------------- */ /* Compute the prescaler value */ PrescalerValue = (uint16_t) ((SystemCoreClock /2) / 1000000) - 1;//generate 1Mz frequency /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 20000-1;//down to 50hz TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;//84-1 TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); /* PWM1 Mode configuration: Channel1 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR1_Val;//1000-1 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM3, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); /* PWM1 Mode configuration: Channel2 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR2_Val; TIM_OC2Init(TIM3, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); /* PWM1 Mode configuration: Channel3 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR3_Val; TIM_OC3Init(TIM3, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable); /* PWM1 Mode configuration: Channel4 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR4_Val; TIM_OC4Init(TIM3, &TIM_OCInitStructure); TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM3, ENABLE); /* TIM3 enable counter */ TIM_Cmd(TIM3, ENABLE); }
/*! @brief Thread to implement alarm @param argument Unused */ void Alarm_LED_thread(void const * argument) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; /* TIM config */ GPIO_InitTypeDef GPIO_InitStructure; /* TIM4 clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); /* LEDs are on GPIOD */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ; GPIO_Init(GPIOD, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_TIM4); /* Compute the prescaler value */ int PresVal = (uint16_t) ((SystemCoreClock /2) / 21000000) - 1; /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 700; TIM_TimeBaseStructure.TIM_Prescaler = PresVal; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); /* PWM1 Mode configuration: Channel3 TIM4 CH3 for GPIOD PD14*/ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC3Init(TIM4, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM4, ENABLE); /* TIM4 enable counter */ TIM_Cmd(TIM4, ENABLE); int intensity = 0; osEvent event; while(1) // Do not exit { event=osSignalWait(SIGNAL_ALARM_ON_OFF, osWaitForever); intensity++; TIM4->CCR3 = 400 - (intensity + 0) % 400; // set brightness Delay(40000); } return; }
void bsp_pwm_config(void) { TIM_TimeBaseInitTypeDef TIM_config; GPIO_InitTypeDef GPIO_config; TIM_OCInitTypeDef TIM_OC_config; /* Habilito el clock */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); /* Configuro leds como Segunda Funcion */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); GPIO_config.GPIO_Mode = GPIO_Mode_AF; GPIO_config.GPIO_Pin = GPIO_Pin_15 | GPIO_Pin_14 | GPIO_Pin_13 | GPIO_Pin_12; GPIO_config.GPIO_Speed = GPIO_Speed_50MHz; GPIO_config.GPIO_PuPd = GPIO_PuPd_UP; GPIO_config.GPIO_OType = GPIO_OType_PP; GPIO_Init(GPIOD, &GPIO_config); GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_TIM4); GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_TIM4); GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_TIM4); GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_TIM4); TIM_config.TIM_CounterMode = TIM_CounterMode_Up; TIM_config.TIM_ClockDivision = 0; TIM_config.TIM_Period = 10000; TIM_config.TIM_Prescaler = 16 - 1; TIM_TimeBaseInit(TIM4, &TIM_config); TIM_OC_config.TIM_OCMode = TIM_OCMode_PWM1; TIM_OC_config.TIM_OutputState = TIM_OutputState_Enable; TIM_OC_config.TIM_Pulse = 0; TIM_OC_config.TIM_OCPolarity = TIM_OCPolarity_High; // CH1 del pwm TIM_OC1Init(TIM4, &TIM_OC_config); TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable); //CH2 del pwm TIM_OC_config.TIM_OutputState = TIM_OutputState_Enable; TIM_OC_config.TIM_Pulse = 0; TIM_OC2Init(TIM4, &TIM_OC_config); TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable); //CH3 del pwm TIM_OC_config.TIM_OutputState = TIM_OutputState_Enable; TIM_OC_config.TIM_Pulse = 0; TIM_OC3Init(TIM4, &TIM_OC_config); TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable); //CH4 del pwm TIM_OC_config.TIM_OutputState = TIM_OutputState_Enable; TIM_OC_config.TIM_Pulse = 0; TIM_OC4Init(TIM4, &TIM_OC_config); TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM4, ENABLE); TIM_Cmd(TIM4, ENABLE); }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f10x_xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f10x.c file */ /* System Clocks Configuration */ RCC_Configuration(); /* NVIC Configuration */ NVIC_Configuration(); /* GPIO Configuration */ GPIO_Configuration(); /* --------------------------------------------------------------- TIM2 Configuration: Output Compare Timing Mode: TIM2 counter clock at 6 MHz CC1 update rate = TIM2 counter clock / CCR1_Val = 146.48 Hz CC2 update rate = TIM2 counter clock / CCR2_Val = 219.7 Hz CC3 update rate = TIM2 counter clock / CCR3_Val = 439.4 Hz CC4 update rate = TIM2 counter clock / CCR4_Val = 878.9 Hz --------------------------------------------------------------- */ /* Compute the prescaler value */ PrescalerValue = (uint16_t) (SystemCoreClock / 12000000) - 1; /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 65535; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); /* Prescaler configuration */ TIM_PrescalerConfig(TIM2, PrescalerValue, TIM_PSCReloadMode_Immediate); /* Output Compare Timing Mode configuration: Channel1 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR1_Val; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM2, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Disable); /* Output Compare Timing Mode configuration: Channel2 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR2_Val; TIM_OC2Init(TIM2, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Disable); /* Output Compare Timing Mode configuration: Channel3 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR3_Val; TIM_OC3Init(TIM2, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Disable); /* Output Compare Timing Mode configuration: Channel4 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR4_Val; TIM_OC4Init(TIM2, &TIM_OCInitStructure); TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Disable); /* TIM IT enable */ TIM_ITConfig(TIM2, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, ENABLE); /* TIM2 enable counter */ TIM_Cmd(TIM2, ENABLE); while (1); }
/*=====================================================================================================*/ void LED_Config( void ) { GPIO_InitTypeDef GPIO_InitStruct; TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct; TIM_OCInitTypeDef TIM_OCInitStruct; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4 | RCC_APB1Periph_TIM5, ENABLE); GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_TIM5); GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_TIM5); GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_TIM4); GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_TIM4); /* LED3 PA4 */ /* LED1 PA8 */ GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_8; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOA, &GPIO_InitStruct); /* LED4 PB5 */ GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOB, &GPIO_InitStruct); /* LED2 PD2 */ GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOD, &GPIO_InitStruct); /* LED6 PA2 */ /* LED8 PA3 */ GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN; GPIO_Init(GPIOA, &GPIO_InitStruct); /* LED7 PB8 */ /* LED5 PB9 */ GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOB, &GPIO_InitStruct); TIM_DeInit(TIM4); TIM_DeInit(TIM5); /************************** PWM Output **************************************/ /* 設定 TIM4 TIM5 Time Base */ TIM_TimeBaseStruct.TIM_Period = (2000-1); // 週期 = 20ms TIM_TimeBaseStruct.TIM_Prescaler = (840-1); // 除頻8400 = 100kHz ( 10us ) TIM_TimeBaseStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up; // 上數 TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStruct); TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStruct); /* 設定 TIM4 TIM5 OC */ TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; // 配置為 PWM1 模式 TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable; // 致能 OC TIM_OCInitStruct.TIM_Pulse = 2000; // 設置跳變值 TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; // 當計數值小於 MOTOR_PWM_Min 時為高電平 TIM_OC3Init(TIM4, &TIM_OCInitStruct); // 初始化 TIM4 OC3 TIM_OC4Init(TIM4, &TIM_OCInitStruct); // 初始化 TIM4 OC4 TIM_OC3Init(TIM5, &TIM_OCInitStruct); // 初始化 TIM5 OC3 TIM_OC4Init(TIM5, &TIM_OCInitStruct); // 初始化 TIM5 OC4 TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable); // 致能 TIM4 OC3 預裝載 TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable); // 致能 TIM4 OC4 預裝載 TIM_OC3PreloadConfig(TIM5, TIM_OCPreload_Enable); // 致能 TIM5 OC3 預裝載 TIM_OC4PreloadConfig(TIM5, TIM_OCPreload_Enable); // 致能 TIM5 OC4 預裝載 /* 啟動 TIM4 TIM5 */ TIM_ARRPreloadConfig(TIM4, ENABLE); // 致能 TIM4 重載寄存器ARR TIM_ARRPreloadConfig(TIM5, ENABLE); // 致能 TIM5 重載寄存器ARR TIM_Cmd(TIM4, ENABLE); // 致能 TIM4 TIM_Cmd(TIM5, ENABLE); // 致能 TIM5 }
static void TIM_Config(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; NVIC_InitTypeDef NVIC_InitStructure; /* TIM3 clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); /* Enable the TIM3 gloabal Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* ----------------------------------------------------------------------- TIM3 Configuration: Output Compare Timing Mode: In this example TIM3 input clock (TIM3CLK) is set to APB1 clock (PCLK1), => TIM3CLK = PCLK1 = SystemCoreClock = 48 MHz To get TIM3 counter clock at 6 MHz, the prescaler is computed as follows: Prescaler = (TIM3CLK / TIM3 counter clock) - 1 Prescaler = (PCLK1 /6 MHz) - 1 CC3 update rate = TIM3 counter clock / CCR3_Val = 439.4 Hz ==> Toggling frequency = 219.7 Hz CC4 update rate = TIM3 counter clock / CCR4_Val = 878.9 Hz ==> Toggling frequency = 439.4 Hz Note: SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f2xx.c file. Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate() function to update SystemCoreClock variable value. Otherwise, any configuration based on this variable will be incorrect. ----------------------------------------------------------------------- */ /* Compute the prescaler value */ PrescalerValue = (uint16_t) (SystemCoreClock / 6000000) - 1; /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 65535; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); /* Prescaler configuration */ TIM_PrescalerConfig(TIM3, PrescalerValue, TIM_PSCReloadMode_Immediate); /* Output Compare Timing Mode configuration: Channel1 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; /* Output Compare Timing Mode configuration: Channel3 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR3_Val; TIM_OC3Init(TIM3, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Disable); /* Output Compare Timing Mode configuration: Channel4 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR4_Val; TIM_OC4Init(TIM3, &TIM_OCInitStructure); TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Disable); /* TIM Interrupts enable */ TIM_ITConfig(TIM3, TIM_IT_CC3 | TIM_IT_CC4, ENABLE); /* TIM3 enable counter */ TIM_Cmd(TIM3, ENABLE); }
/** * @brief Main program * @param None * @retval : None */ int main(void) { /* System Clocks Configuration */ RCC_Configuration(); /* NVIC Configuration */ NVIC_Configuration(); /* GPIO Configuration */ GPIO_Configuration(); /* --------------------------------------------------------------- TIM2 Configuration: Output Compare Timing Mode: TIM2CLK = 36 MHz, Prescaler = 4, TIM2 counter clock = 7.2 MHz CC1 update rate = TIM2 counter clock / CCR1_Val = 146.48 Hz CC2 update rate = TIM2 counter clock / CCR2_Val = 219.7 Hz CC3 update rate = TIM2 counter clock / CCR3_Val = 439.4 Hz CC4 update rate = TIM2 counter clock / CCR4_Val = 878.9 Hz --------------------------------------------------------------- */ /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 65535; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); /* Prescaler configuration */ TIM_PrescalerConfig(TIM2, 4, TIM_PSCReloadMode_Immediate); /* Output Compare Timing Mode configuration: Channel1 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR1_Val; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM2, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Disable); /* Output Compare Timing Mode configuration: Channel2 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR2_Val; TIM_OC2Init(TIM2, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Disable); /* Output Compare Timing Mode configuration: Channel3 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR3_Val; TIM_OC3Init(TIM2, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Disable); /* Output Compare Timing Mode configuration: Channel4 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR4_Val; TIM_OC4Init(TIM2, &TIM_OCInitStructure); TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Disable); /* TIM IT enable */ TIM_ITConfig(TIM2, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, ENABLE); /* TIM2 enable counter */ TIM_Cmd(TIM2, ENABLE); while (1); }
void init_motorPWM(void){ GPIO_InitTypeDef GPIO_InitStructure; /* Enable TIM4 clock */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); /* Enable GPIOD clock */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); /* Enable PWM pins for the motors */ GPIO_InitStructure.GPIO_Pin = MOTOR_LEFT_PWM_PIN | MOTOR_RIGHT_PWM_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(MOTOR_PWM_PORT, &GPIO_InitStructure); /*Connect TIM4 pins to AF*/ GPIO_PinAFConfig(MOTOR_PWM_PORT, GPIO_PinSource14, GPIO_AF_TIM4); GPIO_PinAFConfig(MOTOR_PWM_PORT, GPIO_PinSource15, GPIO_AF_TIM4); /* ----------------------------------------------------------------------- TIM4 Configuration: generate 4 PWM signals with 4 different duty cycles. In this example TIM4 input clock (TIM4CLK) is set to 2 * APB1 clock (PCLK1), since APB1 prescaler is different from 1. TIM4CLK = 2 * PCLK1 PCLK1 = HCLK / 4 => TIM4CLK = HCLK / 2 = SystemCoreClock /2 To get TIM4 counter clock at 12 MHz, the prescaler is computed as follows: Prescaler = (TIM4CLK / TIM4 counter clock) - 1 Prescaler = ((SystemCoreClock /2) /12 MHz) - 1 = 7 - 1 To get TIM4 output clock at 10 KHz, the period (ARR)) is computed as follows: ARR = (TIM4 counter clock / TIM4 output clock) - 1 = 1200 If TIM4_CCR1 = 600, TIM4_CCR2 = 450, TIM4_CCR3 = 300, TIM4_CCR4 = 150 then TIM4 Channel1 duty cycle = (TIM4_CCR1/ TIM4_ARR)* 100 = 50% TIM4 Channel2 duty cycle = (TIM4_CCR2/ TIM4_ARR)* 100 = 37.5% TIM4 Channel3 duty cycle = (TIM4_CCR3/ TIM4_ARR)* 100 = 25% TIM4 Channel4 duty cycle = (TIM4_CCR4/ TIM4_ARR)* 100 = 12.5% Note: SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f4xx.c file. Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate() function to update SystemCoreClock variable value. Otherwise, any configuration based on this variable will be incorrect. ----------------------------------------------------------------------- */ /* this case : 10kHz * 84MHz/10kHz = 8400 * you can adjust the value of the two: * Prescaler = 7 - 1 * Period = 1200 - 1 */ /* Time base configuration*/ TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseStructure.TIM_Period = TimPeriod - 1; TIM_TimeBaseStructure.TIM_Prescaler = TimPrescaler - 1; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); /* PWM setting */ TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; /* initial value */ TIM_OCInitStructure.TIM_Pulse = SpeedValue;//in this case(duty cycle:50%) //PWM1 Mode Configuration: TIM4 Channel3 (MOTOR_LEFT_PWM_PIN) TIM_OC3Init(TIM4, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable); //PWM1 Mode Configuration: TIM4 Channel4 (MOTOR_RIGHT_PWM_PIN) TIM_OC4Init(TIM4, &TIM_OCInitStructure); TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable); TIM_Cmd(TIM4, ENABLE); }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f4xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f4xx.c file */ /* TIM Configuration */ TIM_Config(); /* ----------------------------------------------------------------------- TIM3 Configuration: Output Compare Timing Mode: In this example TIM3 input clock (TIM3CLK) is set to 2 * APB1 clock (PCLK1), since APB1 prescaler is different from 1. TIM3CLK = 2 * PCLK1 PCLK1 = HCLK / 4 => TIM3CLK = HCLK / 2 = SystemCoreClock /2 To get TIM3 counter clock at 50 MHz, the prescaler is computed as follows: Prescaler = (TIM3CLK / TIM3 counter clock) - 1 Prescaler = ((SystemCoreClock /2) /50 MHz) - 1 CC1 update rate = TIM3 counter clock / CCR1_Val = 9.154 Hz ==> Toggling frequency = 4.57 Hz C2 update rate = TIM3 counter clock / CCR2_Val = 18.31 Hz ==> Toggling frequency = 9.15 Hz CC3 update rate = TIM3 counter clock / CCR3_Val = 36.62 Hz ==> Toggling frequency = 18.31 Hz CC4 update rate = TIM3 counter clock / CCR4_Val = 73.25 Hz ==> Toggling frequency = 36.62 Hz Note: SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f4xx.c file. Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate() function to update SystemCoreClock variable value. Otherwise, any configuration based on this variable will be incorrect. ----------------------------------------------------------------------- */ /* Compute the prescaler value */ PrescalerValue = (uint16_t) ((SystemCoreClock / 2) / 500000) - 1; /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 65535; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); /* Prescaler configuration */ TIM_PrescalerConfig(TIM3, PrescalerValue, TIM_PSCReloadMode_Immediate); /* Output Compare Timing Mode configuration: Channel1 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR1_Val; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM3, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Disable); /* Output Compare Timing Mode configuration: Channel2 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR2_Val; TIM_OC2Init(TIM3, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Disable); /* Output Compare Timing Mode configuration: Channel3 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR3_Val; TIM_OC3Init(TIM3, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Disable); /* Output Compare Timing Mode configuration: Channel4 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = CCR4_Val; TIM_OC4Init(TIM3, &TIM_OCInitStructure); TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Disable); /* TIM Interrupts enable */ TIM_ITConfig(TIM3, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, ENABLE); /* TIM3 enable counter */ TIM_Cmd(TIM3, ENABLE); while (1); }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup files (startup_stm32f40_41xxx.s/startup_stm32f427_437xx.s/startup_stm32f429_439xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f4xx.c file */ /* TIM Configuration */ TIM_Config(); /* --------------------------------------------------------------- TIM2 Configuration: Output Compare Inactive Mode: In this example TIM2 input clock (TIM2CLK) is set to 2 * APB1 clock (PCLK1), since APB1 prescaler is different from 1. TIM2CLK = 2 * PCLK1 PCLK1 = HCLK / 4 => TIM2CLK = HCLK / 2 = SystemCoreClock /2 To get TIM2 counter clock at 2 KHz, the prescaler is computed as follows: Prescaler = (TIM2CLK / TIM2 counter clock) - 1 Prescaler = ((SystemCoreClock /2) /2 KHz) - 1 Generate 4 signals with 4 different delays: TIM2_CH1 delay = uhCCR1_Val/TIM2 counter clock = 500 ms TIM2_CH2 delay = uhCCR2_Val/TIM2 counter clock = 250 ms TIM2_CH3 delay = uhCCR3_Val/TIM2 counter clock = 125 ms TIM2_CH4 delay = uhCCR4_Val/TIM2 counter clock = 62.5 ms Note: SystemCoreClock variable holds HCLK frequency and is defined in system_stm32f4xx.c file. Each time the core clock (HCLK) changes, user had to call SystemCoreClockUpdate() function to update SystemCoreClock variable value. Otherwise, any configuration based on this variable will be incorrect. --------------------------------------------------------------- */ /* Compute the prescaler value */ uhPrescalerValue = (uint16_t) ((SystemCoreClock / 2) / 2000) - 1; /* Time base configuration */ TIM_TimeBaseStructure.TIM_Period = 65535; TIM_TimeBaseStructure.TIM_Prescaler = uhPrescalerValue; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); /* Output Compare Active Mode configuration: Channel1 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Inactive; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = uhCCR1_Val; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM2, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Disable); /* Output Compare Active Mode configuration: Channel2 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = uhCCR2_Val; TIM_OC2Init(TIM2, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Disable); /* Output Compare Active Mode configuration: Channel3 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = uhCCR3_Val; TIM_OC3Init(TIM2, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Disable); /* Output Compare Active Mode configuration: Channel4 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = uhCCR4_Val; TIM_OC4Init(TIM2, &TIM_OCInitStructure); TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Disable); TIM_ARRPreloadConfig(TIM2, ENABLE); /* Turn on LED1, LED2, LED3 and LED4 */ STM_EVAL_LEDOn(LED1); STM_EVAL_LEDOn(LED2); STM_EVAL_LEDOn(LED3); STM_EVAL_LEDOn(LED4); /* TIM IT enable */ TIM_ITConfig(TIM2, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, ENABLE); /* TIM2 enable counter */ TIM_Cmd(TIM2, ENABLE); while (1) { } }
void init_pwm(void) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; /* TIM config */ /* TIM4 clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_TIM4); GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_TIM4); GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_TIM2); GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_TIM2); //PrescalerValue = (uint16_t) ((SystemCoreClock /2) / 21000000) - 1; TIM_TimeBaseStructure.TIM_Period = 8400; TIM_TimeBaseStructure.TIM_Prescaler = 4; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned1; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); /* PWM1 Mode configuration: Channel1 */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC3Init(TIM4, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable); /* PWM1 Mode configuration: Channel2 */ TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; TIM_OC4Init(TIM4, &TIM_OCInitStructure); TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable); // PWM1 Mode configuration: Channel3 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; TIM_OC3Init(TIM2, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable); //PWM1 Mode configuration: Channel4 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; TIM_OC4Init(TIM2, &TIM_OCInitStructure); TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM4, ENABLE); TIM_ARRPreloadConfig(TIM2, ENABLE); /* TIM4 enable counter */ TIM_Cmd(TIM4, ENABLE); TIM_Cmd(TIM2, ENABLE); }