基於STM32F103的四路PWM配置程序及個人見解

平臺:STM32F103系列

內容:生成四路PWM波

1、初始化配置

void Pwmpin_init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_0 | GPIO_Pin_1;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

}

這一段爲用到的引腳初始化配置,其中用到定時器3的通道1 、2、 3、 4,分別對應A口的6、7,B口的0、1。

void TIM_Config(void)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_OCInitTypeDef  TIM_OCInitStructure;

    //定時器配置
    TIM_TimeBaseStructure.TIM_Prescaler = 72 ;//設置72分頻
    TIM_TimeBaseStructure.TIM_Period = 1000;//設置計數溢出大小,每計1000個數就產生一個更新事件
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//設置時鐘分割
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//設置計數器模式爲向上計數模式
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);//將配置應用到TIM3中
    //PWM配置ch1
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //配置爲PWM模式2
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能
    TIM_OCInitStructure.TIM_Pulse = 0; //設置待裝入捕獲比較寄存器的脈衝值
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //有效電平爲低電平

    TIM_OC1Init(TIM3, &TIM_OCInitStructure);//使能通道3
    TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);
    //PWM配置ch2
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能
    TIM_OCInitStructure.TIM_Pulse = 0; //設置待裝入捕獲比較寄存器的脈衝值
    
    TIM_OC2Init(TIM3, &TIM_OCInitStructure);//使能通道3
    TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
    //PWM配置ch3
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能
    TIM_OCInitStructure.TIM_Pulse = 0; //設置待裝入捕獲比較寄存器的脈衝值
    
    TIM_OC3Init(TIM3, &TIM_OCInitStructure);//使能通道3
    TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);
    //PWM配置ch4
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能
    TIM_OCInitStructure.TIM_Pulse = 0; //設置待裝入捕獲比較寄存器的脈衝值
    
    TIM_OC4Init(TIM3, &TIM_OCInitStructure);//使能通道3
    TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);

    //使能
    TIM_ARRPreloadConfig(TIM3, ENABLE);//使能TIM3重載寄存器ARR
    TIM_Cmd(TIM3, ENABLE);//使能定時器3
}

這一段代碼是配置PWM的重點,其中最爲主要的是:

TIM_TimeBaseStructure.TIM_Prescaler = 72 ;//設置72分頻
TIM_TimeBaseStructure.TIM_Period = 1000;//設置計數溢出大小,每計1000個數就產生一個更新事件

此兩行代碼確定了PWM波的頻率,經過測試,此處配置完成後示波器顯示的頻率爲1KHz,因此可知頻率其計算方法爲:

                                PWM頻率=TIM3的時鐘頻率/(分頻係數 x 計數溢出值)

2、設置四路PWM波佔空比函數

void Timer3_PWM_SetDutyCycle(u8 ch, u16 Timer3_PWM_DutyCycle)
{
    switch (ch)
    {
    case 1:
        TIM_SetCompare1(TIM3, Timer3_PWM_DutyCycle );//通道1佔空比
        break;
    case 2:
        TIM_SetCompare2(TIM3, Timer3_PWM_DutyCycle );//通道2佔空比
        break;
    case 3:
        TIM_SetCompare3(TIM3, Timer3_PWM_DutyCycle );//通道3佔空比
        break;
    case 4:
        TIM_SetCompare4(TIM3, Timer3_PWM_DutyCycle );//通道4佔空比
        break;	
    }
}

設置佔空比主要是通過 ”TIM_SetComparex(TIM3,佔空比);“這個庫函數來設置,其中x代表相應的通道。

其中佔空比的設置與初始化配置的時候的 “TIM_TimeBaseStructure.TIM_Period = 1000;”相關聯,其關係是最大的佔空比這個值不能大於1000。

其實我更願意把 TIM_Period 叫做精度,假如設置這個值是100,那麼我們能設置的值只有0-100,而設置爲1000的時候我們能設置的值就從0-100,變成了0-1000。這就意味着可以做到更爲精準的額PWM調控,當然若是想保持頻率不變也必須遵循這個公式:PWM頻率=TIM3的時鐘頻率/(分頻係數 x 計數溢出值),相應的改大分頻係數值。

至此PWM的初始化以及佔空比改變函數就已結束。

3、測試主函數代碼

#define duty 500
void TIM3_PWM_Init(void)
{
    Pwmpin_init();
    TIM_Cfg();
}

int main()
{
    TIM3_PWM_Init();
    while(1)
    {
        Timer3_PWM_SetDutyCycle(1,duty);
	Timer3_PWM_SetDutyCycle(2,duty);
	Timer3_PWM_SetDutyCycle(3,duty);
	Timer3_PWM_SetDutyCycle(4,duty);
    }		
}

編譯過後通過示波器即可看到一個頻率爲1KHz,佔空比爲50%的波,或者通過keil軟件仿真也可看到。

有不正確的地方請提出,謝謝。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章