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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

【转载】 stm32之PWM

發(fā)布時(shí)間:2023/11/27 生活经验 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【转载】 stm32之PWM 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

發(fā)現(xiàn)這位博主的博客被大量的轉(zhuǎn)發(fā),我也轉(zhuǎn)載一篇,誰叫人家寫的好呢。

原文地址:http://blog.sina.com.cn/s/blog_49cb42490100s6uh.html

?

脈沖寬度調(diào)制(PWM),是英文“Pulse Width Modulation”的縮寫,簡(jiǎn)稱脈寬調(diào)制,是利用微處理器的數(shù)字輸出來對(duì)模擬電路進(jìn)行控制的一種非常有效的技術(shù)。簡(jiǎn)單一點(diǎn),就是對(duì)脈沖寬度的控制。一般用來控制步進(jìn)電機(jī)的速度等等。

STM32的定時(shí)器除了TIM6和TIM7之外,其他的定時(shí)器都可以用來產(chǎn)生PWM輸出,其中高級(jí)定時(shí)器TIM1和TIM8可以同時(shí)產(chǎn)生7路的PWM輸出,而通用定時(shí)器也能同時(shí)產(chǎn)生4路的PWM輸出。

?

1.1???PWM輸出模式

STM32的PWM輸出有兩種模式,模式1和模式2,由TIMx_CCMRx寄存器中的OCxM位確定的(“110”為模式1,“111”為模式2)。模式1和模式2的區(qū)別如下:

110:PWM模式1-在向上計(jì)數(shù)時(shí),一旦TIMx_CNT<TIMx_CCR1時(shí)通道1為有效電平,否則為無效電平;在向下計(jì)數(shù)時(shí),一旦TIMx_CNT>TIMx_CCR1時(shí)通道1為無效電平(OC1REF=0),否則為有效電平(OC1REF=1)。

111:PWM模式2-在向上計(jì)數(shù)時(shí),一旦TIMx_CNT<TIMx_CCR1時(shí)通道1為無效電平,否則為有效電平;在向下計(jì)數(shù)時(shí),一旦TIMx_CNT>TIMx_CCR1時(shí)通道1為有效電平,否則為無效電平。

由此看來,模式1和模式2正好互補(bǔ),互為相反,所以在運(yùn)用起來差別也并不太大。

而從計(jì)數(shù)模式上來看,PWM也和TIMx在作定時(shí)器時(shí)一樣,也有向上計(jì)數(shù)模式、向下計(jì)數(shù)模式和中心對(duì)齊模式,關(guān)于3種模式的具體資料,可以查看《STM32參考手冊(cè)》的“14.3.9 PWM模式”一節(jié),在此就不詳細(xì)贅述了。

?

1.2???PWM輸出管腳

PWM的輸出管腳是確定好的,具體的引腳功能可以查看《STM32參考手冊(cè)》的“8.3.7?定時(shí)器復(fù)用功能重映射”一節(jié)。在此需要強(qiáng)調(diào)的是,不同的TIMx有分配不同的引腳,但是考慮到管腳復(fù)用功能,STM32提出了一個(gè)重映像的概念,就是說通過設(shè)置某一些相關(guān)的寄存器,來使得在其他非原始指定的管腳上也能輸出PWM。但是這些重映像的管腳也是由參考手冊(cè)給出的。比如說TIM3的第2個(gè)通道,在沒有重映像的時(shí)候,指定的管腳是PA.7,如果設(shè)置部分重映像之后,TIM3_CH2的輸出就被映射到PB.5上了,如果設(shè)置了完全重映像的話,TIM3_CH2的輸出就被映射到PC.7上了。

?

1.3???PWM輸出信號(hào)

PWM輸出的是一個(gè)方波信號(hào),信號(hào)的頻率是由TIMx的時(shí)鐘頻率和TIMx_ARR預(yù)分頻器所決定的,具體設(shè)置方法在前面一個(gè)學(xué)習(xí)筆記中有詳細(xì)的交代。而輸出信號(hào)的占空比則是由TIMx_CRRx寄存器確定的。其公式為“占空比=(TIMx_CRRx/TIMx_ARR)*100%”,因此,可以通過向CRR中填入適當(dāng)?shù)臄?shù)來輸出自己所需的頻率和占空比的方波信號(hào)。

