1. 程式人生 > >PWM of STM32

PWM of STM32

下面是STM32用來產生PWM得檔案,分別是PWM.c和PWM.h

/**************************************************************************
* 檔名:PWM.h                                                             *
* 編寫人:離逝的風                                                            *
* 更新時間:2018.12.9                                                        *
* 說明:此檔案屬於開源,所有權對任何人開放                                        *
* 如有問題請聯絡郵箱:
[email protected]
* * * * PWM是用定時器產生佔空比可調的波形,基本配置步驟如下: * * 1.開啟通道,即設定PWMx_CHy_EN為1即可 * * 2.設定通道引腳對映,下面表中有詳細說明,TIM1_PWM_CH * * 3.設定PWM分頻係數,TIM1_PWM_PSC * * 4.設定重灌值 TIM1_PWM_ARR * * 5.設定比較值 TIM1_CH1_CCR1 * * 6.在主函式中呼叫PWMx_CHy_Init來初始化通道 * * 說明:佔空比R=(ARR-CCRx)/ARR * **************************************************************************
*/ #ifndef __PWM_H #define __PWM_H #include "stm32f10x.h" /*#############################下面為PWM通道引腳定義############################################################### 說明:通道選擇 ------------------------------------------------------------------------------------------------------------------- TIM1_PWM_CH: [0] ETR->PA12 CH1->PA8 CH2->PA9 CH3->PA10 CH4->PA11 BKIN->PB12 CH1N->PB13 CH2N->PB14 CH3N->PB15 [1] ETR->PA12 CH1->PA8 CH2->PA9 CH3->PA10 CH4->PA11 BKIN->PA6 CH1N->PA7 CH2N->PB0 CH3N->PB1 [2] 未分組 [3] ETR->PE7 CH1->PE9 CH2->PE11 CH3->PE13 CH4->PE14 BKIN->PE15 CH1N->PE8 CH2N->PE10 CH3N->PE12 ------------------------------------------------------------------------------------------------------------------- TIM2_PWM_CH: [0] ETR->PA0 CH1->PA0 CH2->PA1 CH3->PA2 CH4->PA3 [1] ETR->PA15 CH1->PA15 CH2->PB3 CH3->PA2 CH4->PA3 [2] ETR->PA0 CH1->PA0 CH2->PA1 CH3->PB10 CH4->PB11 [3] ETR->PA15 CH1->PA15 CH2->PB3 CH3->PB10 CH4->PB11 ------------------------------------------------------------------------------------------------------------------- TIM3_PWM_CH: [0] CH1->PA6 CH2->PA7 CH3->PB0 CH4->PB1 [1] 未分組 [2] CH1->PB4 CH2->PB5 CH3->PB0 CH4->PB1 [3] CH1->PC6 CH2->PC7 CH3->PC8 CH4->PC9 ------------------------------------------------------------------------------------------------------------------- TIM4_PWM_CH: [0] CH1->PB6 CH2->PB7 CH3->PB8 CH4->PB9 [1] CH1->PD12 CH2->PD13 CH3->PD14 CH4->PD15 ------------------------------------------------------------------------------------------------------------------- TIM5_PWM_CH: [0] CH4->PA3 [1] CH4->LSI 注:LSI為內部時鐘震盪器 -------------------------------------------------------------------------------------------------------------------
*/ /**############################下面為檔案配置,根據用更改##########################################################**/ //開啟功能設定1,否則設定0 #define PWM1_CH1_EN 0 #define PWM1_CH2_EN 0 #define PWM1_CH3_EN 0 #define PWM1_CH4_EN 0 #define PWM2_CH1_EN 0 #define PWM2_CH2_EN 0 #define PWM2_CH3_EN 0 #define PWM2_CH4_EN 0 #define PWM3_CH1_EN 0 #define PWM3_CH2_EN 0 #define PWM3_CH3_EN 0 #define PWM3_CH4_EN 0 #define PWM4_CH1_EN 0 #define PWM4_CH2_EN 0 #define PWM4_CH3_EN 0 #define PWM4_CH4_EN 0 #define PWM5_CH4_EN 0 /*############################下面是引腳修改部分,預設0###########################################################*/ #define TIM1_PWM_CH 0 #define TIM2_PWM_CH 0 #define TIM3_PWM_CH 2 #define TIM4_PWM_CH 0 #define TIM5_PWM_CH 0 /***************************下面為預分頻器值,PSC********************************************************************/ //注:PSC的值決定PWM的時鐘頻率 #define TIM1_PWM_PSC 7199 #define TIM2_PWM_PSC 7199 #define TIM3_PWM_PSC 7199 #define TIM4_PWM_PSC 7199 #define TIM5_PWM_PSC 7199 /***************************下面為自動重灌值,ARR***************************************************************/ //注:ARR的值和CCRx值共同決定PWM的佔空比,佔空比R=(ARR-CCRx)/ARR #define TIM1_PWM_ARR 100 #define TIM2_PWM_ARR 100 #define TIM3_PWM_ARR 100 #define TIM4_PWM_ARR 100 #define TIM5_PWM_ARR 100 /**************************下面為捕獲比較暫存器值,CCRx*********************************************************/ //注:ARR的值和CCRx值共同決定PWM的佔空比,佔空比R=(ARR-CCRx)/ARR #define TIM1_CH1_CCR1 10 #define TIM1_CH2_CCR2 10 #define TIM1_CH3_CCR3 10 #define TIM1_CH4_CCR4 10 #define TIM2_CH1_CCR1 10 #define TIM2_CH2_CCR2 10 #define TIM2_CH3_CCR3 10 #define TIM2_CH4_CCR4 10 #define TIM3_CH1_CCR1 10 #define TIM3_CH2_CCR2 10 #define TIM3_CH3_CCR3 10 #define TIM3_CH4_CCR4 10 #define TIM4_CH1_CCR1 10 #define TIM4_CH2_CCR2 10 #define TIM4_CH3_CCR3 10 #define TIM4_CH4_CCR4 10 #define TIM5_CH4_CCR1 10 /*#############################下面為函式接,供使用者使用#########################################################*/ //備註:使用者可以直接PSC暫存器值來改變頻率 /*----------------------PWM1----------------------------------*/ #if(PWM1_CH1_EN==1) void PWM1_CH1_Init(void); #endif #if(PWM1_CH2_EN==1) void PWM1_CH2_Init(void); #endif #if(PWM1_CH3_EN==1) void PWM1_CH3_Init(void); #endif #if(PWM1_CH4_EN==1) void PWM1_CH4_Init(void); #endif /*----------------------PWM2----------------------------------*/ #if(PWM2_CH1_EN==1) void PWM2_CH1_Init(void); #endif #if(PWM2_CH2_EN==1) void PWM2_CH2_Init(void); #endif #if(PWM2_CH3_EN==1) void PWM2_CH3_Init(void); #endif #if(PWM2_CH4_EN==1) void PWM2_CH4_Init(void); #endif /*----------------------PWM3----------------------------------*/ #if(PWM3_CH1_EN==1) void PWM3_CH1_Init(void); #endif #if(PWM3_CH2_EN==1) void PWM3_CH2_Init(void); #endif #if(PWM3_CH3_EN==1) void PWM3_CH3_Init(void); #endif #if(PWM3_CH4_EN==1) void PWM3_CH4_Init(void); #endif /*----------------------PWM4----------------------------------*/ #if(PWM4_CH1_EN==1) void PWM4_CH1_Init(void); #endif #if(PWM4_CH2_EN==1) void PWM4_CH2_Init(void); #endif #if(PWM4_CH3_EN==1) void PWM4_CH3_Init(void); #endif #if(PWM4_CH4_EN==1) void PWM4_CH4_Init(void); #endif /*----------------------PWM5----------------------------------*/ #if(PWM5_CH4_EN==1) void PWM5_CH4_Init(void); #endif #endif //FILE END
/**************************************************************************
* 檔名:PWM.c                                                            *
* 編寫人:離逝的風                                                           *
* 更新時間:2018.12.9                                                       *
* 說明:此檔案屬於開源,所有權對任何人開放                                       *
* 如有問題請聯絡郵箱:[email protected]                                       *
*                                                                         *
* PWM是用定時器產生佔空比可調的波形,基本配置步驟如下:                            *
* 1.開啟通道,即設定PWMx_CHy_EN為1即可                                        *
* 2.設定通道引腳對映,下面表中有詳細說明,TIM1_PWM_CH                            *
* 3.設定PWM分頻係數,TIM1_PWM_PSC                                            *
* 4.設定重灌值  TIM1_PWM_ARR                                                *
* 5.設定比較值  TIM1_CH1_CCR1                                               *
* 6.在主函式中呼叫PWMx_CHy_Init來初始化通道                                    *
* 說明:佔空比R=(ARR-CCRx)/ARR                                               *
***************************************************************************/
#include  "PWM.h"


/*###############################下面為TIM1實現PWM##################################################*/
/*--------------------------------PWM_CH1-----------------------------------------------------------*/
#if(PWM1_CH1_EN==1)
void PWM1_CH1_Init(void)
{
    RCC->APB2ENR|=(1<<11);                          //開啟TIM1時鐘
    
    //下面為對映引腳配置
    #if(TIM1_PWM_CH==0||TIM1_PWM_CH==1)
      RCC->APB2ENR|=(1<<2)|(1<<0);                  //使能GPIOA和AFIO時鐘
      GPIOA->CRH&=0XFFFFFFF0;                       //清除PA8之前配置位
      GPIOA->CRH|=0X0000000B;                       //配置PA8為複用推輓輸出
    #endif
    
    #if(TIM1_PWM_CH==3)
      RCC->APB2ENR|=(1<<6)|(1<<0);                  //使能GPIOE和AFIO時鐘
      GPIOE->CRH&=0XFFFFFF0F;                       //清除PE9之前配置位
      GPIOE->CRH|=0X000000B0;                       //配置PE9為複用推輓輸出 
  #endif  
    //下面為暫存器配置
    AFIO->MAPR|=(TIM1_PWM_CH<<6);                  //定義引腳重對映,設定PWM1相應引腳
    
    TIM1->CR1|=(1<<7);                             //使能自動重灌暫存器
    
    TIM1->PSC|=(TIM1_PWM_PSC);                         //設定預分頻值
    TIM1->ARR&=0X00;                               //清除ARR之前配置
    TIM1->ARR|=TIM1_PWM_ARR;                           //設定ARR為TIM1_ARR
    
    TIM1->CCR1&=0x00;  
    TIM1->CCR1|=TIM1_CH1_CCR1;                     //設定翻轉週期計時長度

    TIM1->CCMR1|=(6<<4)|(1<<3);                    //使能CH1和設定CH1為模式1
    TIM1->CCER|=(1<<0);                            //CH1使能輸出
  TIM1->CR1|=(1<<0);                             //開始計數

}
#endif
/*-----------------------------PWM_CH2-------------------------------------------------------------------*/
#if(PWM1_CH2_EN==1)
void PWM1_CH2_Init(void)
{
    RCC->APB1ENR|=(1<<0);                          //開啟TIM1時鐘
    
    //下面為對映引腳配置
    #if(TIM1_PWM_CH==0||TIM1_PWM_CH==1)
      RCC->APB2ENR|=(1<<2)|(1<<0);                  //使能GPIOA和AFIO時鐘
      GPIOA->CRH&=0XFFFFFF0F;                       //清除PA9之前配置位
      GPIOA->CRH|=0X000000B0;                       //配置PA9為複用推輓輸出
  #endif
    
    #if(TIM1_PWM_CH==3)
      RCC->APB2ENR|=(1<<6)|(1<<0);                  //使能GPIOE和AFIO時鐘
      GPIOE->CRH&=0XFFFF0FFF;                       //清除PE11之前配置位
      GPIOE->CRH|=0X0000B000;                       //配置PE11為複用推輓輸出
    #endif
    //下面為暫存器配置
    AFIO->MAPR|=(TIM1_PWM_CH<<6);                  //定義引腳重對映,設定PWM1相應引腳
    
    TIM1->CR1|=(1<<7);                             //使能自動重灌暫存器
    
    TIM1->PSC|=(TIM1_PWM_PSC);                         //設定預分頻值
    TIM1->ARR&=0X00;                               //清除ARR之前配置
    TIM1->ARR|=TIM1_PWM_ARR;                           //設定ARR為TIM1_ARR
    
    TIM1->CCR2&=0x00;  
    TIM1->CCR2|=TIM1_CH2_CCR2;                      //設定翻轉週期計時長度

    TIM1->CCMR1|=(6<<12)|(1<<11);                   //使能CH2和設定CH2為模式1
    TIM1->CCER|=(1<<4);                             //CH2使能輸出
  TIM1->CR1|=(1<<0);                              //開始計數

}
#endif
/*-----------------------------PWM_CH3-------------------------------------------------------------------*/
#if(PWM1_CH3_EN==1)
void PWM1_CH3_Init(void)
{
    RCC->APB2ENR|=(1<<11);                          //開啟TIM1時鐘
    
    //下面為對映引腳配置
    #if(TIM1_PWM_CH==0||TIM1_PWM_CH==1)
      RCC->APB2ENR|=(1<<2)|(1<<0);                  //使能GPIOA和AFIO時鐘
      GPIOA->CRH&=0XFFFFF0FF;                       //清除PA10之前配置位
      GPIOA->CRH|=0X00000B00;                       //配置PA10為複用推輓輸出
    #endif
    #if(TIM1_PWM_CH==3)
      RCC->APB2ENR|=(1<<6)|(1<<0);                  //使能GPIOE和AFIO時鐘
      GPIOE->CRH&=0XFF0FFFFF;                       //清除PE13之前配置位
      GPIOE->CRH|=0X00B00000;                       //配置PE13為複用推輓輸出
    #endif
    //下面為暫存器配置
    AFIO->MAPR|=(TIM1_PWM_CH<<6);                 //定義引腳重對映,設定PWM1相應引腳
    
    TIM1->CR1|=(1<<7);                             //使能自動重灌暫存器
    
    TIM1->PSC|=(TIM1_PWM_PSC);                         //設定預分頻值
    TIM1->ARR&=0X00;                               //清除ARR之前配置
    TIM1->ARR|=TIM1_PWM_ARR;                           //設定ARR為TIM1_ARR
    
    TIM1->CCR3&=0x00;  
    TIM1->CCR3|=TIM1_CH3_CCR3;                     //設定翻轉週期計時長度

    TIM1->CCMR2|=(6<<4)|(1<<3);                    //使能CH3和設定CH3為模式1
    TIM1->CCER|=(1<<8);                            //CH3使能輸出
  TIM1->CR1|=(1<<0);                             //開始計數

}
#endif
/*-----------------------------PWM_CH4-------------------------------------------------------------------*/
#if(PWM1_CH4_EN==1)
void PWM1_CH4_Init(void)
{
        RCC->APB2ENR|=(1<<11);                          //開啟TIM1時鐘
    
    //下面為對映引腳配置
    #if(TIM1_PWM_CH==0||TIM1_PWM_CH==1)
      RCC->APB2ENR|=(1<<2)|(1<<0);                  //使能GPIOA和AFIO時鐘
      GPIOA->CRH&=0XFFFF0FFF;                       //清除PA11之前配置位
      GPIOA->CRH|=0X0000B000;                       //配置PA11為複用推輓輸出
    #endif
    
    #if(TIM1_PWM_CH==3)
      RCC->APB2ENR|=(1<<6)|(1<<0);                  //使能GPIOE和AFIO時鐘
      GPIOE->CRH&=0XF0FFFFFF;                       //清除PE14之前配置位
      GPIOE->CRH|=0X0B000000;                       //配置PE14為複用推輓輸出
    #endif
    //下面為暫存器配置
    AFIO->MAPR|=(TIM1_PWM_CH<<6);                  //定義引腳重對映,設定PWM1相應引腳
    
    TIM1->CR1|=(1<<7);                              //使能自動重灌暫存器
    
    TIM1->PSC|=(TIM1_PWM_PSC);                         //設定預分頻值
    TIM1->ARR&=0X00;                               //清除ARR之前配置
    TIM1->ARR|=TIM1_PWM_ARR;                           //設定ARR為TIM1_ARR
    
    TIM1->CCR4&=0x00;  
    TIM1->CCR4|=TIM1_CH4_CCR4;                     //設定翻轉週期計時長度

    TIM1->CCMR2|=(6<<12)|(1<<11);                    //使能CH3和設定CH3為模式1
    TIM1->CCER|=(1<<12);                            //CH3使能輸出
  TIM1->CR1|=(1<<0);                             //開始計數

}
#endif
/*###############################下面為TIM2實現PWM##################################################*/
/*--------------------------------PWM_CH1-----------------------------------------------------------*/
#if(PWM2_CH1_EN==1)
void PWM2_CH1_Init(void)
{
    RCC->APB1ENR|=(1<<0);                          //開啟TIM2時鐘
    
    //下面為對映引腳配置
    #if(TIM2_PWM_CH==0||TIM2_PWM_CH==2)
      RCC->APB2ENR|=(1<<2)|(1<<0);                  //使能GPIOA和AFIO時鐘
      GPIOA->CRL&=0XFFFFFFF0;                       //清除PA0之前配置位
      GPIOA->CRL|=0X0000000B;                       //配置PA0為複用推輓輸出
    #endif
    
    #if(TIM2_PWM_CH==1||TIM2_PWM_CH==3)
      RCC->APB2ENR|=(1<<2)|(1<<0);                  //使能GPIOA和AFIO時鐘
      GPIOA->CRH&=0X0FFFFFFF;                       //清除PA15之前配置位
      GPIOA->CRH|=0XB0000000;                       //配置P15為複用推輓輸出   
    #endif
    //下面為暫存器配置
    AFIO->MAPR|=(TIM2_PWM_CH<<8);                  //定義引腳重對映,設定PWM2相應引腳
    
    TIM2->CR1|=(1<<7);                             //使能自動重灌暫存器
    
    TIM2->PSC|=(TIM2_PWM_PSC);                         //設定預分頻值
    TIM2->ARR&=0X00;                               //清除ARR之前配置
    TIM2->ARR|=TIM2_PWM_ARR;                           //設定ARR為TIM1_ARR
    
    TIM2->CCR1&=0x00;  
    TIM2->CCR1|=TIM2_CH1_CCR1;                     //設定翻轉週期計時長度

    TIM2->CCMR1|=(6<<4)|(1<<3);                    //使能CH1和設定CH1為模式1
    TIM2->CCER|=(1<<0);                            //CH1使能輸出
  TIM2->CR1|=(1<<0);                             //開始計數

}
#endif
/*-----------------------------PWM_CH2-------------------------------------------------------------------*/
#if(PWM2_CH2_EN==1)
void PWM2_CH2_Init(void)
{
    RCC->APB1ENR|=(1<<0);                          //開啟TIM2時鐘
    
    //下面為對映引腳配置
    #if(TIM2_PWM_CH==0||TIM2_PWM_CH==2)
      RCC->APB2ENR|=(1<<2)|(1<<0);                  //使能GPIOA和AFIO時鐘
      GPIOA->CRL&=0XFFFFFF0F;                       //清除PA1之前配置位
      GPIOA->CRL|=0X000000B0;                       //配置PA1為複用推輓輸出
    #endif
    
    #if(TIM2_PWM_CH==1||TIM2_PWM_CH==3)
      RCC->APB2ENR|=(1<<3)|(1<<0);                  //使能GPIOB和AFIO時鐘
      GPIOB->CRL&=0XFFFF0FFF;                       //清除PB3之前配置位
      GPIOB->CRL|=0X0000B000;                       //配置PB3為複用推輓輸出
    #endif
    //下面為暫存器配置
    AFIO->MAPR|=(TIM2_PWM_CH<<8);                  //定義引腳重對映,設定PWM2相應引腳
    
    TIM2->CR1|=(1<<7);                             //使能自動重灌暫存器
    
    TIM2->PSC|=(TIM2_PWM_PSC);                         //設定預分頻值
    TIM2->ARR&=0X00;                               //清除ARR之前配置
    TIM2->ARR|=TIM2_PWM_ARR;                           //設定ARR為TIM1_ARR
    
    TIM2->CCR2&=0x00;  
    TIM2->CCR2|=TIM2_CH2_CCR2;                      //設定翻轉週期計時長度

    TIM2->CCMR1|=(6<<12)|(1<<11);                   //使能CH2和設定CH2為模式1
    TIM2->CCER|=(1<<4);                             //CH2使能輸出
  TIM2->CR1|=(1<<0);                              //開始計數

}
#endif
/*-----------------------------PWM_CH3-------------------------------------------------------------------*/
#if(PWM2_CH3_EN==1)
void PWM2_CH3_Init(void)
{
    RCC->APB1ENR|=(1<<0);                          //開啟TIM2時鐘
    
    //下面為對映引腳配置
    #if(TIM2_PWM_CH==0||TIM2_PWM_CH==1)
      RCC->APB2ENR|=(1<<2)|(1<<0);                  //使能GPIOA和AFIO時鐘
      GPIOA->CRH&=0XFFFFF0FF;                       //清除PA2之前配置位
      GPIOA->CRH|=0X00000B00;                       //配置PA2為複用推輓輸出
    #endif
    
    #if(TIM2_PWM_CH==2||TIM2_PWM_CH==3)
      RCC->APB2ENR|=(1<<3)|(1<<0);                  //使能GPIOB和AFIO時鐘
      GPIOB->CRH&=0XFFFFF0FF;                       //清除PB10之前配置位
      GPIOB->CRH|=0X00000B00;                       //配置PB10為複用推輓輸出
    #endif
    //下面為暫存器配置
    AFIO->MAPR|=(TIM2_PWM_CH<<8);                 //定義引腳重對映,設定PWM2相應引腳
    
    TIM2->CR1|=(1<<7);                             //使能自動重灌暫存器
    
    TIM2->PSC|=(TIM2_PWM_PSC);                         //設定預分頻值
    TIM2->ARR&=0X00;                               //清除ARR之前配置
    TIM2->ARR|=TIM2_PWM_ARR;                           //設定ARR為TIM1_ARR
    
    TIM2->CCR3&=0x00;  
    TIM2->CCR3|=TIM2_CH3_CCR3;                     //設定翻轉週期計時長度

    TIM2->CCMR2|=(6<<4)|(1<<3);                    //使能CH3和設定CH3為模式1
    TIM2->CCER|=(1<<8);                            //CH3使能輸出
  TIM2->CR1|=(1<<0);                             //開始計數

}
#endif
/*-----------------------------PWM_CH4-------------------------------------------------------------------*/
#if(PWM2_CH4_EN==1)
void PWM2_CH4_Init(void)
{
        RCC->APB1ENR|=(1<<0);                          //開啟TIM2時鐘
    
    //下面為對映引腳配置
    #if(TIM2_PWM_CH==0||TIM2_PWM_CH==1)
      RCC->APB2ENR|=(1<<2)|(1<<0);                  //使能GPIOA和AFIO時鐘
      GPIOA->CRL&=0XFFFF0FFF;                       //清除PA3之前配置位
      GPIOA->CRL|=0X0000B000;                       //配置PA3為複用推輓輸出
    #endif
    
    #if(TIM2_PWM_CH==2||TIM2_PWM_CH==3)
      RCC->APB2ENR|=(1<<3)|(1<<0);                  //使能GPIOB和AFIO時鐘
      GPIOB->CRH&=0XFFFF0FFF;                       //清除PB11之前配置位
      GPIOB->CRH|=0X0000B000;                       //配置PB11為複用推輓輸出
    #endif
    //下面為暫存器配置
    AFIO->MAPR|=(TIM2_PWM_CH<<6);                  //定義引腳重對映,設定PWM2相應引腳
    
    TIM2->CR1|=(1<<7);                              //使能自動重灌暫存器
    
    TIM2->PSC|=(TIM2_PWM_PSC);                         //設定預分頻值
    TIM2->ARR&=0X00;                               //清除ARR之前配置
    TIM2->ARR|=TIM2_PWM_ARR;                           //設定ARR為TIM1_ARR
    
    TIM2->CCR4&=0x00;  
    TIM2->CCR4|=TIM2_CH4_CCR4;                     //設定翻轉週期計時長度

    TIM2->CCMR2|=(6<<12)|(1<<11);                    //使能CH3和設定CH3為模式1
    TIM2->CCER|=(1<<12);                            //CH3使能輸出
  TIM2->CR1|=(1<<0);                             //開始計數
}
#endif
/*###############################下面為TIM3實現PWM##################################################*/
/*--------------------------------PWM_CH1-----------------------------------------------------------*/
#if(PWM3_CH1_EN==1)
void PWM3_CH1_Init(void)
{
    RCC->APB1ENR|=(1<<1);                          //開啟TIM3時鐘
    
    //下面為對映引腳配置
    #if(TIM3_PWM_CH==0)
      RCC->APB2ENR|=(1<<2)|(1<<0);                  //使能GPIOA和AFIO時鐘
      GPIOA->CRL&=0XF0FFFFFF;                       //清除PA6之前配置位
      GPIOA->CRL|=0X0B000000;                       //配置PA6為複用推輓輸出
    #endif
    
    #if(TIM3_PWM_CH==2)
      RCC->APB2ENR|=(1<<3)|(1<<0);                  //使能GPIOB和AFIO時鐘
      GPIOB->CRL&=0XFFF0FFFF;                       //清除PB4之前配置位
      GPIOB->CRL|=0X000B0000;                       //配置PB4為複用推輓輸出  
  #endif
    
    #if(TIM3_PWM_CH==3)
      RCC->APB2ENR|=(1<<4)|(1<<0);                  //使能GPIOC和AFIO時鐘
      GPIOC->CRL&=0XF0FFFFFF;                       //清除PC6之前配置位
      GPIOC->CRL|=0X0B000000;                       //配置PC6為複用推輓輸出   
    #endif
    //下面為暫存器配置
    AFIO->MAPR|=(TIM3_PWM_CH<<10);                  //定義引腳重對映,設定PWM3相應引腳
    
    TIM3->CR1|=(1<<7);                             //使能自動重灌暫存器
    
    TIM3->PSC|=(TIM3_PWM_PSC);                         //設定預分頻值
    TIM3->ARR&=0X00;                               //清除ARR之前配置
    TIM3->ARR|=TIM3_PWM_ARR;                           //設定ARR為TIM1_ARR
    
    TIM3->CCR1&=0x00;  
    TIM3->CCR1|=TIM3_CH1_CCR1;                     //設定翻轉週期計時長度

    TIM3->CCMR1|=(6<<4)|(1<<3);                    //使能CH1和設定CH1為模式1
    TIM3->CCER|=(1<<0);                            //CH1使能輸出
  TIM3->CR1|=(1<<0);                             //開始計數

}
#endif
/*-----------------------------PWM_CH2-------------------------------------------------------------------*/
#if(PWM3_CH2_EN==1)
void PWM3_CH2_Init(void)
{
    RCC->APB1ENR|=(1<<1);                          //開啟TIM3時鐘
    
    //下面為對映引腳配置
    #if(TIM3_PWM_CH==0)
      RCC->APB2ENR|=(1<<2)|(1<<0);                  //使能GPIOA和AFIO時鐘
      GPIOA->CRL&=0X0FFFFFFF;                       //清除PA7之前配置位
      GPIOA->CRL|=0XB0000000;                       //配置PA7為複用推輓輸出
  #endif
    
    #if(TIM3_PWM_CH==2)
      RCC->APB2ENR|=(1<<3)|(1<<0);                  //使能GPIOB和AFIO時鐘
      GPIOB->CRL&=0XFF0FFFFF;                       //清除PB5之前配置位
      GPIOB->CRL|=0X00B00000;                       //配置PB5為複用推輓輸出
  #endif
    //下面為暫存器配置
    AFIO->MAPR|=(TIM3_PWM_CH<<10);                  //定義引腳重對映,設定PWM3相應引腳
    
    TIM3->CR1|=(1<<7);                             //使能自動重灌暫存器
    
    TIM3->PSC|=(TIM3_PWM_PSC);                         //設定預分頻值
    TIM3->ARR&=0X00;                               //清除ARR之前配置
    TIM3->ARR|=TIM3_PWM_ARR;                           //設定ARR為TIM3_ARR
    
    TIM3->CCR2&=0x00;  
    TIM3->CCR2|=TIM3_CH2_CCR2;                      //設定翻轉週期計時長度

    TIM3->CCMR1|=(6<<12)|(1<<11);                   //使能CH2和設定CH2為模式1
    TIM3->CCER|=(1<<4);                             //CH2使能輸出
  TIM3->CR1|=(1<<0);                              //開始計數

}
#endif
/*-----------------------------PWM_CH3-------------------------------------------------------------------*/
#if(PWM3_CH3_EN==1)
void PWM3_CH3_Init(void)
{
    RCC->APB1ENR|=(1<<1);                          //開啟TIM3時鐘
    
    //下面為對映引腳配置
    #if(TIM3_PWM_CH==0||TIM3_PWM_CH==2)
      RCC->APB2ENR|=(1<<3)|(1<<0);                  //使能GPIOB和AFIO時鐘
      GPIOB->CRL&=0XFFFFFFF0;                       //清除PB0之前配置位
      GPIOB->CRL|=0X0000000B;                       //配置PB0為複用推輓輸出
    #endif
    
    #if(TIM2_PWM_CH==3)
      RCC->APB2ENR|=(1<<4)|(1<<0);                  //使能GPIOC和AFIO時鐘
      GPIOC->CRH&=0XFFFFFFF0;                       //清除PC8之前配置位
      GPIOC->CRH|=0X0000000B;                       //配置PC8為複用推輓輸出
    #endif
    //下面為暫存器配置
    AFIO->MAPR|=(TIM3_PWM_CH<<10);                 //定義引腳重對映,設定PWM3相應引腳
    
    TIM3->CR1|=(1<<7);                             //使能自動重灌暫存器
    
    TIM3->PSC|=(TIM3_PWM_PSC);                         //設定預分頻值
    TIM3->ARR&=0X00;                               //清除ARR之前配置
    TIM3->ARR|=TIM3_PWM_ARR;                           //設定ARR為TIM3_ARR
    
    TIM3->CCR3&=0x00;  
    TIM3->CCR3|=TIM3_CH3_CCR3;                     //設定翻轉週期計時長度

    TIM3->CCMR2|=(6<<4)|(1<<3);                    //使能CH3和設定CH3為模式1
    TIM3->CCER|=(1<<8);                            //CH3使能輸出
  TIM3->CR1|=(1<<0);                             //開始計數

}
#endif
/*-----------------------------PWM_CH4-------------------------------------------------------------------*/
#if(PWM3_CH4_EN==1)
void PWM3_CH4_Init(void)
{
        RCC->APB1ENR|=(1<<1);                          //開啟TIM3時鐘
    
    //下面為對映引腳配置
    #if(TIM3_PWM_CH==0||TIM3_PWM_CH==2)
      RCC->APB2ENR|=(1<<3)|(1<<0);                  //使能GPIOB和AFIO時鐘
      GPIOB->CRL&=0XFFFFFF0F;                       //清除PB1之前配置位
      GPIOB->CRL|=0X000000B0;                       //配置PB1為複用推輓輸出
    #endif
    
    #if(TIM3_PWM_CH==3)
      RCC->APB2ENR|=(1<<4)|(1<<0);                  //使能GPIOC和AFIO時鐘
      GPIOC->CRH&=0XFFFFFF0F;                       //清除PC9之前配置位
      GPIOC->CRH|=0X000000B0;                       //配置PC9為複用推輓輸出
  #endif
    //下面為暫存器配置
    AFIO->MAPR|=(TIM3_PWM_CH<<6);                  //定義引腳重對映,設定PWM3相應引腳
    
    TIM3->CR1|=(1<<7);                              //使能自動重灌暫存器
    
    TIM3->PSC|=(TIM3_PWM_PSC);                         //設定預分頻值
    TIM3->ARR&=0X00;                               //清除ARR之前配置
    TIM3->ARR|=TIM3_PWM_ARR;                           //設定ARR為TIM3_ARR
    
    TIM3->CCR4&=0x00;  
    TIM3->CCR4|=TIM3_CH4_CCR4;                     //設定翻轉週期計時長度

    TIM3->CCMR2|=(6<<12)|(1<<11);                    //使能CH3和設定CH3為模式1
    TIM3->CCER|=(1<<12);                            //CH3使能輸出
  TIM3->CR1|=(1<<0);                             //開始計數
}
#endif

