Chinaunix首页 | 论坛 | 博客
  • 博客访问: 805821
  • 博文数量: 281
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2770
  • 用 户 组: 普通用户
  • 注册时间: 2009-08-02 19:45
个人简介

邮箱:zhuimengcanyang@163.com 痴爱嵌入式技术的蜗牛

文章分类
文章存档

2020年(1)

2018年(1)

2017年(56)

2016年(72)

2015年(151)

分类: 嵌入式

2015-10-19 16:09:37

/**
 * \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);
}


阅读(9520) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~