?

2.?????TIMER輸出PWM實(shí)現(xiàn)步驟

1.???????設(shè)置RCC時(shí)鐘;

2.???????設(shè)置GPIO時(shí)鐘;

3.???????設(shè)置TIMx定時(shí)器的相關(guān)寄存器;

4.???????設(shè)置TIMx定時(shí)器的PWM相關(guān)寄存器。

?

1步設(shè)置RCC時(shí)鐘已經(jīng)在前文中給出了詳細(xì)的代碼,在此就不再多說了。需要注意的是通用定時(shí)器TIMx是由APB1提供時(shí)鐘,而GPIO則是由APB2提供時(shí)鐘。注意,如果需要對(duì)PWM的輸出進(jìn)行重映像的話,還需要開啟引腳復(fù)用時(shí)鐘AFIO。

2步設(shè)置GPIO時(shí)鐘時(shí),GPIO模式應(yīng)該設(shè)置為復(fù)用推挽輸出GPIO_Mode_AF_PP,如果需要引腳重映像的話,則需要用GPIO_PinRemapConfig()函數(shù)進(jìn)行設(shè)置。

3步設(shè)置TIMx定時(shí)器的相關(guān)寄存器時(shí),和前一篇學(xué)習(xí)筆記一樣,設(shè)置好相關(guān)的TIMx的時(shí)鐘和技術(shù)模式等等。具體設(shè)置參看“TIMER基本定時(shí)功能”的學(xué)習(xí)筆記。

4步設(shè)置PWM相關(guān)寄存器,首先要設(shè)置PWM模式(默認(rèn)情況下PWM是凍結(jié)的),然后設(shè)置占空比(根據(jù)前面所述公式進(jìn)行計(jì)算),再設(shè)置輸出比較極性:當(dāng)設(shè)置為High時(shí),輸出信號(hào)不反相,當(dāng)設(shè)置為Low時(shí),輸出信號(hào)反相之后再輸出。最重要是是要使能TIMx的輸出狀態(tài)和使能TIMx的PWM輸出使能。

相關(guān)設(shè)置完成之后,就可以通過TIM_Cmd()來打開TIMx定時(shí)器,從而得到PWM輸出了。

?

3.?????TIMER輸出PWM源代碼

由于我現(xiàn)在手上的奮斗開發(fā)板是將PB.5接到LED上,因此需要使用TIM3的CH2通道,并且要進(jìn)行引腳重映像。打開TIM3之后,PWM輸出,使得LED點(diǎn)亮,通過改變PWM_cfg()中的占空比可以調(diào)節(jié)LED的亮度。

?

#include "stm32f10x_lib.h"

?

void RCC_cfg();

void GPIO_cfg();

void TIMER_cfg();

void PWM_cfg();

//占空比,取值范圍為0-100

int dutyfactor = 50;

?

int main()

{

?????int Temp;

???????RCC_cfg();

???????GPIO_cfg();

???????TIMER_cfg();

???????PWM_cfg();

?

???????//使能TIM3計(jì)時(shí)器,開始輸出PWM

???????TIM_Cmd(TIM3, ENABLE);

?

???????while(1);

}

?

void RCC_cfg()

