#include "sys.h" #include "delay.h" #include "pwm.h" #include "includes.h" //ucos Use ////////////////////////////////////////////////////////////////////////////////// //This program is for educational purposes only, without the author's permission, may not be used for any other purpose //ALIENTEK STM32F4 Explorer Board //Initialize serial port 2 //Hot Atomic @ALIENTEK //Forum: www.openedv.com //Date modified: 2015/9/12 //Version: V1.0 //All rights reserved pirated reserved. //Copyright(C) Guangzhou wing electronic technology limited company 2009-2019 //All rights reserved //******************************************************************************** ////////////////////////////////////////////////////////////////////////////////// /* Defines -------------------------------------------------------------------*/ /* Type declarations ---------------------------------------------------------*/ /* Exported macro ------------------------------------------------------------*/ void TM_OC_Init(void); void TM_TIMER_Init(void); void TM_PWM_Init(void); void PWM_Init(void) { /* Init OC */ TM_OC_Init(); /* Init timer */ TM_TIMER_Init(); /* Init PWM */ TM_PWM_Init(); } void TM_OC_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; /* Clock for GPIOD */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); /* Alternating functions for pins */ GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_TIM4); /* Set pins */ GPIO_InitStruct.GPIO_Pin = GPIO_Pin_15; GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz; GPIO_Init(GPIOD, &GPIO_InitStruct); } void TM_TIMER_Init(void) { TIM_TimeBaseInitTypeDef TIM_BaseStruct; /* Enable clock for TIM4 */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); /* TIM4 is connected to APB1 bus, which has on F407 device 42MHz clock But, timer has internal PLL, which double this frequency for timer, up to 84MHz Remember: Not each timer is connected to APB1, there are also timers connected on APB2, which works at 84MHz by default, and internal PLL increase this to up to 168MHz Set timer prescaler Timer count frequency is set with timer_tick_frequency = Timer_default_frequency / (prescaller_set + 1) In our case, we want a max frequency for timer, so we set prescaller to 0 And our timer will have tick frequency timer_tick_frequency = 84000000 / (0 + 1) = 84000000 */ TIM_BaseStruct.TIM_Prescaler = 0; /* Count up */ TIM_BaseStruct.TIM_CounterMode = TIM_CounterMode_Up; /* Set timer period when it have reset First you have to know max value for timer In our case it is 16bit = 65535 To get your frequency for PWM, equation is simple PWM_frequency = timer_tick_frequency / (TIM_Period + 1) If you know your PWM frequency you want to have timer period set correct TIM_Period = timer_tick_frequency / PWM_frequency - 1 In our case, for 10Khz PWM_frequency, set Period to TIM_Period = 84000000 / 10000 - 1 = 8399 If you get TIM_Period larger than max timer value (in our case 65535), you have to choose larger prescaler and slow down timer tick frequency */ TIM_BaseStruct.TIM_Period = 8399; /* 10kHz PWM */ TIM_BaseStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_BaseStruct.TIM_RepetitionCounter = 0; /* Initialize TIM4 */ TIM_TimeBaseInit(TIM4, &TIM_BaseStruct); /* Start count on TIM4 */ TIM_Cmd(TIM4, ENABLE); } void TM_PWM_Init(void) { TIM_OCInitTypeDef TIM_OCStruct; /* Common settings */ /* PWM mode 2 = Clear on compare match */ /* PWM mode 1 = Set on compare match */ TIM_OCStruct.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCStruct.TIM_OutputState = TIM_OutputState_Enable; TIM_OCStruct.TIM_OCPolarity = TIM_OCPolarity_Low; /* To get proper duty cycle, you have simple equation pulse_length = ((TIM_Period + 1) * DutyCycle) / 100 - 1 where DutyCycle is in percent, between 0 and 100% 25% duty cycle: pulse_length = ((8399 + 1) * 25) / 100 - 1 = 2099 50% duty cycle: pulse_length = ((8399 + 1) * 50) / 100 - 1 = 4199 75% duty cycle: pulse_length = ((8399 + 1) * 75) / 100 - 1 = 6299 100% duty cycle: pulse_length = ((8399 + 1) * 100) / 100 - 1 = 8399 Remember: if pulse_length is larger than TIM_Period, you will have output HIGH all the time */ // TIM_OCStruct.TIM_Pulse = 2099; /* 25% duty cycle */ // TIM_OC1Init(TIM4, &TIM_OCStruct); // TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable); TIM_OCStruct.TIM_Pulse = 6299; /* 50% duty cycle */ TIM_OC4Init(TIM4, &TIM_OCStruct); TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable); // TIM_OCStruct.TIM_Pulse = 6299; /* 75% duty cycle */ // TIM_OC3Init(TIM4, &TIM_OCStruct); // TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable); // TIM_OCStruct.TIM_Pulse = 8399; /* 100% duty cycle */ // TIM_OC4Init(TIM4, &TIM_OCStruct); // TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable); } void TM_PWM_PulseSet(u32 aPulse) { switch (aPulse) { case 0: TIM_SetCompare4(TIM4, 2099); /* 25% duty cycle */ break; case 1: TIM_SetCompare4(TIM4, 4199); /* 50% duty cycle */ break; case 2: TIM_SetCompare4(TIM4, 6299); /* 75% duty cycle */ break; case 3: TIM_SetCompare4(TIM4, 8399); /* 100% duty cycle */ break; } }