pwm互補輸出 死區設置


 

void TIM8_PWM_Init(u16 arr,u16 psc)
{  
     GPIO_InitTypeDef GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    TIM_OCInitTypeDef  TIM_OCInitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
    TIM_BDTRInitTypeDef TIM_BDTRInitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);// 使能定時器時鍾
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOB , ENABLE);  //使能GPIO外設時鍾使能
                                                                             

   //設置該引腳為復用輸出功能,輸出TIM1 CH1的PWM脈沖波形
    GPIO_InitStructure.GPIO_Pin =GPIO_Pin_7; //TIM_CH2
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //復用推挽輸出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //TIM_CH2, 3  4
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //復用推挽輸出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    TIM_TimeBaseStructure.TIM_Period = arr; //設置在下一個更新事件裝入活動的自動重裝載寄存器周期的值     80K   
    TIM_TimeBaseStructure.TIM_Prescaler =psc; //設置用來作為TIMx時鍾頻率除數的預分頻值  不分頻
    TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設置時鍾分割:TDTS = Tck_tim
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上計數模式
    TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure); //根據TIM_TimeBaseInitStruct中指定的參數初始化TIMx的時間基數單位

**************************************************************************************************************************************************************************************************************
    

定時器1時鍾掛在APB2總線上,時鍾為72M   當TIM_ClockDivision = 0時,  Tdts = 1/72M = 13.89ns

****************************************************************************************************************************************************************************************************************
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //選擇定時器模式:TIM脈沖寬度調制模式2
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能
    TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;//互補輸出使能
    TIM_OCInitStructure.TIM_Pulse = 0; //設置待裝入捕獲比較寄存器的脈沖值
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//ocx高電平有效
    TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;//ocxn高電平有效 
    TIM_OC2Init(TIM8, &TIM_OCInitStructure);  //根據TIM_OCInitStruct中指定的參數初始化外設TIMx

**********************************************************************************************************************************************************************************************************************

CC1P:輸入/捕獲1輸出極性 (Capture/Compare 1 output polarity)
CC1通道配置為輸出:
0OC1高電平有效;
1OC1低電平有效。
CC1NP:輸入/捕獲1互補輸出極性 (Capture/Compare 1 complementary output polarity)
0OC1N高電平有效;
1OC1N低電平有效。


關於pwm模式1,2的區別可以看一看我的另一篇文章,有講過=》》https://www.cnblogs.com/caiya/articles/9267844.html

我這里兩個通道都是高電平有效

**********************************************************************************************************************************************************************************************************************
 
    TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
    TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1; //鎖定級別1  不能寫入TIMx_BDTR寄存器的DTG、 BKE、 BKP、 AOE位和TIMx_CR2寄存器的OISx/OISxN位;
    TIM_BDTRInitStructure.TIM_DeadTime  = 0x2B;        //死區時間為600ns
    TIM_BDTRInitStructure.TIM_Break     = TIM_Break_Disable;//禁止剎車輸入(不使能剎車功能)
    TIM_BDTRConfig(TIM8,&TIM_BDTRInitStructure);
   ******************************************************************************************************************************************************************************************************************

 

 

 

關於死區設置,這里我先解釋一下在說死區時間計算;

1死區:死區我通過示波器看,我理解是---

高電平有效時:

OCx輸出信號與參考信號相同,只是它的上升沿相對於參考信號的上升沿有一個延遲。
OCxN輸出信號與參考信號相反,只是它的上升沿相對於參考信號的下降沿有一個延遲。

低電平有效時:

OCx輸出信號與參考信號相同,只是它的下降沿相對於參考信號的下降沿有一個延遲。
OCxN輸出信號與參考信號相反,只是它的下降沿相對於參考信號的上升沿有一個延遲。

2剎車寄存器的設置:剎車源既可以是剎車輸入引腳又可以是一個時鍾失敗事件。時鍾失敗事件由復位時鍾控制器中的時鍾安全系統產生 。通過這段話我理解是剎車是出於安全考慮,才使用。
因為我只需要死區,並不考慮剎車,也就是我不需要剎車功能,所以我要禁止剎車輸入。

12 BKE: 剎車功能使能 (Break enable)
0:禁止剎車輸入(BRKCCS時鍾失效事件)
1:開啟剎車輸入(BRKCCS時鍾失效事件)

也因為我沒有使用剎車,所以剎車極性我也沒有必要設置。

13 BKP: 剎車輸入極性 (Break polarity)
0:剎車輸入低電平有效;
1:剎車輸入高電平有效。

因為我是通過軟件給MOE置1,所以AOE我也沒有必要設置,就默認0就好

14 AOE: 自動輸出使能 (Automatic output enable)
0MOE只能被軟件置’1’
1MOE能被軟件置’1’或在下一個更新事件被自動置’1’(如果剎車輸入無效)
15 MOE: 主輸出使能 (Main output enable)
一旦剎車輸入有效,該位被硬件異步清’0’。根據AOE位的設置值,該位可以由軟件清’0’或被自
動置1。它僅對配置為輸出的通道有效。
0:禁止OCOCN輸出或強制為空閑狀態;
1:如果設置了相應的使能位(TIMx_CCER寄存器的CCxECCxNE),則開啟OCOCN
出。


因為我沒有使用剎車,所以我的MOE應該不會變成0,所以上面的表75中,OSSI我沒有必要設置。

TIMx_CR2 寄存器中:

