STM32F103單片機生成16路PWM波

單片機輸出pwm波在項目中是恨常用的一個功能,今天就總結一下用STM32F103C8T6單片機輸出16路 pwm波。

使用keil5軟件,用標準庫函數來實現。

首先看定時器初始化


void TIM1_PWM_Init(u16 arr, u16 psc)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    TIM_OCInitTypeDef TIM_OCInitSturcture;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_TIM1, ENABLE);
    //初始化IO口
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    //設置 TIM ARR PSC
    TIM_TimeBaseInitStructure.TIM_Period = arr;
    TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;		//向上計數模式
    TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0x00;
    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseInitStructure);

    //TIM1_CH1  PWM1 模式
    TIM_OCInitSturcture.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitSturcture.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitSturcture.TIM_OCPolarity = TIM_OCPolarity_High;			//輸出高電平有效
    TIM_OC1Init(TIM1, &TIM_OCInitSturcture);

    //TIM1_CH2  PWM1 模式
    TIM_OCInitSturcture.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitSturcture.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitSturcture.TIM_OCPolarity = TIM_OCPolarity_High;		 
    TIM_OC2Init(TIM1, &TIM_OCInitSturcture);


    //TIM1_CH3  PWM2 模式
    TIM_OCInitSturcture.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitSturcture.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitSturcture.TIM_OCPolarity = TIM_OCPolarity_High;		 
    TIM_OC3Init(TIM1, &TIM_OCInitSturcture);

    //TIM1_CH4  PWM2 模式
    TIM_OCInitSturcture.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitSturcture.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitSturcture.TIM_OCPolarity = TIM_OCPolarity_High;		
    TIM_OC4Init(TIM1, &TIM_OCInitSturcture);


    TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);					//TIM1_CH1 使能預裝載寄存器
    TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);					 //TIM1_CH2 使能預裝載寄存器
    TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);					 //TIM1_CH3 使能預裝載寄存器
    TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);					 //TIM1_CH4 使能預裝載寄存器


    TIM_Cmd(TIM1, ENABLE);				//使能計數器
    TIM_CtrlPWMOutputs(TIM1, ENABLE);	//主輸出使能
}

初始化定時1的4個通道,對應IO口爲 PA8,PA9,PA10,PA11,將這4個口都設置爲PWM輸出口。入口參數arr用來設置定時器的自動重裝載值,psc用於設置時鐘分頻係數。時鐘默認爲72MHZ。

下來初始化定時器2

void TIM2_PWM_Init(u16 arr, u16 psc)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    TIM_OCInitTypeDef TIM_OCInitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);			  //使能定時器2時鐘
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);	          //使能GPIO時鐘

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

    //初始化TIM2
    TIM_TimeBaseInitStructure.TIM_Period = arr;
    TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);

	//初始化TIM2_CH1  PWM 模式
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OC1Init(TIM2, &TIM_OCInitStructure);	

    //初始化TIM2_CH2  PWM 模式
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OC2Init(TIM2, &TIM_OCInitStructure);

    //初始化TIM2_CH3  PWM 模式
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OC3Init(TIM2, &TIM_OCInitStructure);

    //初始化TIM2_CH4  PWM 模式
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OC4Init(TIM2, &TIM_OCInitStructure);

    //使能TIM2在CCR上的預裝載寄存器
	TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);
    TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);
    TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);
    TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable);

    //使能TIM2
    TIM_Cmd(TIM2, ENABLE);
}

這裏要注意的是,定時器1是高級定時器,定時器2、3、4是通用定時器。只有高級定時器有重複計數寄存器,而通過定時器沒有重複計數寄存器。定時器2初始化時,比定時器1少一行代碼,這裏要注意一下。

 TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0x00;

重複計數寄存器主要作用如下:

其餘設置方法和定時器1基本一樣,定時器2的4個通道對應的IO口爲PA0,PA1,PA2,PA3.將這四個口設置爲PWM輸出模式。

入口參數arr用來設置定時器的自動重裝載值,psc用於設置時鐘分頻係數。時鐘默認爲72MHZ。

下來設置定時器3

void TIM3_PWM_Init(u16 arr, u16 psc)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    TIM_OCInitTypeDef TIM_OCInitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);							//使能定時器3時鐘
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);	//使能GPIO時鐘

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

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

    //初始化TIM3
    TIM_TimeBaseInitStructure.TIM_Period = arr;
    TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);

    //初始化TIM3_CH1  PWM 模式
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OC1Init(TIM3, &TIM_OCInitStructure);

    //初始化TIM3_CH2  PWM 模式
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OC2Init(TIM3, &TIM_OCInitStructure);

    //初始化TIM3_CH3  PWM 模式
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OC3Init(TIM3, &TIM_OCInitStructure);

    //初始化TIM3_CH4  PWM 模式
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OC4Init(TIM3, &TIM_OCInitStructure);

    //使能TIM3在CCR上的預裝載寄存器
    TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);
    TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
    TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);
    TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);
    //使能TIM3
    TIM_Cmd(TIM3, ENABLE);
}