/*###############################下面為TIM4實現PWM##################################################*/
/*--------------------------------PWM_CH1-----------------------------------------------------------*/
#if(PWM4_CH1_EN==1)
void PWM4_CH1_Init(void)
{
    RCC->APB1ENR|=(1<<2);                           //開啟TIM4時鐘
    
    //下面為對映引腳配置
    #if(TIM4_PWM_CH==0)
      RCC->APB2ENR|=(1<<3)|(1<<0);                  //使能GPIOB和AFIO時鐘
      GPIOB->CRL&=0XF0FFFFFF;                       //清除PB6之前配置位
      GPIOB->CRL|=0X0B000000;                       //配置PB6為複用推輓輸出
    #endif
    
    #if(TIM4_PWM_CH==1)
      RCC->APB2ENR|=(1<<5)|(1<<0);                  //使能GPIOD和AFIO時鐘
      GPIOD->CRH&=0XFFF0FFFF;                       //清除PD12之前配置位
      GPIOD->CRH|=0X000B0000;                       //配置PD12為複用推輓輸出   
  #endif
    
    //下面為暫存器配置
    AFIO->MAPR|=(TIM4_PWM_CH<<12);                  //定義引腳重對映,設定PWM4相應引腳
    
    TIM4->CR1|=(1<<7);                             //使能自動重灌暫存器
    
    TIM4->PSC|=(TIM4_PWM_PSC);                         //設定預分頻值
    TIM4->ARR&=0X00;                               //清除ARR之前配置
    TIM4->ARR|=TIM4_PWM_ARR;                           //設定ARR為TIM4_ARR
    
    TIM4->CCR1&=0x00;  
    TIM4->CCR1|=TIM4_CH1_CCR1;                     //設定翻轉週期計時長度

    TIM4->CCMR1|=(6<<4)|(1<<3);                    //使能CH1和設定CH1為模式1
    TIM4->CCER|=(1<<0);                            //CH1使能輸出
  TIM4->CR1|=(1<<0);                             //開始計數

}
#endif
/*-----------------------------PWM_CH2-------------------------------------------------------------------*/
#if(PWM4_CH2_EN==1)
void PWM4_CH2_Init(void)
{
    RCC->APB1ENR|=(1<<2);                           //開啟TIM1時鐘
    
    //下面為對映引腳配置
    #if(TIM4_PWM_CH==0)
      RCC->APB2ENR|=(1<<3)|(1<<0);                  //使能GPIOB和AFIO時鐘
      GPIOB->CRL&=0X0FFFFFFF;                       //清除PB7之前配置位
      GPIOB->CRL|=0XB0000000;                       //配置PB7為複用推輓輸出
    #endif
    
    #if(TIM4_PWM_CH==1)
      RCC->APB2ENR|=(1<<5)|(1<<0);                  //使能GPIOD和AFIO時鐘
      GPIOD->CRH&=0XFF0FFFFF;                       //清除PD13之前配置位
      GPIOD->CRH|=0X00B00000;                       //配置PD13為複用推輓輸出
    #endif
    //下面為暫存器配置
    AFIO->MAPR|=(TIM4_PWM_CH<<12);                  //定義引腳重對映,設定PWM4相應引腳
    
    TIM4->CR1|=(1<<7);                             //使能自動重灌暫存器
    
    TIM4->PSC|=(TIM4_PWM_PSC);                         //設定預分頻值
    TIM4->ARR&=0X00;                               //清除ARR之前配置
    TIM4->ARR|=TIM4_PWM_ARR;                           //設定ARR為TIM4_ARR
    
    TIM4->CCR2&=0x00;  
    TIM4->CCR2|=TIM4_CH2_CCR2;                      //設定翻轉週期計時長度

    TIM4->CCMR1|=(6<<12)|(1<<11);                   //使能CH2和設定CH2為模式1
    TIM4->CCER|=(1<<4);                             //CH2使能輸出
  TIM4->CR1|=(1<<0);                              //開始計數

}
#endif
/*-----------------------------PWM_CH3-------------------------------------------------------------------*/
#if(PWM4_CH3_EN==1)
void PWM4_CH3_Init(void)
{
    RCC->APB1ENR|=(1<<2);                          //開啟TIM4時鐘
    
    //下面為對映引腳配置
    #if(TIM4_PWM_CH==0)
      RCC->APB2ENR|=(1<<3)|(1<<0);                  //使能GPIOB和AFIO時鐘
      GPIOB->CRH&=0XFFFFFFF0;                       //清除PB8之前配置位
      GPIOB->CRH|=0X0000000B;                       //配置PB8為複用推輓輸出
    #endif
    
    #if(TIM4_PWM_CH==1)
      RCC->APB2ENR|=(1<<5)|(1<<0);                  //使能GPIOC和AFIO時鐘
      GPIOD->CRH&=0XF0FFFFFF;                       //清除PD14之前配置位
      GPIOD->CRH|=0X0B00000F;                       //配置PD14為複用推輓輸出
    #endif
    //下面為暫存器配置
    AFIO->MAPR|=(TIM4_PWM_CH<<12);                 //定義引腳重對映,設定PWM4相應引腳
    
    TIM4->CR1|=(1<<7);                             //使能自動重灌暫存器
    
    TIM4->PSC|=(TIM4_PWM_PSC);                         //設定預分頻值
    TIM4->ARR&=0X00;                               //清除ARR之前配置
    TIM4->ARR|=TIM4_PWM_ARR;                           //設定ARR為TIM4_ARR
    
    TIM4->CCR3&=0x00;  
    TIM4->CCR3|=TIM4_CH3_CCR3;                     //設定翻轉週期計時長度

    TIM4->CCMR2|=(6<<4)|(1<<3);                    //使能CH3和設定CH3為模式1
    TIM4->CCER|=(1<<8);                            //CH3使能輸出
  TIM4->CR1|=(1<<0);                             //開始計數

}
#endif
/*-----------------------------PWM_CH4-------------------------------------------------------------------*/
#if(PWM4_CH4_EN==1)
void PWM4_CH4_Init(void)
{
        RCC->APB1ENR|=(1<<2);                          //開啟TIM4時鐘
    
    //下面為對映引腳配置
    #if(TIM3_PWM_CH==0)
      RCC->APB2ENR|=(1<<3)|(1<<0);                  //使能GPIOB和AFIO時鐘
      GPIOB->CRH&=0XFFFFFF0F;                       //清除PB9之前配置位
      GPIOB->CRH|=0X000000B0;                       //配置PB9為複用推輓輸出
    #endif
    
    #if(TIM4_PWM_CH==1)
      RCC->APB2ENR|=(1<<5)|(1<<0);                  //使能GPIOD和AFIO時鐘
      GPIOD->CRH&=0X0FFFFFFF;                       //清除PD15之前配置位
      GPIOD->CRH|=0XB0000000;                       //配置PD15為複用推輓輸出
    #endif
    //下面為暫存器配置
    AFIO->MAPR|=(TIM4_PWM_CH<<12);                  //定義引腳重對映,設定PWM4相應引腳
    
    TIM4->CR1|=(1<<7);                              //使能自動重灌暫存器
    
    TIM4->PSC|=(TIM4_PWM_PSC);                         //設定預分頻值
    TIM4->ARR&=0X00;                               //清除ARR之前配置
    TIM4->ARR|=TIM4_PWM_ARR;                           //設定ARR為TIM4_ARR
    
    TIM4->CCR4&=0x00;  
    TIM4->CCR4|=TIM4_CH4_CCR4;                     //設定翻轉週期計時長度

    TIM4->CCMR2|=(6<<12)|(1<<11);                    //使能CH4和設定CH4為模式1
    TIM4->CCER|=(1<<12);                            //CH4使能輸出
  TIM4->CR1|=(1<<0);                             //開始計數
}
#endif
/*###############################下面為TIM5實現PWM##################################################*/
/*--------------------------------PWM_CH4-----------------------------------------------------------*/
#if(PWM5_CH4_EN==1)
void PWM5_CH4_Init(void)
{
    RCC->APB1ENR|=(1<<3);                           //開啟TIM5時鐘
    
    //下面為對映引腳配置
    #if(TIM5_PWM_CH==0)
      RCC->APB2ENR|=(1<<2)|(1<<0);                  //使能GPIOA和AFIO時鐘
      GPIOA->CRL&=0XFFFF0FFF;                       //清除PA3之前配置位
      GPIOA->CRL|=0X0B00B000;                       //配置PA3為複用推輓輸出
    #endif

    //下面為暫存器配置
    AFIO->MAPR|=(TIM5_PWM_CH<<16);                  //定義引腳重對映,設定PWM5相應引腳
    
    TIM5->CR1|=(1<<7);                             //使能自動重灌暫存器
    
    TIM5->PSC|=(TIM5_PWM_PSC);                         //設定預分頻值
    TIM5->ARR&=0X00;                               //清除ARR之前配置
    TIM5->ARR|=TIM5_PWM_ARR;                           //設定ARR為TIM5_ARR
    
    TIM5->CCR1&=0x00;  
    TIM5->CCR1|=TIM5_CH4_CCR1;                     //設定翻轉週期計時長度

    TIM5->CCMR2|=(6<<12)|(1<<11);                    //使能CH4和設定CH4為模式1
    TIM5->CCER|=(1<<12);                            //CH4使能輸出
  TIM5->CR1|=(1<<0);                             //開始計數
}

#endif

//FILE END