9 OIS1N:輸出空閑狀態1(OC1N輸出) (Output Idle state 1)
0:當MOE=0時,死區后OC1N=0
1:當MOE=0時,死區后OC1N=1
注:已經設置了LOCK(TIMx_BKR寄存器)級別123后,該位不能被修改。
8 OIS1:輸出空閑狀態1(OC1輸出) (Output Idle state 1)
0:當MOE=0時,如果實現了OC1N,則死區后OC1=0
1:當MOE=0時,如果實現了OC1N,則死區后OC1=1
注:已經設置了LOCK(TIMx_BKR寄存器)級別123后,該位不能被修改。

這些類似的地方我也沒有必要設置。

為什么我要把OSSR置1呢?

其實這個程序中我將OSSR給1或者0都是一樣的,因為從表75我們可以清楚的知道,ossr=0,則當CCXE,CCXNE=0時,兩個通道都將輸出0,而ossr=1時,CCXE,CCXNE=0時,兩個通道將輸出我們上面設置的CCXP/CCXNP的值,而這里我的這兩個對應位是0,所以效果一樣。但是我考慮到萬一我需要失能時輸出高電平的時候呢,萬一我關閉定時器pwm通道的時候我需要通道輸出的是高電平呢?所以我設置了此位為1.

2 CC1NE:輸入/捕獲1互補輸出使能 (Capture/Compare 1 complementary output enable)
0:關閉- OC1N禁止輸出,因此OC1N的電平依賴於MOEOSSIOSSROIS1OIS1N
CC1E位的值。
1:開啟- OC1N信號輸出到對應的輸出引腳,其輸出電平依賴於MOEOSSIOSSR
OIS1OIS1NCC1E位的值。


 

0 CC1E: 輸入/捕獲1輸出使能 (Capture/Compare 1 output enable)
CC1通道配置為輸出:
0: 關閉- OC1禁止輸出,因此OC1的輸出電平依賴於MOEOSSIOSSROIS1OIS1N
CC1NE位的值。
1: 開啟- OC1信號輸出到對應的輸出引腳,其輸出電平依賴於MOEOSSIOSSR
OIS1OIS1NCC1NE位的值。


至於鎖定嘛,看下面表格就知道了。

9:8 LOOK[1:0]: 鎖定設置 (Lock configuration)
該位為防止軟件錯誤而提供寫保護。
00:鎖定關閉,寄存器無寫保護;
01:鎖定級別1,不能寫入TIMx_BDTR寄存器的DTGBKEBKPAOE位和TIMx_CR2寄存
器的OISx/OISxN位;
10:鎖定級別2,不能寫入鎖定級別1中的各位,也不能寫入CC極性位(一旦相關通道通過
CCxS位設為輸出, CC極性位是TIMx_CCER寄存器的CCxP/CCNxP)以及OSSR/OSSI位;
11:鎖定級別3,不能寫入鎖定級別2中的各位,也不能寫入CC控制位(一旦相關通道通過
CCxS位設為輸出, CC控制位是TIMx_CCMRx寄存器的OCxM/OCxPE)
注:在系統復位后,只能寫一次LOCK位,一旦寫入TIMx_BDTR寄存器,則其內容凍結直至復
位。


我設置的時鎖定級別1.

 

3死區時間計算:

7:0 UTG[7:0]: 死區發生器設置 (Dead-time generator setup)
這些位定義了插入互補輸出之間的死區持續時間。假設DT表示其持續時間:
DTG[7:5]=0xx => DT=DTG[7:0] × TdtgTdtg = TDTS
DTG[7:5]=10x => DT=(64+DTG[5:0]) × TdtgTdtg = 2 × TDTS
DTG[7:5]=110 => DT=(32+DTG[4:0]) × TdtgTdtg = 8 × TDTS
DTG[7:5]=111 => DT=(32+DTG[4:0])× TdtgTdtg = 16 × TDTS
例:若TDTS = 125ns(8MHZ),可能的死區時間為:
015875ns,若步長時間為125ns
16us31750ns,若步長時間為250ns
32us63us,若步長時間為1us
64us126us,若步長時間為2us
注:一旦LOCK級別(TIMx_BDTR寄存器中的LOCK)設為123,則不能修改這些位。


舉例600ns怎么來的:0x2b=00101011,這明顯就是上面說的0xx型,所以時間=0x2b × Tdtg,上面我們設置始終分頻因子的時候就已經知道tdtg=13.89ns,所以我們可以算出DT就約等與600ns。

*********************************************************************************************************************************************************************************************************************
    
  TIM_OC2PreloadConfig(TIM8, TIM_OCPreload_Enable);  //CH2預裝載使能
    
    TIM_ClearFlag(TIM8, TIM_FLAG_Update);//清除中斷標志
    
    TIM_ITConfig(TIM8, TIM_IT_CC2/*TIM 輸入捕獲中斷源*/, ENABLE); //使能或者失能指定的TIM中斷
   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
   NVIC_InitStructure.NVIC_IRQChannel = TIM8_CC_IRQn;//TIM8捕捉比較中斷
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
   NVIC_Init(&NVIC_InitStructure);

  TIM_CtrlPWMOutputs(TIM8,ENABLE);    //MOE 主輸出使能    高級定時器需要這句   這個上面我粘貼了圖標的,往上翻一番就知道了
 
    
    TIM_ARRPreloadConfig(TIM8, ENABLE); //使能TIMx在ARR上的預裝載寄存器
    
    TIM_Cmd(TIM8, ENABLE);  //使能TIM8
   
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM