/**
* \brief grant add here. timer module to generate 8 channal PWM output.
* \date
*
* PWM Channal pin mapping:
*
* PC9 - TIM8_CH4 ---> PWM1
* PC8 - TIM8_CH3 ---> PWM2
* PC7 - TIM8_CH2 ---> PWM3
* PC6 - TIM8_CH1 ---> PWM4
* PB6 - TIM4_CH1 ---> PWM5
* PB7 - TIM4_CH2 ---> PWM6
* PB8 - TIM4_CH3 ---> PWM7
* PB9 - TIM4_CH4 ---> PWM8
*
**/
#include "timer.h"
#include "stm32f10x.h"
/**
* PWM: frequency = 250hz.
*/
#define PWM_FREQENCY 4000
#define PWM_OUTPUT_CH 8
#define PWM_PATTERN_NUM 5
static const uint8_t PWM_DutyCycle_Array[PWM_OUTPUT_CH][PWM_PATTERN_NUM] ={
{0, 95, 90, 30, 90}, // TIM8_CH4
{0, 65, 80, 40, 90}, // TIM8_CH3
{0, 40, 60, 50, 90}, // TIM8_CH2
{0, 40, 50, 60, 90}, // TIM8_CH1
{0, 50, 40, 70, 90}, // TIM4_CH1
{0, 60, 30, 80, 90}, // TIM4_CH2
{0, 70, 20, 90, 90}, // TIM4_CH3
{0, 80, 10, 100, 90}, // TIM4_CH4
};
static void timer4_PWM_GpioInit(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* 设置TIM4CLK为72MHZ */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
/* GPIOB clock enable, Enable AFIO function */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
/* PB6,7,8,9 -> timer4: Config to PWM output mode */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
static void timer8_PWM_GpioInit(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* 设置TIM8CLK为72MHZ */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);
/* GPIOC clock enable, Enable AFIO function */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);
/* PC8,9: Config to PWM output mode */
/*GPIOB Configuration: TIM8 channel 3 and 4 as alternate function push-pull */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
static void timer8_PWM_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_DeInit(TIM8);
//TIM_InternalClockConfig(TIM8);
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Prescaler = 71; // prescaler = 71, TIM_CLK = 72MHZ/(71+1) = 1MHZ.
TIM_TimeBaseStructure.TIM_Period = PWM_FREQENCY -1 ; // 当定时器从0计数到999,即为1000次,为一个定时周期
// pwm F = 1MHZ/(3999+1) = 250HZ.
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1 ; //设置时钟分频系数:不分频(这里用不到)
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //配置为PWM模式1
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //当定时器计数值小于CCR1_Val时为高电平
/* PWM1 Mode configuration: Channel4 */
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = (PWM_DutyCycle_Array[0][0] * PWM_FREQENCY )/100; //设置通道4的电平跳变值,输出另外一个占空比的PWM
TIM_OC4Init(TIM8, &TIM_OCInitStructure); //使能通道4
TIM_OC4PreloadConfig(TIM8, TIM_OCPreload_Enable);
/* PWM1 Mode configuration: Channel3 */
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = (PWM_DutyCycle_Array[1][0] * PWM_FREQENCY )/100; //设置通道4的电平跳变值,输出另外一个占空比的PWM
TIM_OC3Init(TIM8, &TIM_OCInitStructure); //使能通道3
TIM_OC3PreloadConfig(TIM8, TIM_OCPreload_Enable);
/* PWM1 Mode configuration: Channel2 */
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = (PWM_DutyCycle_Array[2][0] * PWM_FREQENCY )/100; //设置通道4的电平跳变值,输出另外一个占空比的PWM
TIM_OC2Init(TIM8, &TIM_OCInitStructure); //使能通道2
TIM_OC2PreloadConfig(TIM8, TIM_OCPreload_Enable);
/* PWM1 Mode configuration: Channel1 */
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = (PWM_DutyCycle_Array[3][0] * PWM_FREQENCY )/100; //设置通道4的电平跳变值,输出另外一个占空比的PWM
TIM_OC1Init(TIM8, &TIM_OCInitStructure); //使能通道1
TIM_OC1PreloadConfig(TIM8, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM8, ENABLE); // 使能TIM8重载寄存器ARR
/* TIM8 enable counter */
TIM_Cmd(TIM8, ENABLE); // 使能定时器8
TIM_CtrlPWMOutputs(TIM8, ENABLE); // 注意: 配置定时器8的PWM模式,必须加上这句话!!
}
static void timer4_PWM_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_InternalClockConfig(TIM4);
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Prescaler = 71; // prescaler = 71, TIM_CLK = 72MHZ/(71+1) = 1MHZ.
TIM_TimeBaseStructure.TIM_Period = PWM_FREQENCY -1 ; // 当定时器从0计数到999,即为1000次,为一个定时周期
// pwm F = 1MHZ/(3999+1) = 250HZ.
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1 ; //设置时钟分频系数:不分频(这里用不到)
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //配置为PWM模式1
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //当定时器计数值小于CCR1_Val时为高电平
/* PWM1 Mode configuration: Channel1 */
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = (PWM_DutyCycle_Array[4][0] * PWM_FREQENCY )/100; //设置通道4的电平跳变值,输出另外一个占空比的PWM
TIM_OC1Init(TIM4, &TIM_OCInitStructure); //使能通道1
TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);
/* PWM1 Mode configuration: Channel2 */
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = (PWM_DutyCycle_Array[5][0] * PWM_FREQENCY )/100; //设置通道4的电平跳变值,输出另外一个占空比的PWM
TIM_OC2Init(TIM4, &TIM_OCInitStructure); //使能通道2
TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable);
/* PWM1 Mode configuration: Channel3 */
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = (PWM_DutyCycle_Array[6][0] * PWM_FREQENCY )/100; //设置通道4的电平跳变值,输出另外一个占空比的PWM
TIM_OC3Init(TIM4, &TIM_OCInitStructure); //使能通道3
TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);
/* PWM1 Mode configuration: Channel4 */
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = (PWM_DutyCycle_Array[7][0] * PWM_FREQENCY )/100; //设置通道4的电平跳变值,输出另外一个占空比的PWM
TIM_OC4Init(TIM4, &TIM_OCInitStructure); //使能通道4
TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM4, ENABLE); // 使能TIM3重载寄存器ARR
/* TIM4 enable counter */
TIM_Cmd(TIM4, ENABLE); //使能定时器4
}
static void PWM_SetDutyCycle(TEST_PATTERN test_pattern)
{
TIM_SetCompare4(TIM8, (( PWM_DutyCycle_Array[0][test_pattern] * (PWM_FREQENCY/100))));
TIM_SetCompare3(TIM8, (( PWM_DutyCycle_Array[1][test_pattern] * (PWM_FREQENCY/100))));
TIM_SetCompare2(TIM8, (( PWM_DutyCycle_Array[2][test_pattern] * (PWM_FREQENCY/100))));
TIM_SetCompare1(TIM8, (( PWM_DutyCycle_Array[3][test_pattern] * (PWM_FREQENCY/100))));
TIM_SetCompare1(TIM4, (( PWM_DutyCycle_Array[4][test_pattern] * (PWM_FREQENCY/100))));
TIM_SetCompare2(TIM4, (( PWM_DutyCycle_Array[5][test_pattern] * (PWM_FREQENCY/100))));
TIM_SetCompare3(TIM4, (( PWM_DutyCycle_Array[6][test_pattern] * (PWM_FREQENCY/100))));
TIM_SetCompare4(TIM4, (( PWM_DutyCycle_Array[7][test_pattern] * (PWM_FREQENCY/100))));
}
void PWM_GpioInit(void)
{
timer8_PWM_GpioInit();
timer4_PWM_GpioInit();
}
void PWM_TimerInit(void)
{
timer8_PWM_Init();
timer4_PWM_Init();
}
void PWM_RunPattern(TEST_PATTERN *p_test_pattern)
{
TEST_PATTERN test_pattern;
test_pattern = *p_test_pattern;
PWM_SetDutyCycle(test_pattern);
}
阅读(9746) | 评论(0) | 转发(0) |