Files

174 lines
5.6 KiB
C

#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;
}
}