PWM
脈沖寬度調制模式可以產生一個由TIMx_ARR寄存器確定頻率、由TIMx_CCRx寄存器確定占空比的信號,也就是說對脈沖寬度的控制。
STM32 的定時器除了 TIM6 和 7。其他的定時器都可以用來產生 PWM 輸出。其中高級定時器 TIM1 和 TIM8 可以同時產生多達 7 路的 PWM 輸出。而通用定時器也能同時產生多達 4路的 PWM 輸出,這樣,STM32 最多可以同時產生 30 路 PWM 輸出!
在TIMx_CCMRx寄存器中的OCxM位寫入’110’(PWM模式1)或’111’(PWM模式2),能夠獨立地設置每個OCx輸出通道產生一路PWM。必須設置TIMx_CCMRx寄存OCxPE位以使能相應的預裝載寄存器,最后還要設置TIMx_CR1寄存器的ARPE位,(在向上計數或中心對稱模式中)使能自動重裝載的預裝載寄存器。
僅當發生一個更新事件的時候,預裝載寄存器才能被傳送到影子寄存器,因此在計數器開始計數之前,必須通過設置TIMx_EGR寄存器中的UG位來初始化所有的寄存器。
OCx的極性可以通過軟件在TIMx_CCER寄存器中的CCxP位設置,它可以設置為高電平有效或低電平有效。TIMx_CCER寄存器中的CCxE位控制OCx輸出使能。詳見TIMx_CCERx寄存器的描述。
在PWM模式(模式1或模式2)下,TIMx_CNT和TIMx_CCRx始終在進行比較,(依據計數器的計數方向)以確定是否符合TIMx_CCRx≤TIMx_CNT或者TIMx_CNT≤TIMx_CCRx。然而為了與OCREF_CLR的功能(在下一個PWM周期之前,ETR信號上的一個外部事件能夠清除OCxREF)一致,OCxREF信號只能在下述條件下產生:
● 當比較的結果改變,或通用定時器(TIMx)
● 當輸出比較模式(TIMx_CCMRx寄存器中的OCxM位)從“凍結”(無比較,OCxM=’000’)切換到某個PWM模式(OCxM=’110’或’111’)。
這樣在運行中可以通過軟件強置PWM輸出。
根據TIMx_CR1寄存器中CMS位的狀態,定時器能夠產生邊沿對齊的PWM信號或中央對齊的PWM信號。
PWM 邊沿對齊模式
向上計數配置
當TIMx_CR1寄存器中的DIR位為低的時候執行向上計數。
下面是一個PWM模式1的例子。當TIMx_CNT 如果比較值為0,則OCxREF保持為’0’。 下圖為TIMx_ARR=8時邊沿對齊的PWM波形實例。 - 向下計數配置 當TIMx_CR1寄存器的DIR位為高時執行向下計數。 在PWM模式1,當TIMx_CNT>TIMx_CCRx時參考信號OCxREF為低,否則為高。如果TIMx_CCRx中的比較值大于TIMx_ARR中的自動重裝載值,則OCxREF保持為’1’。該模式下不能產生0%的PWM波形。 PWM 中央對齊模式 當TIMx_CR1寄存器中的CMS位不為’00’時,為中央對齊模式(所有其他的配置OCxREF/OCx信號都有相同的作用)。根據不同的CMS位設置,比較標志可以在計數器向上計數時被置’1’、在計數器向下計數時被置’1’、或在計數器向上和向下計數時被置’1’。TIMx_CR1寄存器中的計數方向位(DIR)由硬件更新,不要用軟件修改它。 下圖給出了一些中央對齊的PWM波形的例子 ● TIMx_ARR=8 ● PWM模式1 ● TIMx_CR1寄存器中的CMS=01,在中央對齊模式1時,當計數器向下計數時設置比較標志。 使用中央對齊模式的提示: ● 進入中央對齊模式時,使用當前的向上/向下計數配置;這就意味著計數器向上還是向下計數取決于TIMx_CR1寄存器中DIR位的當前值。此外,軟件不能同時修改DIR和CMS位。 ● 不推薦當運行在中央對齊模式時改寫計數器,因為這會產生不可預知的結果。特別地: ─ 如果寫入計數器的值大于自動重加載的值(TIMx_CNT>TIMx_ARR),則方向不會被更新。 例如,如果計數器正在向上計數,它就會繼續向上計數。 ─ 如果將0或者TIMx_ARR的值寫入計數器,方向被更新,但不產生更新事件UEV。 ● 使用中央對齊模式最保險的方法,就是在啟動計數器之前產生一個軟件更新(設置 TIMx_EGR 位中的UG位),不要在計數進行過程中修改計數器的值。 通過庫函數來配置該功能的步驟 注:本次學習的使用TIM3的向上計數模式(TIM3_CH2 通道將重映射到 PB5 上)產生PWM。 1. 開啟TIM3時鐘以及復用功能時鐘,配置PB5為復用輸出。 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); //使能定時器3時鐘 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //復用時鐘使能 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //使能GPIOB時鐘 GPIO_InitTypeDef GPIO_ITDef_PB5; GPIO_ITDef_PB5.GPIO_Pin = GPIO_Pin_5; GPIO_ITDef_PB5.GPIO_Mode = GPIO_Mode_AF_PP;//復用推挽輸出 GPIO_ITDef_PB5.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(GPIOB,&GPIO_ITDef_PB5); 2. 設置TIM3_CH2重映射到 PB5上。 默認條件下,TIM3_REMAP[1:0]為 00,是沒有重映射的,所以 TIM3_CH1~TIM3_CH4 分別是接在 PA6、PA7、PB0 和 PB1 上的,而我們想讓 TIM3_CH2 映射到 PB5 上,則需要設置TIM3_REMAP[1:0]=10,即部分重映射,這里需要注意,此時 TIM3_CH1 也被映射到 PB4 上了。 GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3,ENABLE); //重映射 TIM3_CH2->PB5 3. 初始化TIM3, 設置TIM3的ARR和PSC 。 注:向上計數模式 TIM_TBIStruct_TIM3.TIM_Period = 100; //設置自動重裝載值 ARR TIM_TBIStruct_TIM3.TIM_Prescaler = 7199; //設置預分頻值 PSC TIM_TBIStruct_TIM3.TIM_ClockDivision = TIM_CKD_DIV1; //設置時鐘分割:TDTS = Tck_tim TIM_TBIStruct_TIM3.TIM_ClockDivision = TIM_CounterMode_Up; //TIM 向上計數模式 TIM_TimeBaseInit(TIM3,&TIM_TBIStruct_TIM3); 4. 設置TIM3_CH2的PWM 模式 使能TIM3的CH2輸出。 注:在固件庫"stm32f10x.h"和"stm32f10x.c"里能查到。 void TIM_OC2Init(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); //主要還是TIM_OCInitTypeDef結構體的定義內容。 typedef struct { uint16_t TIM_OCMode;//選擇定時器模式。 /* TIM_OCMode_Timing TIM 輸出比較時間模式 TIM_OCMode_Active TIM 輸出比較主動模式 TIM_OCMode_Inactive TIM 輸出比較非主動模式 TIM_OCMode_Toggle TIM 輸出比較觸發模式 TIM_OCMode_PWM1 TIM 脈沖寬度調制模式 1 TIM_OCMode_PWM2 TIM 脈沖寬度調制模式 2 */ uint16_t TIM_OutputState; //設置比較輸出使能 uint16_t TIM_OutputNState; //指定TIM的互補輸出比較狀態。 //設置了待裝入捕獲比較寄存器的脈沖值。它的取值必須在 0x0000 和 0xFFFF 之間。 uint16_t TIM_Pulse; uint16_t TIM_OCPolarity;//輸出極性 /* TIM_OCPolarity_High TIM 輸出比較極性高 TIM_OCPolarity_Low TIM 輸出比較極性低 */ uint16_t TIM_OCNPolarity;//指定互補的輸出極性。 uint16_t TIM_OCIdleState; //指定空閑狀態下的TIM輸出比較引腳狀態。 uint16_t TIM_OCNIdleState; //指定空閑狀態下的TIM輸出比較引腳狀態。 } TIM_OCInitTypeDef; //初始化 TIM3 Channel2 PWM 模式 TIM_OCInitTypeDef TIM_OCITDef_TIM3; TIM_OCITDef_TIM3.TIM_OCMode = TIM_OCMode_PWM2; //選擇 PWM 模式 2 TIM_OCITDef_TIM3.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能 TIM_OCITDef_TIM3.TIM_OCPolarity = TIM_OCPolarity_High; //輸出極性高 TIM_OC2Init(TIM3, &TIM_OCITDef_TIM3); //初始化外設 TIM3 OC2 注:TIM_OutputNState、TIM_OCNPolarity、TIM_OCIdleState 和 TIM_OCNIdleState 是高級定時器 TIM1 和 TIM8 才用到的 5. 使能TIM3。 TIM_Cmd(TIM3, ENABLE); //使能 TIM3 6. 修改TIM3_CCR2來控制占空比。 注:修改Compare2便可以修改占空比。 void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2); 完整程序 #include "stm32f10x.h" /* TIM3輸出比較模式 LED PB5 KEY0 */ u16 data = 0;//0-1000 u8 temp = 2;//1-250 2-500 3-1000 u8 dir = 1; void delay_ms(u16 time) { u16 i = 0; while(time--) { i = 12000; while(i--); } } void LED_Init_PE5(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE); GPIO_InitTypeDef GPIO_ITDef_PE5; GPIO_ITDef_PE5.GPIO_Pin = GPIO_Pin_5; GPIO_ITDef_PE5.GPIO_Mode = GPIO_Mode_Out_PP;//推挽輸出 GPIO_ITDef_PE5.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(GPIOE,&GPIO_ITDef_PE5); GPIO_SetBits(GPIOE,GPIO_Pin_5);//1 } void KEY0_Init_PE4(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE|RCC_APB2Periph_AFIO,ENABLE); GPIO_InitTypeDef GPIO_ITDef_PE4; GPIO_ITDef_PE4.GPIO_Pin = GPIO_Pin_4; GPIO_ITDef_PE4.GPIO_Mode = GPIO_Mode_IPU;//上拉輸入 GPIO_Init(GPIOE,&GPIO_ITDef_PE4); //外部中斷 GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource4); EXTI_InitTypeDef EXTI_ITDef_PE4; EXTI_ITDef_PE4.EXTI_Line = EXTI_Line4; EXTI_ITDef_PE4.EXTI_Mode = EXTI_Mode_Interrupt;//為中斷請求 EXTI_ITDef_PE4.EXTI_Trigger = EXTI_Trigger_Falling;//輸入線路下升沿中斷 EXTI_ITDef_PE4.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_ITDef_PE4); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//設置 NVIC 中斷分組 2:2 位搶占優先級,2 位響應優先級 NVIC_InitTypeDef NVIC_ITDef; NVIC_ITDef.NVIC_IRQChannel = EXTI4_IRQn; //使能按鍵外部中斷通道 NVIC_ITDef.NVIC_IRQChannelPreemptionPriority = 0x02; //搶占優先級 2, NVIC_ITDef.NVIC_IRQChannelSubPriority = 0x02; //子優先級 2 NVIC_ITDef.NVIC_IRQChannelCmd = ENABLE; //使能外部中斷通道 NVIC_Init(&NVIC_ITDef); } void TIM3_Init(void) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //復用時鐘使能 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_InitTypeDef GPIO_ITDef_PB5; GPIO_ITDef_PB5.GPIO_Pin = GPIO_Pin_5; GPIO_ITDef_PB5.GPIO_Mode = GPIO_Mode_AF_PP;//復用推挽輸出 GPIO_ITDef_PB5.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(GPIOB,&GPIO_ITDef_PB5); TIM_DeInit(TIM3);//復位TIM3(可要可不要) GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3,ENABLE); //重映射 TIM3_CH2->PB5 TIM_TimeBaseInitTypeDef TIM_TBIStruct_TIM3; TIM_TBIStruct_TIM3.TIM_Period = 100; //設置自動重裝載值 TIM_TBIStruct_TIM3.TIM_Prescaler = 7199; //設置預分頻值 TIM_TBIStruct_TIM3.TIM_ClockDivision = TIM_CKD_DIV1; //設置時鐘分割:TDTS = Tck_tim TIM_TBIStruct_TIM3.TIM_ClockDivision = TIM_CounterMode_Up; //TIM 向上計數模式 TIM_TimeBaseInit(TIM3,&TIM_TBIStruct_TIM3); //初始化 TIM3 Channel2 PWM 模式 TIM_OCInitTypeDef TIM_OCITDef_TIM3; TIM_OCITDef_TIM3.TIM_OCMode = TIM_OCMode_PWM2; //選擇 PWM 模式 2 TIM_OCITDef_TIM3.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能 TIM_OCITDef_TIM3.TIM_OCPolarity = TIM_OCPolarity_High; //輸出極性高 TIM_OC2Init(TIM3, &TIM_OCITDef_TIM3); //初始化外設 TIM3 OC2 TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable); //使能預裝載寄存器 TIM_Cmd(TIM3,ENABLE); //使能 TIM3 } int main(void) { LED_Init_PE5(); KEY0_Init_PE4(); TIM3_Init(); while(1) { //按鍵處理(通過按鍵改變占空比) switch(temp) { case 0:data=0;break; case 1:data=3;break; case 2:data=5;break; case 3:data=10;break; case 4:data=50;break; case 5:data=90;break; case 6:data=100;break; } /* data從0-200-0 來修改占空比 delay_ms(10); if(dir)data++; else data--; if(data>200)dir=0; if(data==0)dir=1; */ TIM_SetCompare2(TIM3,data); } } //按鍵中斷處理函數,按鍵每按一下,PE5的狀態翻轉一次(LED亮滅翻轉) void EXTI4_IRQHandler(void) { if(EXTI_GetITStatus(EXTI_Line4)!=RESET)//判斷某個線上的中斷是否發生 { delay_ms(10); //按鍵延時消斗 if(!(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)))//再次判斷是否按鍵按下 { temp++;//按下一次,temp+1, if(temp>6)temp=0;//這里可以根據實際需求修改 if(GPIO_ReadOutputDataBit(GPIOE,GPIO_Pin_5))//是滅的 { GPIO_ResetBits(GPIOE,GPIO_Pin_5); //BRR 0 亮 }else { GPIO_SetBits(GPIOE,GPIO_Pin_5); //BSRR 1 滅 } } EXTI_ClearITPendingBit(EXTI_Line4);
上一篇:STM32學習筆記(一)GPIO
下一篇:STM32基于固件庫學習筆記(12)LCD5110顯示
- 熱門資源推薦
- 熱門放大器推薦
設計資源 培訓 開發板 精華推薦
- 使用 Analog Devices 的 LT1579CGN-3.3 的參考設計
- LT1120CN8 微功率穩壓器的典型應用電路,用于將比較器補償為運算放大器
- Sp6669、1.5-Mhz、600Ma 固定同步降壓轉換器的典型應用
- RD-478,將 FSQ0365RN 電源開關用于輔助電源應用的參考設計
- AM3GH-4815DZ ±15V 傳導和輻射發射 DC/DC 轉換器的典型應用
- 用于 NCP3063B 1.5A 降壓型開關穩壓器的帶有外部 PMOS 晶體管的典型降壓應用原理圖
- LM2596ADPBCKGEVB:降壓開關穩壓器評估板
- Cμ4 四位CPU
- SimpleFoc驗證板
- 用于 1.2V 和 1V 輸出跟蹤的 LTM4628EV DC/DC 模塊穩壓器的典型應用電路