測試環境:Keil 5.20.0.0 STM32F103RBT6 固件庫版本:STM32F10x_StdPeriph_Lib_V3.5.0(2011) 本文使用TIM1的通道1,通道2,產生兩路1khz,死區時間1us的互補PWM波。 所使用的IO口:由下圖知,我們使用引腳為PA9,PA10,互補輸 ...
測試環境:Keil 5.20.0.0 STM32F103RBT6 固件庫版本:STM32F10x_StdPeriph_Lib_V3.5.0(2011)
本文使用TIM1的通道1,通道2,產生兩路1khz,死區時間1us的互補PWM波。
所使用的IO口:由下圖知,我們使用引腳為PA9,PA10,互補輸出使用PB14,PB15
部分代碼如下:
1 /* 配置TIM1復用輸出PWM時用到的I/O */ 2 static void TIM1_GPIO_Config(void) 3 { 4 GPIO_InitTypeDef GPIO_InitStructure; 5 6 /* TIM1 clock enable */ 7 RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); 8 9 /* GPIOA and GPIOB clock enable */ 10 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE); 11 12 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; 13 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 14 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 15 16 GPIO_Init(GPIOA, &GPIO_InitStructure); 17 18 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14 | GPIO_Pin_15; 19 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 20 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 21 22 GPIO_Init(GPIOB, &GPIO_InitStructure); 23 24 }初始化IO
初始化定時器功能配置
1 u16 CCR2_Val = 500; 2 u16 CCR3_Val = 500;//占空比,周期為1000 3 4 /*配置TIM1輸出的PWM信號的模式,如周期、極性、占空比 */ 5 void TIM1_Mode_Config(void) 6 { 7 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; 8 TIM_BDTRInitTypeDef TIM1_BDTRInitStruct; 9 TIM_OCInitTypeDef TIM_OCInitStructure; 10 11 /* Time base configuration */ 12 TIM_TimeBaseStructure.TIM_Period = 1000-1; //計數周期,向上記到此數,計數值清零 13 TIM_TimeBaseStructure.TIM_Prescaler = 72-1;//定時器分頻繫數,Ftimer = 72M/(TIM_Prescaler+1) = 1ms 14 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//與死區時間分頻有關 15 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上計數模式 16 TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); 17 18 /****** 配置BDTR寄存器,配置死區時間****************/ 19 /* 20 定時器時鐘 72M TIM_ClockDivision = TIM_CKD_DIV1時, Tdts = 13.89ns 21 0 - 1.764us 用演算法一 22 1.778us - 3.505us 用演算法二 23 3.556us - 7.000us 用演算法三 24 7.1117us - 14us 用演算法四 25 需要更長時間,使用TIM_ClockDivision分頻 26 */ 27 TIM1_BDTRInitStruct.TIM_OSSRState = TIM_OSSRState_Disable; 28 TIM1_BDTRInitStruct.TIM_OSSIState = TIM_OSSIState_Disable; 29 TIM1_BDTRInitStruct.TIM_LOCKLevel = TIM_LOCKLevel_OFF; 30 TIM1_BDTRInitStruct.TIM_DeadTime = 205; //死區時間 72:1us 172:3us 205:5us 31 TIM_BDTRConfig(TIM1,&TIM1_BDTRInitStruct); 32 33 // TIM1->BDTR |= 72; //設置死區 註:上面那種方法也可以,這種快且簡單 34 35 /* PWM1 Mode configuration: Channel2 */ 36 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;//PWM2模式 37 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能 38 TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;//比較互補輸出使能 39 TIM_OCInitStructure.TIM_Pulse = CCR2_Val; //比較值,即占空比 40 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //輸出極性 41 TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;//互補輸出極性 42 TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;//指定空閑狀態下的TIM輸出比較的引腳狀態。 43 TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;//指定空閑狀態下的TIM互補輸出比較的引腳狀態。 44 TIM_OC2Init(TIM1, &TIM_OCInitStructure); //初始化通道二比較輸出 45 TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable); //配置通道二,自動重裝載使能 46 47 48 /* PWM1 Mode configuration: Channel3 */ 49 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; 50 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; 51 TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; 52 TIM_OCInitStructure.TIM_Pulse = CCR3_Val; 53 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; 54 TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; 55 TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset; 56 TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; 57 TIM_OC3Init(TIM1, &TIM_OCInitStructure); 58 TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable); 59 60 TIM_ARRPreloadConfig(TIM1, ENABLE);//重載裝載值 ENABLE 立即生效,DISABLE 下一個比較周期生效 61 62 /* TIM1 enable counter */ 63 TIM_Cmd(TIM1, ENABLE);//使能定時器1 64 65 TIM_CtrlPWMOutputs(TIM1, ENABLE);//使能PWM外圍輸出 66 }
1 int main(void) 2 { 3 TIM1_GPIO_Config(); 4 TIM1_Mode_Config(); 5 while(1) 6 { 7 TIM1->CCR2 = CCR2_Val; 8 TIM1->CCR3 = CCR3_Val; 9 CCR2_Val+=5; 10 CCR3_Val+=10; 11 if(CCR2_Val>900) CCR2_Val = 100; 12 if(CCR3_Val>900) CCR3_Val = 100; 13 Delay_mS(200); 14 } 15 }main函數
關於死區時間計算:
先貼幾張關於TIM時鐘的圖:
第一張圖:關於死區時間分頻因數。(代碼見,初始化定時器功能配置代碼部分第14行所示)
第二張圖:死區時間計算
定時器1時鐘掛在APB2匯流排上,時鐘為72M 當TIM_ClockDivision = TIM_CKD_DIV1時, Tdts = 1/72M = 13.89ns
0 - 1.764us 用演算法一
1.778us - 3.505us 用演算法二
3.556us - 7.000us 用演算法三
7.1117us - 14us 用演算法四
需要更長時間,使用TIM_ClockDivision分頻後(可2分,4分頻),設置死區時間。
測試數據:
實驗現象:產生了兩路死區時間為1us的互補PWM信號,其頻率都是1kHz,占空比在10% - 90%不斷變化,通道三比通道二變化要快。
死區時間(以通道二為例):(黃:PA10 綠:PB15)
通道二抓拍波形 (黃:PA10 綠:PB15)
通道三抓拍波形 (黃:PA9 綠:PB14)
通道二和通道三 (黃:PA9 綠:PA10)