stm32 PWM互补输出
stm32高級定時(shí)器例子—stm32 PWM互補(bǔ)輸出
定時(shí)器初始化結(jié)構(gòu)體
TIM_TimeBaseInitTypeDef
時(shí)基結(jié)構(gòu)體,用于定時(shí)器基礎(chǔ)參數(shù)設(shè)置,與TIM_TimeBaseInit函數(shù)配合使用,完成配置。
typedef struct { TIM_Prescaler /*定時(shí)器預(yù)分頻器設(shè)置,時(shí)鐘源經(jīng)該預(yù)分頻器才是定時(shí)器計(jì) 數(shù)時(shí)鐘CK_CNT,它設(shè)定PSC寄存器的值。計(jì)數(shù)器時(shí)鐘頻率 (fCK_CNT) 等于fCK_PSC/(PSC[15:0]+1),可實(shí)現(xiàn)1至65536分頻。*/ TIM_CounterMode /*定時(shí)器計(jì)數(shù)方式,可設(shè)置為向上計(jì)數(shù)、向下計(jì)數(shù)、中心對齊*/ TIM_Period /*定時(shí)器周期,設(shè)定自動(dòng)重載寄存器ARR的值可設(shè)置范圍為0至65535*/ TIM_ClockDivision /*時(shí)鐘分頻,設(shè)置定時(shí)器時(shí)鐘CK_INT頻率與死區(qū)發(fā)生器以及數(shù)字濾波器采樣時(shí)鐘頻率分頻比。可以選擇 1、2、4 分頻。*/ TIM_RepetitionCounter /*重復(fù)計(jì)數(shù)器,只有 8 位,只存在于高級定時(shí)器*/ }TIM_TimeBaseInitTypeDef;TIM_OCInitTypeDef
輸出比較結(jié)構(gòu)體,用于輸出比較模式。與TIM_OCxInit函數(shù)配合使用,完成指定定時(shí)器輸出通道初始化配置。
typedef struct {uint16_t TIM_OCMode; /*比較輸出模式選擇,共有八種。常用的為 PWM1/PWM2。設(shè)定CCMRx寄存器OCxM[2:0]位的值*/uint16_t TIM_OutputState; /*比較輸出使能,決定最終的輸出比較信號OCx是否通過外部引腳輸出。設(shè)定TIMx_CCER寄存器CCxE/CCxNE位的值。*/uint16_t TIM_OutputNState; /*比較互補(bǔ)輸出使能,決定OCx的互補(bǔ)信號OCxN是否通過外部引腳輸出。設(shè)定CCER寄存器CCxNE位的值*/uint16_t TIM_Pulse; /*比較輸出脈沖寬度,設(shè)定比較寄存器CCR的值,決定脈沖寬度。可設(shè)置范圍為0至65535。*/uint16_t TIM_OCPolarity; /*比較輸出極性,可選OCx為高電平有效或低電平有效。決定定時(shí)器通道有效電平。設(shè)定CCER寄存器的CCxP位的值*/uint16_t TIM_OCNPolarity; /*比較互補(bǔ)輸出極性,可選OCxN為高電平有效或低電平有效。設(shè)定TIMx_CCER寄存器的CCxNP位的值。*/uint16_t TIM_OCIdleState; /*空閑狀態(tài)時(shí),通道輸出電平設(shè)置,可選輸出1或輸出0,即在空閑狀態(tài)(BDTR_MOE位為0)時(shí),經(jīng)過死區(qū)時(shí)間后定時(shí)器通道輸出高電平或低電平。設(shè)定CR2寄存器的OISx位的值*/uint16_t TIM_OCNIdleState; /*空閑狀態(tài)時(shí)互補(bǔ)通道輸出電平設(shè)置,可選輸出1或輸出0,即在空閑狀態(tài)(BDTR_MOE位為0)時(shí),經(jīng)過死區(qū)時(shí)間后定時(shí)器互補(bǔ)通道輸出高電平或低電平,設(shè)定值必須與TIM_OCIdleState相反。設(shè)定CR2寄存器的OISxN位的值。*/ } TIM_OCInitTypeDef;TIM_ICInitTypeDef
輸入捕獲結(jié)構(gòu)體,用于輸入捕獲模式。
與TIM_ICInit函數(shù)配合使用,完成定時(shí)器輸入通道初始化配置。
如果使用PWM輸入模式,與TIM_PWMIConfig函數(shù)配合使用,完成定時(shí)器輸入通道初始化配置。
typedef struct {uint16_t TIM_Channel; /*捕獲通道ICx選擇,可選TIM_Channel_1、2、3、4四個(gè)通道。設(shè)定CCMRx寄存器CCxS位的值*/uint16_t TIM_ICPolarity; /*輸入捕獲邊沿觸發(fā)選擇,可選上升沿觸發(fā)、下降沿觸發(fā)、邊沿跳變觸發(fā)。設(shè)定CCER寄存器CCxP位和CCxNP位的值。*/ uint16_t TIM_ICSelection; /*輸入通道選擇,捕獲通道ICx的信號可來自三個(gè)輸入通道,分別為TIM_ICSelection_DirectTI、TIM_ICSelection_IndirectTITIM_ICSelection_TRC普通的輸入捕獲,4個(gè)通道都可以使用,PWM輸入,只能使用通道1和通道2。設(shè)定CCRMx寄存器的CCxS[1:0]位的值*/uint16_t TIM_ICPrescaler; /*輸入捕獲通道預(yù)分頻器,可設(shè)置1、2、4、8分頻,設(shè)定CCMRx寄存器的ICxPSC[1:0]位的值。如果需捕獲輸入信號的每個(gè)有效邊沿,則設(shè)置1分頻。*/uint16_t TIM_ICFilter; /*輸入捕獲濾波器設(shè)置,可設(shè)置0x0至0x0F。設(shè)定CCMRx寄存器ICxF[3:0]位的值。一般不使用濾波器,設(shè)置為0*/ } TIM_ICInitTypeDef;關(guān)于捕獲通道ICx的信號可來自三個(gè)輸入通道:
TIM_BDTRInitTypeDef
斷路和死區(qū)結(jié)構(gòu)體,用于斷路和死區(qū)參數(shù)的設(shè)置,高級定時(shí)器專用。
用于配置斷路時(shí),通道輸出狀態(tài)、死區(qū)時(shí)間。
與TIM_BDTRConfig函數(shù)配置使用,完成參數(shù)配置。
這個(gè)結(jié)構(gòu)體的成員只對應(yīng)BDTR寄存器。
typedef struct {uint16_t TIM_OSSRState; /*運(yùn)行模式下的關(guān)閉狀態(tài)選擇,設(shè)定BDTR寄存器OSSR位的值*/uint16_t TIM_OSSIState; /*空閑模式下的關(guān)閉狀態(tài)選擇,設(shè)定BDTR寄存器OSSI位的值。*/ uint16_t TIM_LOCKLevel; /*鎖定級別配置, 設(shè)定BDTR寄存器LOCK[1:0]位的值*/ uint16_t TIM_DeadTime; /*配置死區(qū)發(fā)生器,定義死區(qū)持續(xù)時(shí)間,可選設(shè)置范圍為0x0至0xFF。設(shè)定BDTR寄存器DTG[7:0]位的值*/ uint16_t TIM_Break; /*斷路輸入功能選擇,可選使能或禁止。設(shè)定BDTR寄存器BKE位的值*/ uint16_t TIM_BreakPolarity; /*斷路輸入通道BRK極性選擇,可選高電平有效或低電平有效。設(shè)定BDTR寄存器BKP位的值。*/ uint16_t TIM_AutomaticOutput; /*自動(dòng)輸出使能,可選使能或禁止,設(shè)定BDTR寄存器AOE位的值。*/ } TIM_BDTRInitTypeDef;PWM 互補(bǔ)輸出
在主輸出通道輸出波形,在互補(bǔ)通道輸出與主通道互補(bǔ)的的波形,添加斷路和死區(qū)功能。
使用高級定時(shí)器TIM1的通道1及其互補(bǔ)通道作為本實(shí)驗(yàn)的波形輸出通道。對應(yīng)PA8和PB13。
將示波器的兩個(gè)輸入通道分別與PA8和PB13引腳連接,共地,觀察波形。
增加斷路功能,用到TIM1_BKIN引腳。對應(yīng)PB12引腳。
設(shè)置該引腳為高電平有效,BKIN引腳置高電平時(shí),兩路互補(bǔ)的PWM輸出就被停止,像是剎車一樣。
Main函數(shù),調(diào)用ADVANCE_TIM_Init()函數(shù)。
該函數(shù)調(diào)用ADVANCE_TIM_GPIO_Config()和ADVANCE_TIM_Mode_Config()進(jìn)行定時(shí)器GPIO引腳和工作模式的初始化。
相應(yīng)的GPIO引腳上可以檢測到互補(bǔ)輸出的PWM信號,而且?guī)绤^(qū)時(shí)間。
程序運(yùn)行的過程中,如果BKIN引腳被拉高,PWM輸出會(huì)被禁止,像是斷路或者剎車。
#include "stm32f10x.h" #include "bsp_led.h" #include "bsp_AdvanceTim.h" /*** @brief 主函數(shù)* @param 無 * @retval 無*/ int main(void) { /* 高級定時(shí)器初始化 */ADVANCE_TIM_Init();while(1){ } }修改PWM的周期和占空比,只需修改下面的ADVANCE_TIM_PERIOD、ADVANCE_TIM_PSC和ADVANCE_TIM_PULSE這三個(gè)宏即可。具體原因,看之前寫的文章—高級定時(shí)器里面的PWM輸出模式。
TIM_CLK等于72MHZ,ARR是自動(dòng)重裝載寄存器的值,對應(yīng)ADVANCE_TIM_PERIOD;PSC是計(jì)數(shù)器時(shí)鐘的分頻因子,對應(yīng)ADVANCE_TIM_PSC。
PWM信號的頻率:F = TIM_CLK/{(ARR+1)*(PSC+1)}
計(jì)數(shù)器時(shí)鐘CK_CNT:
定時(shí)器時(shí)鐘經(jīng)過PSC預(yù)分頻器后,即CK_CNT,用來驅(qū)動(dòng)計(jì)數(shù)器計(jì)數(shù)。
PSC是16位的預(yù)分頻器,可以對定時(shí)器時(shí)鐘TIMxCLK進(jìn)行1~65536之間的任何一個(gè)數(shù)進(jìn)行分頻。CK_CNT=TIMxCLK/(PSC+1)。
ARR=8,CCR=4,CNT從0開始計(jì)數(shù)。
當(dāng)CNT<CCR,OCxREF為有效的高電平,同時(shí),比較中斷寄存器CCxIF置位。
CCR<=CNT<=ARR,OCxREF為無效的低電平。
計(jì)數(shù)器在CK_CNT的驅(qū)動(dòng)下,計(jì)一個(gè)數(shù)的時(shí)間,1/(TIMxCLK/(PSC+1))=1/(CK_CNT)=(PSC+1)/TIMxCLK
計(jì)一個(gè)數(shù)的時(shí)間乘上一個(gè)波形的計(jì)數(shù)次數(shù)(ARR+1),就是整個(gè)波形的所需時(shí)間。
時(shí)間取倒數(shù)就是PWM信號的頻率。
由此可知F = TIM_CLK/{(ARR+1)*(PSC+1)}的含義。
ARR :自動(dòng)重裝載寄存器的值 CLK_cnt:計(jì)數(shù)器的時(shí)鐘,等于 Fck_int / (psc+1) = 72M/(psc+1) PWM 信號的周期 T = (ARR+1) * (1/CLK_cnt) = (ARR+1)*(PSC+1) / 72M 占空比P=CCR/(ARR+1) #ifndef __BSP_ADVANCETIME_H #define __BSP_ADVANCETIME_H#include "stm32f10x.h"/************高級定時(shí)器TIM參數(shù)定義,只限TIM1和TIM8************/ // 當(dāng)使用不同的定時(shí)器的時(shí)候,對應(yīng)的GPIO是不一樣的,這點(diǎn)要注意 // 這里我們使用高級控制定時(shí)器TIM1#define ADVANCE_TIM TIM1 #define ADVANCE_TIM_APBxClock_FUN RCC_APB2PeriphClockCmd #define ADVANCE_TIM_CLK RCC_APB2Periph_TIM1 // PWM 信號的頻率 F = TIM_CLK/{(ARR+1)*(PSC+1)} #define ADVANCE_TIM_PERIOD (8-1) #define ADVANCE_TIM_PSC (9-1) #define ADVANCE_TIM_PULSE 4#define ADVANCE_TIM_IRQ TIM1_UP_IRQn #define ADVANCE_TIM_IRQHandler TIM1_UP_IRQHandler// TIM1 輸出比較通道 #define ADVANCE_TIM_CH1_GPIO_CLK RCC_APB2Periph_GPIOA #define ADVANCE_TIM_CH1_PORT GPIOA #define ADVANCE_TIM_CH1_PIN GPIO_Pin_8// TIM1 輸出比較通道的互補(bǔ)通道 #define ADVANCE_TIM_CH1N_GPIO_CLK RCC_APB2Periph_GPIOB #define ADVANCE_TIM_CH1N_PORT GPIOB #define ADVANCE_TIM_CH1N_PIN GPIO_Pin_13// TIM1 輸出比較通道的剎車通道 #define ADVANCE_TIM_BKIN_GPIO_CLK RCC_APB2Periph_GPIOB #define ADVANCE_TIM_BKIN_PORT GPIOB #define ADVANCE_TIM_BKIN_PIN GPIO_Pin_12/**************************函數(shù)聲明********************************/void ADVANCE_TIM_Init(void);#endif /* __BSP_ADVANCETIME_H */ #include "bsp_AdvanceTim.h" static void ADVANCE_TIM_GPIO_Config(void) {GPIO_InitTypeDef GPIO_InitStructure;// 輸出比較通道 GPIO 初始化RCC_APB2PeriphClockCmd(ADVANCE_TIM_CH1_GPIO_CLK, ENABLE);GPIO_InitStructure.GPIO_Pin = ADVANCE_TIM_CH1_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(ADVANCE_TIM_CH1_PORT, &GPIO_InitStructure);// 輸出比較通道互補(bǔ)通道 GPIO 初始化RCC_APB2PeriphClockCmd(ADVANCE_TIM_CH1N_GPIO_CLK, ENABLE);GPIO_InitStructure.GPIO_Pin = ADVANCE_TIM_CH1N_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(ADVANCE_TIM_CH1N_PORT, &GPIO_InitStructure);// 輸出比較通道剎車通道 GPIO 初始化RCC_APB2PeriphClockCmd(ADVANCE_TIM_BKIN_GPIO_CLK, ENABLE);GPIO_InitStructure.GPIO_Pin = ADVANCE_TIM_BKIN_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(ADVANCE_TIM_BKIN_PORT, &GPIO_InitStructure);// BKIN引腳默認(rèn)先輸出低電平GPIO_ResetBits(ADVANCE_TIM_BKIN_PORT,ADVANCE_TIM_BKIN_PIN); }///* // * 注意:TIM_TimeBaseInitTypeDef結(jié)構(gòu)體里面有5個(gè)成員,TIM6和TIM7的寄存器里面只有 // * TIM_Prescaler和TIM_Period,所以使用TIM6和TIM7的時(shí)候只需初始化這兩個(gè)成員即可, // * 另外三個(gè)成員是通用定時(shí)器和高級定時(shí)器才有. // *----------------------------------------------------------------------------- // *typedef struct // *{ TIM_Prescaler 都有 // * TIM_CounterMode TIMx,x[6,7]沒有,其他都有 // * TIM_Period 都有 // * TIM_ClockDivision TIMx,x[6,7]沒有,其他都有 // * TIM_RepetitionCounter TIMx,x[1,8,15,16,17]才有 // *}TIM_TimeBaseInitTypeDef; // *----------------------------------------------------------------------------- // *//* ---------------- PWM信號 周期和占空比的計(jì)算--------------- */ // ARR :自動(dòng)重裝載寄存器的值 // CLK_cnt:計(jì)數(shù)器的時(shí)鐘,等于 Fck_int / (psc+1) = 72M/(psc+1) // PWM 信號的周期 T = (ARR+1) * (1/CLK_cnt) = (ARR+1)*(PSC+1) / 72M // 占空比P=CCR/(ARR+1)static void ADVANCE_TIM_Mode_Config(void) {// 開啟定時(shí)器時(shí)鐘,即內(nèi)部時(shí)鐘CK_INT=72MADVANCE_TIM_APBxClock_FUN(ADVANCE_TIM_CLK,ENABLE);/*--------------------時(shí)基結(jié)構(gòu)體初始化-------------------------*/TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;// 自動(dòng)重裝載寄存器的值,累計(jì)TIM_Period+1個(gè)頻率后產(chǎn)生一個(gè)更新或者中斷TIM_TimeBaseStructure.TIM_Period=ADVANCE_TIM_PERIOD; // 驅(qū)動(dòng)CNT計(jì)數(shù)器的時(shí)鐘 = Fck_int/(psc+1)TIM_TimeBaseStructure.TIM_Prescaler= ADVANCE_TIM_PSC; // 時(shí)鐘分頻因子 ,配置死區(qū)時(shí)間時(shí)需要用到TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; // 計(jì)數(shù)器計(jì)數(shù)模式,設(shè)置為向上計(jì)數(shù)TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; // 重復(fù)計(jì)數(shù)器的值,沒用到不用管TIM_TimeBaseStructure.TIM_RepetitionCounter=0; // 初始化定時(shí)器TIM_TimeBaseInit(ADVANCE_TIM, &TIM_TimeBaseStructure);/*--------------------輸出比較結(jié)構(gòu)體初始化-------------------*/ TIM_OCInitTypeDef TIM_OCInitStructure;// 配置為PWM模式1TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;// 輸出使能TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;// 互補(bǔ)輸出使能TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; // 設(shè)置占空比大小TIM_OCInitStructure.TIM_Pulse = ADVANCE_TIM_PULSE;// 輸出通道電平極性配置TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;// 互補(bǔ)輸出通道電平極性配置TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;// 輸出通道空閑電平極性配置TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;// 互補(bǔ)輸出通道空閑電平極性配置TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;TIM_OC1Init(ADVANCE_TIM, &TIM_OCInitStructure);TIM_OC1PreloadConfig(ADVANCE_TIM, TIM_OCPreload_Enable);/*-------------------剎車和死區(qū)結(jié)構(gòu)體初始化-------------------*/// 有關(guān)剎車和死區(qū)結(jié)構(gòu)體的成員具體可參考BDTR寄存器的描述TIM_BDTRInitTypeDef TIM_BDTRInitStructure;TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;// 輸出比較信號死區(qū)時(shí)間配置,具體如何計(jì)算可參考 BDTR:UTG[7:0]的描述// 這里配置的死區(qū)時(shí)間為152nsTIM_BDTRInitStructure.TIM_DeadTime = 11;TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable;// 當(dāng)BKIN引腳檢測到高電平的時(shí)候,輸出比較信號被禁止,就好像是剎車一樣TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;TIM_BDTRConfig(ADVANCE_TIM, &TIM_BDTRInitStructure);// 使能計(jì)數(shù)器TIM_Cmd(ADVANCE_TIM, ENABLE); // 主輸出使能,當(dāng)使用的是通用定時(shí)器時(shí),這句不需要TIM_CtrlPWMOutputs(ADVANCE_TIM, ENABLE); }void ADVANCE_TIM_Init(void) {ADVANCE_TIM_GPIO_Config();ADVANCE_TIM_Mode_Config(); }
目前這里沒有示波器,于是就用仿真模擬。應(yīng)該是出現(xiàn)一路互補(bǔ)的帶死區(qū)時(shí)間的PWM波形。
當(dāng)BKIN引腳接高電平時(shí),PWM輸出被禁止,好像是剎車一樣。
總結(jié)
以上是生活随笔為你收集整理的stm32 PWM互补输出的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: stm32基本定时器
- 下一篇: 新手学习c语言的方法,学习C语言方法“新