stm32F051系列 单片机引脚定时器输出pwm波形控制风扇转速

 

概述:stm32的每个引脚都有其自带的特殊功能,有定时器输出功能的引脚可以输出pwm。如果没有的也可以io口模拟输出,如果非要较真的话,理论上可以算是每个引脚都能输出PWM,但一般我们都使用带定时器输出功能的io。此文章来详述使用stm32F051R8T6型号单片机,带有定时器输出功能的引脚来输出pwm波形,同理其他型号的单片机也可实现。并同时来控制直流电机转速,本文以adda公司生产的AD0212DB-G50直流风扇为例讲述。

1.硬件条件

保证单片机输出IO可以支持定时器功能。我板子上连接风扇的引脚为PC9,根据单片机手册PC9引脚带有定时器功能

stm32F051系列 单片机引脚定时器输出pwm波形控制风扇转速_第1张图片

同理如下图的几个引脚都可以

stm32F051系列 单片机引脚定时器输出pwm波形控制风扇转速_第2张图片

再次就不一一列举了,在是用不同型号的单片机时,参考单片机手册。

2.stm32固件库

stm32F051系列 单片机引脚定时器输出pwm波形控制风扇转速_第3张图片

上图分别是stm32定时器相关的库函数,和相关调用的定时器驱动子函数,用户自己定义。

软硬件条件都准备好了,接下来就是pwm所需的相关配置。

1.首先是输出管脚的IO口设置,PWM输出,自然会采用到IO口作为输出端口,在STM32F051系列中,IO端口可以复用为TIM定时器输出通道。

采用PC9的复用功能AF1作为TIM3定时器的第4通道输出。

2.设置定时器的参数,配置出频率为17.57 KHz的PWM波

考虑time定时器的时钟频率。如果我们设置分频数为0,也就是说time定时器等于系统时钟,system_stm32f0xx.c中已经把系统频率设置在48MHZ,在startup_stm32f0xx.s中,首先运行了systemInit函数,因此可以确定time定时器运行在48MHZ。
定时器产生的PWM的频率可以按照下面的公式进行计算:
预定标的值TIM1_Period = (time定时器频率 / pwm的频率) - 1
预定标的值实际上就是定时器运行多少次算一个PWM周期,这个在设置pwm频率中重要的参数。

配置完整代码如下:

/*==============================================================================
    函数名      : Fan_PWMConfigInit
    功能        : 风扇控制引脚输出pwm控制风扇转速
    输入参数说明: 无
    返回值说明  : 无
------------------------------------------------------------------------------*/
void Fan_PWMConfigInit(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_OCInitTypeDef TIM_OCInitStructure;
    s32 TimerPeriod, Channel1Pulse;

    /* 使能GPIO时钟 */ 
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
    /* 配置GPIO管脚参数设置*/ 
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 
    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(GPIOC, &GPIO_InitStructure);
    /* GPIO管脚复用设置*/ 
    GPIO_PinAFConfig(GPIOC, GPIO_PinSource9, GPIO_AF_1); 


    /*计算预定标 的值,也就是多少个时钟计数为一个周期*/
    TimerPeriod = (SystemCoreClock / 17570 ) - 1;
    /*计算CCR1 跳转值 在占空比为50%时*/
    Channel1Pulse = (u16)(((u32)5 * (TimerPeriod - 1)) / 10);

    /* TIM3 时钟使能 */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
    /* Time 定时基础设置*/
    TIM_TimeBaseStructure.TIM_Prescaler = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 
    /* Time 定时设置为上升沿计算模式*/
    TIM_TimeBaseStructure.TIM_Period = TimerPeriod;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
    /* 频道1的PWM 模式设置 */
    TIM_OCInitStructure.TIM_OCMode          = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState     = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_OutputNState    = TIM_OutputNState_Enable;
    TIM_OCInitStructure.TIM_OCPolarity      = TIM_OCPolarity_Low;
    TIM_OCInitStructure.TIM_OCNPolarity     = TIM_OCNPolarity_High;
    TIM_OCInitStructure.TIM_OCIdleState     = TIM_OCIdleState_Set;
    TIM_OCInitStructure.TIM_OCNIdleState    = TIM_OCIdleState_Reset;
    TIM_OCInitStructure.TIM_Pulse = Channel1Pulse;      
    TIM_OC4Init(TIM3, &TIM_OCInitStructure);
    /* TIM3 计算器使能*/
    TIM_Cmd(TIM3, ENABLE);
    /* TIM3 主输出使能 */
    TIM_CtrlPWMOutputs(TIM3, ENABLE);

}

在需要改变风扇转速时,只需要改变占空比即可。

/* 风扇控制 */
static s32 CmdFanCtrl (TCmdTbl *cmdtp, s32 argc, s8 *argv[])
{
    u8 byCmd;
    s32 Channel1Pulse;
    
    if (argc < 2)
		return -1;

    byCmd = strtoul(argv[1], NULL, 0);
    switch(byCmd){
    case 1:
        Channel1Pulse = (u16)(((u32)875 * 2730) / 1000);
        break;
    case 2:
        Channel1Pulse = (u16)(((u32)75 * 2730) / 100);
        break;
    case 3:
        Channel1Pulse = (u16)(((u32)625 * 2730) / 1000);
        break;
    case 4:
        Channel1Pulse = (u16)(((u32)5 * 2730) / 10);
        break;
    case 5:
        Channel1Pulse = (u16)(((u32)375 * 2730) / 1000);
        break;
    case 6:
        Channel1Pulse = (u16)(((u32)25 * 2730) / 100);
        break;
    case 7:
        Channel1Pulse = (u16)(((u32)125 * 2730) / 1000);
        break;
    case 8:
        Channel1Pulse = (u16)(((u32)1 * 2730) / 100);
        break;
    }

    TIM_SetCompare4(TIM3, Channel1Pulse);

    return 0;
}

TIM_SetCompare4(TIM3, Channel1Pulse);该函数是改变对应TIM定时器对应通道占空比的函数,其中的2370是根据系统时间计算出来。使用不同的定时器和通道,可在stm32f0xx_tim.c中查找不同的库函数。

下面是输出的pwm波形

stm32F051系列 单片机引脚定时器输出pwm波形控制风扇转速_第4张图片

 

你可能感兴趣的:(stm32)