設置方法和定時器2一樣,定時器3的4個通道對應的IO口爲PA6,PA7,PB0,PB1。將這四個口設置爲PWM輸出模式。

入口參數arr用來設置定時器的自動重裝載值,psc用於設置時鐘分頻係數。時鐘默認爲72MHZ。

最後設置定時器4


void TIM4_PWM_Init(u16 arr, u16 psc)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    TIM_OCInitTypeDef TIM_OCInitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);			//使能定時器4時鐘
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE);	          //使能GPIO時鐘

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


    //初始化TIM4
    TIM_TimeBaseInitStructure.TIM_Period = arr;
    TIM_TimeBaseInitStructure.TIM_Prescaler = psc;
    TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM4, &TIM_TimeBaseInitStructure);

	//初始化TIM4_CH1  PWM 模式
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OC1Init(TIM4, &TIM_OCInitStructure);
	

    //初始化TIM4_CH2  PWM 模式
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OC2Init(TIM4, &TIM_OCInitStructure);

    //初始化TIM4_CH3  PWM 模式
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OC3Init(TIM4, &TIM_OCInitStructure);

    //初始化TIM4_CH4  PWM 模式
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OC4Init(TIM4, &TIM_OCInitStructure);

    //使能TIM4在CCR上的預裝載寄存器
    TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);
    TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable);
    TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);
    TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);

    //使能TIM4
    TIM_Cmd(TIM4, ENABLE);
}

設置方法和定時器2一樣,定時器4的4個通道對應的IO口爲PB6,PB7,PB8,PB9。將這四個口設置爲PWM輸出模式。

入口參數arr用來設置定時器的自動重裝載值,psc用於設置時鐘分頻係數。時鐘默認爲72MHZ。

這樣總共16路的PWM初始化就完成了,下來看主函數設置

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "pwm.h"

int main(void)
{
    u16 led_pwm_val = 0;

    delay_init();       //延時函數初始化
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
   
    //不分頻。PWM頻率=72000000/9000=8Khz
    TIM1_PWM_Init(8999, 0);
    TIM2_PWM_Init(8999, 0);
    TIM3_PWM_Init(8999, 0);
    TIM4_PWM_Init(8999, 0);
    led_pwm_val = 899;
    while(1)
    {
        if(led_pwm_val < 8999)
            led_pwm_val++;
        else
            led_pwm_val = 0;

        TIM_SetCompare1(TIM1, led_pwm_val);			    //TIM1_CH1    PA8
        TIM_SetCompare2(TIM1, led_pwm_val);				//TIM1_CH2    PA9
        TIM_SetCompare3(TIM1, led_pwm_val);				//TIM1_CH3    PA10
        TIM_SetCompare4(TIM1, led_pwm_val);				//TIM1_CH4    PA11

        TIM_SetCompare1(TIM2, led_pwm_val);				//TIM2_CH1	  PA0
        TIM_SetCompare2(TIM2, led_pwm_val);				//TIM2_CH2    PA1
        TIM_SetCompare3(TIM2, led_pwm_val);				//TIM2_CH3    PA2
        TIM_SetCompare4(TIM2, led_pwm_val);				//TIM2_CH4    PA3

        TIM_SetCompare1(TIM3, led_pwm_val);			   //TIM3_CH1	  PA6
        TIM_SetCompare2(TIM3, led_pwm_val);				//TIM3_CH2    PA7
        TIM_SetCompare3(TIM3, led_pwm_val);				//TIM3_CH3    PB0
        TIM_SetCompare4(TIM3, led_pwm_val);				//TIM3_CH4    PB1

        TIM_SetCompare1(TIM4, led_pwm_val);				//TIM4_CH1     PB6
        TIM_SetCompare2(TIM4, led_pwm_val);				//TIM4_CH2     PB7
        TIM_SetCompare3(TIM4, led_pwm_val);				//TIM4_CH3     PB8
        TIM_SetCompare4(TIM4, led_pwm_val);				//TIM4_CH4     PB9

        delay_ms(1);
    }
}

初始化時設置4個定時器的頻率爲8K,在while循環中調節佔空比從0---100%變化。程序編譯後燒寫到單片機中,通過示波器就能觀察到PWM波形變化了。

這裏先用軟件仿真看一下效果

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