{

???????//定義錯(cuò)誤狀態(tài)變量

???????ErrorStatus HSEStartUpStatus;

??????

???????//將RCC寄存器重新設(shè)置為默認(rèn)值

???????RCC_DeInit();

?

???????//打開外部高速時(shí)鐘晶振

???????RCC_HSEConfig(RCC_HSE_ON);

?

???????//等待外部高速時(shí)鐘晶振工作

???????HSEStartUpStatus = RCC_WaitForHSEStartUp();

???????if(HSEStartUpStatus == SUCCESS)

???????{

??????????????//設(shè)置AHB時(shí)鐘(HCLK)為系統(tǒng)時(shí)鐘

??????????????RCC_HCLKConfig(RCC_SYSCLK_Div1);

?

??????????????//設(shè)置高速AHB時(shí)鐘(APB2)為HCLK時(shí)鐘

??????????????RCC_PCLK2Config(RCC_HCLK_Div1);

?

??????????????//設(shè)置低速AHB時(shí)鐘(APB1)為HCLK的2分頻

??????????????RCC_PCLK1Config(RCC_HCLK_Div2);

?????????????

??????????????//設(shè)置FLASH代碼延時(shí)

??????????????FLASH_SetLatency(FLASH_Latency_2);

?

??????????????//使能預(yù)取指緩存

??????????????FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

?

??????????????//設(shè)置PLL時(shí)鐘,為HSE的9倍頻?8MHz * 9 = 72MHz

??????????????RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

?

??????????????//使能PLL

??????????????RCC_PLLCmd(ENABLE);

?

??????????????//等待PLL準(zhǔn)備就緒

??????????????while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);

?

??????????????//設(shè)置PLL為系統(tǒng)時(shí)鐘源

??????????????RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

?

??????????????//判斷PLL是否是系統(tǒng)時(shí)鐘

??????????????while(RCC_GetSYSCLKSource() != 0x08);

???????}

?

???????//開啟TIM3的時(shí)鐘

???????RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);

???????//開啟GPIOB的時(shí)鐘和復(fù)用功能

???????RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO,ENABLE);

?

}

?

void GPIO_cfg()

{

???????GPIO_InitTypeDef GPIO_InitStructure;

?

??????

???????//部分映射,將TIM3_CH2映射到PB5

//?????GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE);

???????GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);

?

???????//選擇引腳5

???????GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;

???????//輸出頻率最大50MHz????????????????????????????????????????????????????????

???????GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

???????//復(fù)用推挽輸出??????????????????????????????????????????????

??????GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;?

?

???????GPIO_Init(GPIOB,&GPIO_InitStructure);

}

?

void TIMER_cfg()

{

???????TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

?

???????//重新將Timer設(shè)置為缺省值

???????TIM_DeInit(TIM3);

???????//采用內(nèi)部時(shí)鐘給TIM3提供時(shí)鐘源

???????TIM_InternalClockConfig(TIM3);

???????//預(yù)分頻系數(shù)為0,即不進(jìn)行預(yù)分頻,此時(shí)TIMER的頻率為72MHz

???????TIM_TimeBaseStructure.TIM_Prescaler = 0;

???????//設(shè)置時(shí)鐘分割

???????TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;

???????//設(shè)置計(jì)數(shù)器模式為向上計(jì)數(shù)模式

???????TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

???????//設(shè)置計(jì)數(shù)溢出大小,每計(jì)7200個(gè)數(shù)就產(chǎn)生一個(gè)更新事件,即PWM的輸出頻率為10kHz

???????TIM_TimeBaseStructure.TIM_Period = 7200 - 1;

???????//將配置應(yīng)用到TIM3中

???????TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);

}

?

void PWM_cfg()

{

???????TIM_OCInitTypeDef TimOCInitStructure;

???????//設(shè)置缺省值

???????TIM_OCStructInit(&TimOCInitStructure);

???????//PWM模式1輸出

???????TimOCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;

???????//設(shè)置占空比,占空比=(CCRx/ARR)*100%或(TIM_Pulse/TIM_Period)*100%

???????TimOCInitStructure.TIM_Pulse = dutyfactor * 7200 / 100;

???????//TIM輸出比較極性高

???????TimOCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

???????//使能輸出狀態(tài)

???????TimOCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

???????//TIM3的CH2輸出

???????TIM_OC2Init(TIM3, &TimOCInitStructure);

???????//設(shè)置TIM3的PWM輸出為使能

???????TIM_CtrlPWMOutputs(TIM3,ENABLE);

}

轉(zhuǎn)載于:https://www.cnblogs.com/qsyll0916/p/6439615.html

總結(jié)

以上是生活随笔為你收集整理的【转载】 stm32之PWM的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。