日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

stm32 PWM输出学习

發布時間:2025/3/15 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 stm32 PWM输出学习 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

STM32 的定時器除了 TIM6 和 7,其他的定時器都可以用來產生 PWM 輸出。其中高級定時器 TIM1 和 TIM8 可以同時產生多達 7 路的 PWM 輸出。通用定時器也能同時產生多達 4路的 PWM 輸出。

今天的實驗,我們僅利用 TIM3的 CH2 通道產生一路 PWM 輸出。

1.相關寄存器介紹

1)捕獲/比較模式寄存器 (TIMx_CCMR1/2)?

捕獲/比較模式寄存器(TIMx_CCMR1/2),該寄存器總共有 2 個,TIMx ?_CCMR1和 TIMx _CCMR2。TIMx_CCMR1 控制 CH1 和 CH2,而 TIMx_CCMR2 控制 CH3 和 CH4。


OCxx描述了通道在輸出模式下的功能(上行),ICxx描述了通道在輸出模式下的功能(下行)。因此必須注意,同一個位在輸出模式和輸入模式下的功能是不同的。?

這里我們需要說明的是模式設置位 OCxM,此部分由 3 位組成。總共可以配置成 7 種模式,我們使用的是 PWM 模式,所以這 3 位必須設置為 110/111。這兩種PWM 模式的區別就是輸出電平的極性相反。?


這里的有效電平或者無效電平是可以配置的。

2)?捕獲/比較使能寄存器(TIMx_CCER)?



3)捕獲/比較寄存器(TIMx_CCR1~4)

該寄存器總共有 4 個,對應 4 個通道 CH1~CH4。因為這 4 個寄存器都差不多,我們僅以 TIMx_CCR1 為例介紹。


我們通過修改這個寄存器的值,就可以控制 PWM 的輸出脈寬。

2.?TIM3_REMAP 重映射

我們要利用 TIM3 的 CH2 輸出 PWM 來控制 LED的亮度,但是 TIM3_CH2 默認是接在 PA7上面的,而我們的 LED接在 PB5 上面,如果是普通 MCU,可能就只能用飛線把 PA7 飛到 PB5上;不過,我們用的是 STM32,可以通過重映射功能,把 TIM3_CH2映射到 PB5 上。?


3.代碼難點分析

1)RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);//使能TIM3時鐘
? ? ? RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); ?
//使能GPIOB時鐘(PB5連接LED)和AFIO復用功能時鐘

為什么要使能RCC_APB2Periph_AFIO呢?

參考手冊上說:

對寄存器AFIO_EVCR(事件控制寄存器),AFIO_MAPR(?復用重映射和調試I/O配置寄存器),AFIO_EXTICRX(外部中斷配置寄存器)進行讀寫操作前,應當首先打開AFIO的時鐘。

因為我們在這個實驗中用到了AFIO_MAPR,所以要打開AFIO時鐘。

2)GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //Timer3部分重映射,TIM3_CH2->PB5?

3)GPIO配置

//設置該引腳為復用輸出功能,輸出TIM3-CH2的PWM波形
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;?
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; ?//推挽復用輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);


4)TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;?

? ? ?可以參考捕獲/比較使能寄存器(TIMx_CCER)位0, 輸出使能。

5)TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;?

? ? ?可以參考捕獲/比較使能寄存器(TIMx_CCER)位1, 高/低 電平有效。

6)TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); 預裝載使能

? ? ?可以參考捕獲/比較模式寄存器 (TIMx_CCMR1/2) 位3.


7)TIM_SetCompare2(TIM3,300);

參考捕獲/比較寄存器(TIMx_CCR1~4),這里設置比較值為300.

4. 代碼參考

//PWM輸出初始化函數 //arr:自動重裝載值 //psc: 預分頻系數 void TIM3_PWM_Init(u16 arr,u16 psc) { GPIO_InitTypeDef GPIO_InitStructure;TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;TIM_OCInitTypeDef TIM_OCInitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能TIM3時鐘RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); //使能GPIOB時鐘(PB5連接LED)和AFIO復用功能時鐘GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //Timer3部分重映射,TIM3_CH2->PB5 //設置該引腳為復用輸出功能,輸出TIM3-CH2的PWM波形GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復用推挽輸出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化TIM3TIM_TimeBaseStructure.TIM_Period = arr; TIM_TimeBaseStructure.TIM_Prescaler = psc; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上計數TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //TIM3 Channel2 PWM 初始化TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //PWM2模式TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //捕獲/比較使能寄存器(TIMx_CCER) 輸出使能TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //高電平有效TIM_OC2Init(TIM3, &TIM_OCInitStructure); TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //預裝載使能TIM_Cmd(TIM3, ENABLE); //開啟TIM3}
main函數如下

int main(void) { TIM3_PWM_Init(999,71); //72/(71+1)=1MHz, T=1us*(999+1) = 1msTIM_SetCompare2(TIM3,300); //脈寬= 300/1000 *1ms = 0.3mswhile(1){; } }

仿真說明:我們的代碼設置為:

PWM2模式,向上計數,高電平有效。

所以,TIMx_CNT<TIMx_CCRx時通道x為低,否則為高。

5.仿真效果圖如下


6. 疑問

如果調換main函數兩句的順序,則無法達到預期效果。

<span style="font-size:18px;">int main(void) //實驗失敗 { TIM_SetCompare2(TIM3,300); //脈寬= 300/1000 *1ms = 0.3msTIM3_PWM_Init(999,71); //72/(71+1)=1MHz, T=1us*(999+1) = 1mswhile(1){; } }</span>

至于原因,這里不討論,留待以后思考。

7. 用PWM控制LED的亮度

int main(void) { u16 led0pwmval = 0; //比較值u8 dir = 1; delay_init(); TIM3_PWM_Init(899,0); while(1){delay_ms(10); if(dir)led0pwmval++;else led0pwmval--;if(led0pwmval>300)dir=0;if(led0pwmval==0)dir=1; TIM_SetCompare2(TIM3,led0pwmval); } }

這里,我們將 led0pwmval 這個值設置為 PWM 比較值,也就是通過 led0pwmval 來控制 PWM 的占空比,進而控制LED的平均電流,達到控制LED亮度的目的。

?led0pwmval 的值從 0 變到 301,然后又從 301 變到 0,如此循環,LED的亮度也會跟著從暗變到亮,然后又從亮變到暗。至于這里的值,我們為什么取 300,是因為 PWM 的輸出占空比達到并且超過這個值的時候, LED 亮度變化就不明顯了。



總結

以上是生活随笔為你收集整理的stm32 PWM输出学习的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。