/** * @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 */ /* TIM1 Configuration */ TIM_Config(); /* Time base configuration */ /* ----------------------------------------------------------------------- TIM1 Configuration: generate 1 PWM signal using the DMA burst mode: TIM1 input clock (TIM1CLK) is set to APB2 clock (PCLK2) TIM1CLK = PCLK2 PCLK2 = HCLK => TIM1CLK = HCLK = SystemCoreClock To get TIM1 counter clock at 24 MHz, the prescaler is computed as follows: Prescaler = (TIM1CLK / TIM1 counter clock) - 1 Prescaler = (SystemCoreClock /24 MHz) - 1 TIM1 Frequency = TIM1 counter clock/(ARR + 1) = 24 MHz / 4096 = 5.85 KHz TIM1 Channel1 duty cycle = (TIM1_CCR1/ TIM1_ARR)* 100 = 33.33% 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. ----------------------------------------------------------------------- */ TIM_TimeBaseStructure.TIM_Period = 0xFFFF; TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t) (SystemCoreClock / 24000000) - 1; TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /* TIM Configuration in PWM Mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0xFFF; TIM_OC1Init(TIM1, &TIM_OCInitStructure); /* TIM1 DMAR Base register and DMA Burst Length Config */ TIM_DMAConfig(TIM1, TIM_DMABase_ARR, TIM_DMABurstLength_3Transfers); /* TIM1 DMA Update enable */ TIM_DMACmd(TIM1, TIM_DMA_Update, ENABLE); /* TIM1 enable */ TIM_Cmd(TIM1, ENABLE); /* TIM1 PWM Outputs Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); /* Enable DMA2 Stream5 */ DMA_Cmd(DMA1_Channel5, ENABLE); /* Wait until DMA2 Stream5 end of Transfer */ while (!DMA_GetFlagStatus(DMA1_FLAG_TC5)) { } /* 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(); /* TIM1 configuration ------------------------------------------------------*/ /* Time Base configuration */ TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = 0xFF; TIM_TimeBaseStructure.TIM_Prescaler = 0x4; TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /* TIM1 channel1 configuration in PWM mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0x7F; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OC1Init(TIM1, &TIM_OCInitStructure); /* DMA1 Channel1 Configuration ----------------------------------------------*/ DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_RegularConvertedValueTab; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = 32; 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_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel1, &DMA_InitStructure); /* Enable DMA1 channel1 */ DMA_Cmd(DMA1_Channel1, ENABLE); /* ADC1 configuration ------------------------------------------------------*/ ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = DISABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 1; ADC_Init(ADC1, &ADC_InitStructure); /* ADC1 regular channel14 configuration */ ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_13Cycles5); /* Set injected sequencer length */ ADC_InjectedSequencerLengthConfig(ADC1, 1); /* ADC1 injected channel Configuration */ ADC_InjectedChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_71Cycles5); /* ADC1 injected external trigger configuration */ ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_None); /* Enable automatic injected conversion start after regular one */ ADC_AutoInjectedConvCmd(ADC1, ENABLE); /* Enable ADC1 DMA */ ADC_DMACmd(ADC1, ENABLE); /* Enable ADC1 external trigger */ ADC_ExternalTrigConvCmd(ADC1, ENABLE); /* Enable JEOC interupt */ ADC_ITConfig(ADC1, ADC_IT_JEOC, ENABLE); /* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE); /* Enable ADC1 reset calibaration register */ ADC_ResetCalibration(ADC1); /* Check the end of ADC1 reset calibration register */ while(ADC_GetResetCalibrationStatus(ADC1)); /* Start ADC1 calibaration */ ADC_StartCalibration(ADC1); /* Check the end of ADC1 calibration */ while(ADC_GetCalibrationStatus(ADC1)); /* TIM1 counter enable */ TIM_Cmd(TIM1, ENABLE); /* TIM1 main Output Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); /* Test on channel1 transfer complete flag */ while(!DMA_GetFlagStatus(DMA1_FLAG_TC1)); /* Clear channel1 transfer complete flag */ DMA_ClearFlag(DMA1_FLAG_TC1); /* TIM1 counter disable */ TIM_Cmd(TIM1, DISABLE); while (1) { } }
// 计时器设置为PWM发生器,可以四路输出 void Timer::mode_pwm_output(float freq, float duty, uint8_t CH_No, PinTypedef p) { freq_ = freq; Pin pin(p); // 函数调用后变量就消失了 uint8_t tmp = this->GPIO_AF_TIM(this->TIM); // 看看tmp有没有问题 pin.mode_pwm_output(tmp); // 时钟预分频 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructrue; // 计时器分频初始化器 uint16_t Period; uint16_t Width; Period = (uint16_t) (TIMER_CLOCK/freq); Width = (uint16_t) (Period*duty); TIM_TimeBaseStructrue.TIM_Period = Period - 1; //PWM周期 TIM_TimeBaseStructrue.TIM_Prescaler = PRESCALER; switch (this->TIM_No) { case (1): case (8): case (9): case (10): case (11): { TIM_TimeBaseStructrue.TIM_Prescaler = PRESCALER_APB2; break; } } TIM_TimeBaseStructrue.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructrue.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInit(this->TIM, &TIM_TimeBaseStructrue); /* Enable TIM4 Preload register on ARR */ TIM_ARRPreloadConfig(this->TIM, ENABLE); TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //配置为PWM模式1 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = Width; // Period*duty //设置跳变值,当计数器计数到这个值时,电平发生跳变 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //当定时器计数值小于CCR1_Val时为高电平 switch (CH_No) { case (1):{ TIM_OC1Init(this->TIM, &TIM_OCInitStructure); TIM_OC1PreloadConfig(this->TIM, TIM_OCPreload_Enable); break; } case (2):{ TIM_OC2Init(this->TIM, &TIM_OCInitStructure); TIM_OC2PreloadConfig(this->TIM, TIM_OCPreload_Enable); break; } case (3):{ TIM_OC3Init(this->TIM, &TIM_OCInitStructure); TIM_OC3PreloadConfig(this->TIM, TIM_OCPreload_Enable); break; } case (4):{ TIM_OC4Init(this->TIM, &TIM_OCInitStructure); TIM_OC4PreloadConfig(this->TIM, TIM_OCPreload_Enable); break; } } TIM_Cmd(this->TIM, ENABLE); //使能定时器 /* TIM1 Main Output Enable */ TIM_CtrlPWMOutputs(this->TIM, 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(); /* TIM1 DMA Transfer example ------------------------------------------------- TIM1 input clock (TIM1CLK) is set to 2 * APB2 clock (PCLK2), since APB2 prescaler is different from 1. TIM1CLK = 2 * PCLK2 PCLK2 = HCLK / 2 => TIM1CLK = 2 * (HCLK / 2) = HCLK = SystemCoreClock TIM1CLK = SystemCoreClock, Prescaler = 0, TIM1 counter clock = SystemCoreClock SystemCoreClock is set to 168 MHz for STM32F4xx devices. The objective is to configure TIM1 channel 3 to generate complementary PWM signal with a frequency equal to 17.57 KHz: - TIM1_Period = (SystemCoreClock / 17570) - 1 and a variable duty cycle that is changed by the DMA after a specific number of Update DMA request. The number of this repetitive requests is defined by the TIM1 Repetion counter, each 3 Update Requests, the TIM1 Channel 3 Duty Cycle changes to the next new value defined by the SRC_Buffer. 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 value to be set in ARR regiter to generate signal frequency at 17.57 Khz */ TimerPeriod = (SystemCoreClock / 17570 ) - 1; /* Compute CCR1 value to generate a duty cycle at 50% */ SRC_Buffer[0] = (uint16_t) (((uint32_t) 5 * (TimerPeriod - 1)) / 10); /* Compute CCR1 value to generate a duty cycle at 37.5% */ SRC_Buffer[1] = (uint16_t) (((uint32_t) 375 * (TimerPeriod - 1)) / 1000); /* Compute CCR1 value to generate a duty cycle at 25% */ SRC_Buffer[2] = (uint16_t) (((uint32_t) 25 * (TimerPeriod - 1)) / 100); /* TIM1 Peripheral Configuration -------------------------------------------*/ /* TIM1 clock enable */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); /* Time Base configuration */ TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = TimerPeriod; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 3; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /* Channel 3 Configuration in PWM mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse = SRC_Buffer[0]; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; TIM_OC3Init(TIM1, &TIM_OCInitStructure); /* TIM1 counter enable */ TIM_Cmd(TIM1, ENABLE); /* DMA enable*/ DMA_Cmd(DMA2_Stream6, ENABLE); /* TIM1 Update DMA Request enable */ TIM_DMACmd(TIM1, TIM_DMA_CC3, ENABLE); /* Main Output Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); while (1) {} }
/** * @brief Configures TIM1: channels in PWM mode * @param None * @retval None */ void TIM_Config(void) { TIM_BDTRInitTypeDef TIM_BDTRInitStructure; TIM_OCInitTypeDef TIM_OCInitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; GPIO_InitTypeDef GPIO_InitStructure; /* GPIOA clock enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); /* TIM1 channels pin configuration: TIM1_CH1 -> PA8 */ GPIO_StructInit(&GPIO_InitStructure); 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_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_Init(GPIOA, &GPIO_InitStructure); /* Enable Alternate function on PA8 to be controlled by TIM1 */ GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_2); /* TIM1 clock enable */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); /* Time Base configuration */ TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = 100; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /* Channel 1 Configuration in PWM mode */ TIM_OCStructInit(&TIM_OCInitStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse = 50; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; TIM_OC1Init(TIM1, &TIM_OCInitStructure); /* Automatic Output enable, Break, dead time and lock configuration*/ TIM_BDTRStructInit(&TIM_BDTRInitStructure); TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1; TIM_BDTRInitStructure.TIM_DeadTime = 11; TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable; TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure); /* Main Output Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); /* TIM1 counter enable */ TIM_Cmd(TIM1, ENABLE); }
/** * @brief Configure the TIM1 Pins. * @param None * @retval None */ static void TIM_Config(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; TIM_BDTRInitTypeDef TIM_BDTRInitStructure; GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; /* GPIOA and GPIOB clocks enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB, ENABLE); /* TIM1 clock enable */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); /* GPIOA Configuration: Channel 1, 2, 1N and 3 as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10; 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_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStructure); /* GPIOB Configuration: Channel 2N and 3N as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_12; GPIO_Init(GPIOB, &GPIO_InitStructure); /* Connect TIM pins to AF2 */ GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_2); GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_2); GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_2); GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_2); GPIO_PinAFConfig(GPIOB, GPIO_PinSource0, GPIO_AF_2); GPIO_PinAFConfig(GPIOB, GPIO_PinSource1, GPIO_AF_2); GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_2); /*---------------------------------------------------------------------------- The STM32F0xx TIM1 peripheral offers the possibility to program in advance the configuration for the next TIM1 outputs behaviour (step) and change the configuration of all the channels at the same time. This operation is possible when the COM (commutation) event is used. The COM event can be generated by software by setting the COM bit in the TIM1_EGR register or by hardware (on TRC rising edge). In this example, a software COM event is generated each 100 ms: using the SysTick interrupt. The TIM1 is configured in Timing Mode, each time a COM event occurs, a new TIM1 configuration will be set in advance. The following Table describes the TIM1 Channels states: ----------------------------------------------- | Step1 | Step2 | Step3 | Step4 | Step5 | Step6 | ---------------------------------------------------------- |Channel1 | 1 | 0 | 0 | 0 | 0 | 1 | ---------------------------------------------------------- |Channel1N | 0 | 0 | 1 | 1 | 0 | 0 | ---------------------------------------------------------- |Channel2 | 0 | 0 | 0 | 1 | 1 | 0 | ---------------------------------------------------------- |Channel2N | 1 | 1 | 0 | 0 | 0 | 0 | ---------------------------------------------------------- |Channel3 | 0 | 1 | 1 | 0 | 0 | 0 | ---------------------------------------------------------- |Channel3N | 0 | 0 | 0 | 0 | 1 | 1 | ---------------------------------------------------------- ----------------------------------------------------------------------------*/ /* Time Base configuration */ TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = 4095; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /* Channel 1, 2,3 and 4 Configuration in PWM mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse = 2047; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set; TIM_OC1Init(TIM1, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = 1023; TIM_OC2Init(TIM1, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = 511; TIM_OC3Init(TIM1, &TIM_OCInitStructure); /* Automatic Output enable, Break, dead time and lock configuration*/ 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 = 1; TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable; TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure); TIM_CCPreloadControl(TIM1, ENABLE); TIM_ITConfig(TIM1, TIM_IT_COM, ENABLE); /* TIM1 counter enable */ TIM_Cmd(TIM1, ENABLE); /* Main Output Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); /* Enable the TIM1 Trigger and commutation interrupt */ NVIC_InitStructure.NVIC_IRQChannel = TIM1_BRK_UP_TRG_COM_IRQn; NVIC_InitStructure.NVIC_IRQChannelPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); }
void motor_enable(void) { motor_stop_all(); TIM_Cmd(MOTOR_TIMER, ENABLE); // enable timer TIM_CtrlPWMOutputs(MOTOR_TIMER, ENABLE); // enable PWM outputs }
/**************************** * PB0,PWM输出 ****************************/ void motor_init() { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TimOCInitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOB, &GPIO_InitStructure); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //控制电机方向 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOB, &GPIO_InitStructure); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //控制电机方向 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOB, &GPIO_InitStructure); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); TIM_DeInit(TIM3); TIM_InternalClockConfig(TIM3); //预分频系数为72,这样计数器时钟为72MHz/72 = 1MHz TIM_TimeBaseStructure.TIM_Prescaler = 72; //设置时钟分割 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置计数器模式为向上计数模式 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //设置计数溢出大小,每计1000个数就产生一个更新事件 TIM_TimeBaseStructure.TIM_Period = 1000-1; //将配置应用到TIM1中 TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure); //禁止ARR预装载缓冲器 TIM_ARRPreloadConfig(TIM3, DISABLE); TIM_Cmd(TIM3, DISABLE); //失能TIMx外设 //设置缺省值 TIM_OCStructInit(&TimOCInitStructure); //PWM模式1输出 TimOCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //设置占空比,占空比=(CCRx/ARR)*100%或(TIM_Pulse/TIM_Period)*100% TimOCInitStructure.TIM_Pulse = 500-1; //TIM输出比较极性高 TimOCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //使能输出状态 TimOCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //TimOCInitStructure.TIM_Channel = TIM_Channel_4; //TIM1的CH4输出 TIM_OC3Init(TIM3, &TimOCInitStructure); //TIM_OC4Init(TIM1, &TimOCInitStructure); //设置TIM2的PWM输出为使能 TIM_CtrlPWMOutputs(TIM3,ENABLE); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); }
//红外遥控初始化 //设置IO以及定时器4的输入捕获 void IRRemote_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_ICInitTypeDef TIM_ICInitStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //使能PORTB时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE); //TIM4 时钟使能 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PB9 输入 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //上拉输入 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_SetBits(GPIOB,GPIO_Pin_9); //初始化GPIOB.9 TIM_TimeBaseStructure.TIM_Period = 10000; //设定计数器自动重装值 最大10ms溢出 TIM_TimeBaseStructure.TIM_Prescaler =(72-1); //预分频器,1M的计数频率,1us加1. TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式 TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx TIM_ICInitStructure.TIM_Channel = TIM_Channel_4; // 选择输入端 IC4映射到TI4上 TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获 TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置输入分频,不分频 TIM_ICInitStructure.TIM_ICFilter = 0x03;//IC4F=0011 配置输入滤波器 8个定时器时钟周期滤波 TIM_ICInit(TIM4, &TIM_ICInitStructure);//初始化定时器输入捕获通道 TIM_Cmd(TIM4,ENABLE ); //使能定时器4 NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; //TIM3中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //先占优先级0级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级3级 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能 NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 TIM_ITConfig( TIM4,TIM_IT_Update|TIM_IT_CC4,ENABLE);//允许更新中断 ,允许CC4IE捕获中断 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8,ENABLE); GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); //TIM8基本计数器设置(设置PWM频率) //频率=TIM8_CLK/(ARR+1) TIM_TimeBaseStructure.TIM_Period = 1895; //不分频。PWM频率=72000/1895=38Khz TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure); //启用ARR的影子寄存器(直到产生更新事件才更改设置) TIM_ARRPreloadConfig(TIM8, ENABLE); //TIM8_OC1模块设置(设置1通道占空比) TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse = (1895+1)/3; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM8, &TIM_OCInitStructure); //启用CCR1寄存器的影子寄存器(直到产生更新事件才更改设置) TIM_OC1PreloadConfig(TIM8, TIM_OCPreload_Enable); TIM_Cmd(TIM8, ENABLE); //TIM8_OC通道输出PWM TIM_CtrlPWMOutputs(TIM8, ENABLE); }
L298::L298() : SimpleMotorController( { L298_Motor_Names[0], L298_Motor_Names[1], L298_Motor_Names[2], L298_Motor_Names[3] }) { // Enable timers { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; // Enable TIM1 RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); TIM_TimeBaseStructure.TIM_Period = MOTOR_MAX_VAL + 1; TIM_TimeBaseStructure.TIM_Prescaler = 31; //PrescalerValue; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); // Enable TIM3 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); TIM_TimeBaseStructure.TIM_Period = MOTOR_MAX_VAL + 1; TIM_TimeBaseStructure.TIM_Prescaler = 15; //PrescalerValue; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); } // init pwm and gpio { TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; // TIMER 1 // PWM KANAL 1 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_OCNPolarity_High; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set; TIM_OC1Init(TIM1, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); //PWM KANAL2 TIM_OC2Init(TIM1, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable); //PWM KANAL3 TIM_OC3Init(TIM1, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable); //PWM KANAL 4 TIM_OC4Init(TIM1, &TIM_OCInitStructure); TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM1, ENABLE); TIM_Cmd(TIM1, ENABLE); TIM_CtrlPWMOutputs(TIM1, ENABLE); // TIMER 3 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // PWM KANAL 1 TIM_OC1Init(TIM3, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); //PWM KANAL2 TIM_OC2Init(TIM3, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //PWM KANAL3 TIM_OC3Init(TIM3, &TIM_OCInitStructure); TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable); //PWM KANAL 4 TIM_OC4Init(TIM3, &TIM_OCInitStructure); TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM3, ENABLE); TIM_Cmd(TIM3, ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; // init pwm pins for (int i = 0; i < 4; i++) { // EN pin GPIO_InitStructure.GPIO_Pin = motorIOConfig[i].EN_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(motorIOConfig[i].EN_PORT, &GPIO_InitStructure); // IN1 GPIO_InitStructure.GPIO_Pin = motorIOConfig[i].IN1_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(motorIOConfig[i].IN1_PORT, &GPIO_InitStructure); // set alternate function of enable pin to pwm GPIO_PinAFConfig(motorIOConfig[i].IN1_PORT, motorIOConfig[i].IN1_PIN_SOURCE, GPIO_AF_TIM1); /// IN2 GPIO_InitStructure.GPIO_Pin = motorIOConfig[i].IN2_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(motorIOConfig[i].IN2_PORT, &GPIO_InitStructure); // set alternate function of enable pin to pwm GPIO_PinAFConfig(motorIOConfig[i].IN2_PORT, motorIOConfig[i].IN2_PIN_SOURCE, GPIO_AF_TIM3); } } }
/** * @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_stm32f30x.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f30x.c file */ /* GPIOA and GPIOB clocks enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB, ENABLE); /* TIM1 clock enable */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); /* GPIOA Configuration: Channel 1, 2 and 3 as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10; 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_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStructure); /* GPIOA Configuration: BKIN and channel 1N as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; GPIO_Init(GPIOA, &GPIO_InitStructure); /* GPIOB Configuration: 2N and 3N as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; GPIO_Init(GPIOB, &GPIO_InitStructure); /* Connect TIM pins to AF6 */ GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_6); GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_6); GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_6); GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_6); GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_6); GPIO_PinAFConfig(GPIOB, GPIO_PinSource0, GPIO_AF_6); GPIO_PinAFConfig(GPIOB, GPIO_PinSource1, GPIO_AF_6); /* --------------------------------------------------------------------------- TIM1 Configuration to: 1/ Generate 3 complementary PWM signals with 3 different duty cycles: TIM1 input clock (TIM1CLK) is set to APB2 clock (PCLK2). TIM1CLK = PCLK2 PCLK2 = HCLK => TIM1CLK = HCLK = SystemCoreClock TIM1CLK is fixed to SystemCoreClock, the TIM1 Prescaler is equal to 0 so the TIM1 counter clock used is SystemCoreClock (48MHz). The objective is to generate PWM signal at 17.57 KHz: - TIM1_Period = (SystemCoreClock / 17570) - 1 The Three Duty cycles are computed as the following description: The channel 1 duty cycle is set to 50% so channel 1N is set to 50%. The channel 2 duty cycle is set to 25% so channel 2N is set to 75%. The channel 3 duty cycle is set to 12.5% so channel 3N is set to 87.5%. The Timer pulse is calculated as follows: - ChannelxPulse = DutyCycle * (TIM1_Period - 1) / 100 2/ Insert a dead time equal to (11/SystemCoreClock) ns 3/ Configure the break feature, active at High level, and using the automatic output enable feature 4/ Use the Locking parameters level1. 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 value to be set in ARR register to generate signal frequency at 17.57 Khz */ TimerPeriod = (SystemCoreClock / 17570) - 1; /* Compute CCR1 value to generate a duty cycle at 50% for channel 1 */ Channel1Pulse = (uint16_t) (((uint32_t) 5 * (TimerPeriod - 1)) / 10); /* Compute CCR2 value to generate a duty cycle at 25% for channel 2 */ Channel2Pulse = (uint16_t) (((uint32_t) 25 * (TimerPeriod - 1)) / 100); /* Compute CCR3 value to generate a duty cycle at 12.5% for channel 3 */ Channel3Pulse = (uint16_t) (((uint32_t) 125 * (TimerPeriod - 1)) / 1000); /* Time Base configuration */ TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = TimerPeriod; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /* Channel 1, 2 and 3 Configuration in PWM mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse = Channel1Pulse; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; TIM_OC1Init(TIM1, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = Channel2Pulse; TIM_OC2Init(TIM1, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = Channel3Pulse; TIM_OC3Init(TIM1, &TIM_OCInitStructure); /* Automatic Output enable, Break, dead time and lock configuration*/ TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable; TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1; TIM_BDTRInitStructure.TIM_DeadTime = 11; TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable; TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High; TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure); /* TIM1 counter enable */ TIM_Cmd(TIM1, ENABLE); /* Main Output Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); /* Infinite loop */ while (1) { } }
/** * @brief Configure the TIM Pins. * @param None * @retval None */ static void TIM_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; uint16_t TimerPeriod = 0; uint16_t Channel1Pulse = 0, Channel2Pulse = 0, Channel3Pulse = 0, Channel5Pulse = 0; /* GPIOA Clocks enable */ RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOA, ENABLE); /* GPIOA Configuration: Channel 1, 2, 3 and 4 as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10; 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_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_6); GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_6); GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_6); /* TIM1 Configuration --------------------------------------------------- Generate 3 combined PWM signals: TIM1 input clock (TIM1CLK) is set to APB2 clock (PCLK2) => TIM1CLK = PCLK2 = SystemCoreClock TIM1CLK = SystemCoreClock, Prescaler = 0, TIM1 counter clock = SystemCoreClock SystemCoreClock is set to 72 MHz for STM32F30x devices The objective is to generate 3 combined PWM signal at 8.78 KHz (in center aligned mode): - TIM1_Period = (SystemCoreClock / (8.78*2)) - 1 The channel 1 duty cycle is set to 50% The channel 2 duty cycle is set to 37.5% The channel 3 duty cycle is set to 25% The Timer pulse is calculated as follows: - ChannelxPulse = DutyCycle * (TIM1_Period - 1) / 100 The channel 5 is used in PWM2 mode with duty cycle set to 6.22% The 3 resulting signals are made of an AND logical combination of two reference PWMs: - Channel 1 and Channel 5 - Channel 2 and Channel 5 - Channel 3 and Channel 5 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 value to be set in ARR regiter to generate signal frequency at 17.57 Khz */ TimerPeriod = (SystemCoreClock / 17570 ) - 1; /* Compute CCR1 value to generate a duty cycle at 50% for channel 1 */ Channel1Pulse = (uint16_t) (((uint32_t) 5 * (TimerPeriod - 1)) / 10); /* Compute CCR2 value to generate a duty cycle at 37.5% for channel 2 */ Channel2Pulse = (uint16_t) (((uint32_t) 375 * (TimerPeriod - 1)) / 1000); /* Compute CCR3 value to generate a duty cycle at 25% for channel 3 */ Channel3Pulse = (uint16_t) (((uint32_t) 25 * (TimerPeriod - 1)) / 100); /* Compute CCR5 value to generate a duty cycle at 6.22% for channel 5 (in PWM2)*/ Channel5Pulse = (uint16_t) (((uint32_t) 622 * (TimerPeriod - 1)) / 10000); /* TIM1 clock enable */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 , ENABLE); /* Time Base configuration */ TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned1; TIM_TimeBaseStructure.TIM_Period = TimerPeriod; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /* Channel 1, 2,3 and 4 Configuration in PWM mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable; TIM_OCInitStructure.TIM_Pulse = Channel1Pulse; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; TIM_OC1Init(TIM1, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = Channel2Pulse; TIM_OC2Init(TIM1, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse = Channel3Pulse; TIM_OC3Init(TIM1, &TIM_OCInitStructure); /* TIM1 Channel 5 configuration */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_Pulse = Channel5Pulse; TIM_OC5Init(TIM1, &TIM_OCInitStructure); TIM_SelectGC5C1(TIM1, ENABLE); TIM_SelectGC5C2(TIM1, ENABLE); TIM_SelectGC5C3(TIM1, ENABLE); /* TIM1 counter enable */ TIM_Cmd(TIM1, ENABLE); /* TIM1 Main Output Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); }
void transponderIrHardwareInit(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; GPIO_InitTypeDef GPIO_InitStructure; DMA_InitTypeDef DMA_InitStructure; RCC_AHBPeriphClockCmd(TRANSPONDER_GPIO_AHB_PERIPHERAL, ENABLE); GPIO_PinAFConfig(TRANSPONDER_GPIO, TRANSPONDER_PIN_SOURCE, TRANSPONDER_GPIO_AF); /* Configuration alternate function push-pull */ GPIO_StructInit(&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = TRANSPONDER_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(TRANSPONDER_GPIO, &GPIO_InitStructure); RCC_APB2PeriphClockCmd(TRANSPONDER_TIMER_APB2_PERIPHERAL, ENABLE); /* Time base configuration */ TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = 156; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TRANSPONDER_TIMER, &TIM_TimeBaseStructure); /* PWM1 Mode configuration: Channel1 */ TIM_OCStructInit(&TIM_OCInitStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; #ifdef TRANSPONDER_INVERTED TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; #else TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; #endif TIM_OC1Init(TRANSPONDER_TIMER, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TRANSPONDER_TIMER, TIM_OCPreload_Enable); TIM_CtrlPWMOutputs(TRANSPONDER_TIMER, ENABLE); /* configure DMA */ /* DMA clock enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); /* DMA1 Channel6 Config */ DMA_DeInit(TRANSPONDER_DMA_CHANNEL); DMA_StructInit(&DMA_InitStructure); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&TRANSPONDER_TIMER->CCR1; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)transponderIrDMABuffer; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize = TRANSPONDER_DMA_BUFFER_SIZE; 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_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(TRANSPONDER_DMA_CHANNEL, &DMA_InitStructure); TIM_DMACmd(TRANSPONDER_TIMER, TIM_DMA_CC1, ENABLE); DMA_ITConfig(TRANSPONDER_DMA_CHANNEL, DMA_IT_TC, ENABLE); NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = TRANSPONDER_IRQ; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_TRANSPONDER_DMA); NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_TRANSPONDER_DMA); NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); }
void ws2811LedStripHardwareInit(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; GPIO_InitTypeDef GPIO_InitStructure; DMA_InitTypeDef DMA_InitStructure; uint16_t prescalerValue; #ifdef CC3D RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_StructInit(&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); #else RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); /* GPIOA Configuration: TIM3 Channel 1 as alternate function push-pull */ GPIO_StructInit(&GPIO_InitStructure); 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); #endif RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); /* Compute the prescaler value */ prescalerValue = (uint16_t) (SystemCoreClock / 24000000) - 1; /* Time base configuration */ TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = 29; // 800kHz 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_OCStructInit(&TIM_OCInitStructure); 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); TIM_CtrlPWMOutputs(TIM3, ENABLE); /* configure DMA */ /* DMA clock enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); /* DMA1 Channel6 Config */ DMA_DeInit(DMA1_Channel6); DMA_StructInit(&DMA_InitStructure); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&TIM3->CCR1; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ledStripDMABuffer; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize = WS2811_DMA_BUFFER_SIZE; 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_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel6, &DMA_InitStructure); /* TIM3 CC1 DMA Request enable */ TIM_DMACmd(TIM3, TIM_DMA_CC1, ENABLE); DMA_ITConfig(DMA1_Channel6, DMA_IT_TC, ENABLE); NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel6_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(NVIC_PRIO_WS2811_DMA); NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(NVIC_PRIO_WS2811_DMA); NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); const hsvColor_t hsv_white = { 0, 255, 255}; setStripColor(&hsv_white); ws2811UpdateStrip(); }
void motor_disable() { TIM_CtrlPWMOutputs(MOTOR_TIMER, DISABLE); // disable PWM outputs TIM_Cmd(MOTOR_TIMER, DISABLE); // disable timer }
bool pwmInit(drv_pwm_config_t *init) { GPIO_InitTypeDef GPIO_InitStructure = { 0, }; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure = { 0, }; TIM_OCInitTypeDef TIM_OCInitStructure = { 0, }; uint8_t i; // Inputs // RX1 TIM2_CH1 PA0 [also PPM] [also used for throttle calibration] // RX2 TIM2_CH2 PA1 // RX3 TIM2_CH3 PA2 [also UART2_TX] // RX4 TIM2_CH4 PA3 [also UART2_RX] // RX5 TIM3_CH1 PA6 [also ADC_IN6] // RX6 TIM3_CH2 PA7 [also ADC_IN7] // RX7 TIM3_CH3 PB0 [also ADC_IN8] // RX8 TIM3_CH4 PB1 [also ADC_IN9] // Outputs // PWM1 TIM1_CH1 PA8 // PWM2 TIM1_CH4 PA11 // PWM3 TIM4_CH1 PB6 [also I2C1_SCL] // PWM4 TIM4_CH2 PB7 [also I2C1_SDA] // PWM5 TIM4_CH3 PB8 // PWM6 TIM4_CH4 PB9 // use PPM or PWM input usePPMFlag = init->usePPM; // preset channels to center for (i = 0; i < 8; i++) Inputs[i].capture = 1500; // Timers run at 1mhz. // TODO: clean this shit up. Make it all dynamic etc. if (init->enableInput) pwmInitializeInput(usePPMFlag); // Output pins (4x) GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); // Output timer TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Prescaler = (72 - 1); TIM_TimeBaseStructure.TIM_Period = (1000000 / init->motorPwmRate) - 1; TIM_TimeBaseInit(TIM4, &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 = PULSE_1MS; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; // PWM1,2,3,4 TIM_OC1Init(TIM4, &TIM_OCInitStructure); TIM_OC2Init(TIM4, &TIM_OCInitStructure); TIM_OC3Init(TIM4, &TIM_OCInitStructure); TIM_OC4Init(TIM4, &TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable); TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable); TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable); TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable); TIM_Cmd(TIM4, ENABLE); TIM_CtrlPWMOutputs(TIM4, ENABLE); TIM_OC1PreloadConfig (TIM4, TIM_OCPreload_Enable); // turn on more motor outputs if we're using ppm / not using pwm input if (!init->enableInput || init->usePPM) { // TODO } return false; }
void motorCfg(void) { /* -1- */ GPIO_InitTypeDef Gpio_InitStr; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; /* -2- */ //TIM1 Clock Enable RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); //TIM3 TIM4 TIM5 Clock Enable RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM3 | RCC_APB1Periph_TIM4 | RCC_APB1Periph_TIM5, ENABLE); /* -3- */ // GPIOA GPIOB GPIOD clock enable RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOD | RCC_APB2Periph_AFIO, ENABLE); //TIM1 CH1(PA8) CH2(PA9) CH3(PA10) CH4(PA11) //TIM1 No Remap Gpio_InitStr.GPIO_Mode = GPIO_Mode_AF_PP; Gpio_InitStr.GPIO_Speed = GPIO_Speed_50MHz; Gpio_InitStr.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11; GPIO_Init(GPIOA, &Gpio_InitStr); //TIM3 CH1(PB4) CH2(PB5) //TIM3 Partial Remap TIM3_CH1&TIM3_CH2 //TIM3_CH1: PA6 --- PB4 //TIM3_CH2: PA7 --- PB5 GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE); //¹Ø±Õjtag //TIM2 Partial Remap //PA15 Gpio_InitStr.GPIO_Pin = GPIO_Pin_15; GPIO_Init(GPIOA, &Gpio_InitStr); //PB3 Gpio_InitStr.GPIO_Pin = GPIO_Pin_3; GPIO_Init(GPIOB, &Gpio_InitStr); GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2, ENABLE); Gpio_InitStr.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5; GPIO_Init(GPIOB, &Gpio_InitStr); GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); GPIO_SetBits(GPIOB,GPIO_Pin_3); //TIM4 CH3(PD14) CH4(PD15) //TIM4 Full Remap (Motor use CH3~CH4 Ultrasonic use CH1~CH2) //TIM4_CH1: PB6 --- PD12 //TIM4_CH2: PB7 --- PD13 //TIM4_CH3: PB8 --- PD14 //TIM4_CH4: PB9 --- PD15 Gpio_InitStr.GPIO_Pin = GPIO_Pin_14 | GPIO_Pin_15; GPIO_Init(GPIOD, &Gpio_InitStr); GPIO_PinRemapConfig(GPIO_Remap_TIM4, ENABLE); //TIM5 CH1(PA0) CH2(PA1) //TIM1 No Remap Gpio_InitStr.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; GPIO_Init(GPIOA, &Gpio_InitStr); /* -4- */ // Time Base configuration TIM_TimeBaseStructure.TIM_Prescaler = getHclkFrequency()/2000000-1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period = 100-1; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; //TIM1 TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //TIM2 TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //TIM3 TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //TIM4 TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //TIM5 TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure); //PWM set TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0;//Init with duty cycle zero. //High active TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //TIM1 TIM_OC1Init(TIM1, &TIM_OCInitStructure); TIM_OC2Init(TIM1, &TIM_OCInitStructure); TIM_OC3Init(TIM1, &TIM_OCInitStructure); TIM_OC4Init(TIM1, &TIM_OCInitStructure); //TIM2 (PWM CH1~CH2) TIM_OC1Init(TIM2, &TIM_OCInitStructure); TIM_OC2Init(TIM2, &TIM_OCInitStructure); //TIM3(PWM CH1~CH2) TIM_OC1Init(TIM3, &TIM_OCInitStructure); TIM_OC2Init(TIM3, &TIM_OCInitStructure); //TIM4(PWM CH3~CH4) TIM_OC3Init(TIM4, &TIM_OCInitStructure); TIM_OC4Init(TIM4, &TIM_OCInitStructure); //TIM5 TIM_OC1Init(TIM5, &TIM_OCInitStructure); TIM_OC2Init(TIM5, &TIM_OCInitStructure); //TIM1 TIM_Cmd(TIM1, ENABLE); //TIM1 TIM_Cmd(TIM2, ENABLE); //TIM3 TIM_Cmd(TIM3, ENABLE); //TIM4 TIM_Cmd(TIM4, ENABLE); //TIM5 TIM_Cmd(TIM5, ENABLE); //TIM1 Main Output Enable TIM_CtrlPWMOutputs(TIM1, ENABLE); //TIM2 Main Output Enable TIM_CtrlPWMOutputs(TIM2, ENABLE); //TIM3 Main Output Enable TIM_CtrlPWMOutputs(TIM3, ENABLE); //TIM4 Main Output Enable TIM_CtrlPWMOutputs(TIM4, ENABLE); //TIM5 Main Output Enable TIM_CtrlPWMOutputs(TIM5, ENABLE); /* -5- */ TIM_SetCompare1(TIM2, 50); TIM_SetCompare2(TIM2, 50); // //TIM1(PWM CH1~CH4) // TIM_SetCompare1(TIM1, 50); // TIM_SetCompare2(TIM1, 50); // TIM_SetCompare3(TIM1, 50); // TIM_SetCompare4(TIM1, 50); // // //TIM3(PWM CH1~CH2) // TIM_SetCompare1(TIM3, 50); // TIM_SetCompare2(TIM3, 50); // // //TIM4(PWM CH3~CH4) // TIM_SetCompare3(TIM4, 50); // TIM_SetCompare4(TIM4, 50); // // //TIM5(PWM CH1~CH2) // TIM_SetCompare1(TIM5, 50); // TIM_SetCompare2(TIM5, 50); LeftFootMove(50); LeftKneeMove(50); LeftArmMove(50); LeftWristMove(50); HeadMove(50); WaistMove(50); RightFootMove(50); RightKneeMove(70); RightArmMove(50); RightWristMove(50); }