天天看點

stm32F051系列 單片機引腳定時器輸出pwm波形控制風扇轉速

概述:stm32的每個引腳都有其自帶的特殊功能,有定時器輸出功能的引腳可以輸出pwm。如果沒有的也可以io口模拟輸出,如果非要較真的話,理論上可以算是每個引腳都能輸出PWM,但一般我們都使用帶定時器輸出功能的io。此文章來詳述使用stm32F051R8T6型号單片機,帶有定時器輸出功能的引腳來輸出pwm波形,同理其他型号的單片機也可實作。并同時來控制直流電機轉速,本文以adda公司生産的AD0212DB-G50直流風扇為例講述。

1.硬體條件

保證單片機輸出IO可以支援定時器功能。我闆子上連接配接風扇的引腳為PC9,根據單片機手冊PC9引腳帶有定時器功能

stm32F051系列 單片機引腳定時器輸出pwm波形控制風扇轉速

同理如下圖的幾個引腳都可以

stm32F051系列 單片機引腳定時器輸出pwm波形控制風扇轉速

再次就不一一列舉了,在是用不同型号的單片機時,參考單片機手冊。

2.stm32固件庫

stm32F051系列 單片機引腳定時器輸出pwm波形控制風扇轉速

上圖分别是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波形控制風扇轉速

繼續閱讀