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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

单片机_PWM输出原理详解

發(fā)布時(shí)間:2024/3/7 编程问答 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 单片机_PWM输出原理详解 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

單片機(jī)_PWM輸出原理詳解

理論篇
??博主自己的經(jīng)歷告訴我,PWM波的理解和應(yīng)用確實(shí)還是挺重要的,這里專門花一期詳細(xì)介紹一下

  • 什么是PWM?

??PWM,英文名Pulse Width Modulation,是脈沖寬度調(diào)制縮寫,它是通過(guò)對(duì)一系列脈沖的寬度進(jìn)行調(diào)制,等效出所需要的波形(包含形狀以及幅值),對(duì)模擬信號(hào)電平進(jìn)行數(shù)字編碼。
??通俗的說(shuō),就是控制在一個(gè)周期內(nèi),控制高電平多長(zhǎng)時(shí)間,低電平多長(zhǎng)時(shí)間(前面文章種有說(shuō)過(guò)IO口就只有兩種狀態(tài),0和1,對(duì)應(yīng)就是0和5V或者0和3.3V)。也就是說(shuō)通過(guò)調(diào)節(jié)高低電平時(shí)間的變化來(lái)調(diào)節(jié)信號(hào)、能量等的變化。

??圖為周期4毫秒的PWM波形

  • 兩個(gè)重要的概念,頻率、占空比

??頻率是指每秒鐘信號(hào)從高電平到低電平再回到高電平的次數(shù),為一個(gè)PWM波周期的倒數(shù)。上圖中頻率=1/(0.003+0.001)=250 HZ
??占空比是指高電平持續(xù)時(shí)間比一個(gè)周期持續(xù)的時(shí)間。上圖中占空比=1/(1+3)=25%,所以可以通過(guò)控制占空比,來(lái)控制輸出的等效電壓。
??所以對(duì)于方波的話,頻率和占空比就確定了一個(gè)波。

  • 怎么能產(chǎn)生一個(gè)PWM波?

??方法1:利用芯片內(nèi)部模塊輸出PWM信號(hào),STM32 的定時(shí)器除了 TIM6 和 7。其他的定時(shí)器都可以用來(lái)產(chǎn)生 PWM 輸出。其中高級(jí)定時(shí)器 TIM1 和 TIM8 可以同時(shí)產(chǎn)生多達(dá) 7 路的 PWM 輸出。而通用定時(shí)器也能同時(shí)產(chǎn)生多達(dá) 4路的 PWM 輸出,這樣, STM32 最多可以同時(shí)產(chǎn)生 30 路 PWM 輸出! 但是!!!同一個(gè)定時(shí)器TIM只能產(chǎn)生一個(gè)頻率的PWM波,你只能改變占空比。 具體例程見一下實(shí)戰(zhàn)篇STM32部分。
??方法2:利用IO口高低電平轉(zhuǎn)變輸出PWM信號(hào),比如上圖中先把電平置1,維持1ms,然后將電平拉低,維持3ms,再將電平置高,如此循環(huán)往復(fù)下去,就可以產(chǎn)生一個(gè)周期4毫秒占空比為25%的PWM波了。具體方法就是給IO口加一個(gè)定時(shí)器,用定時(shí)器中斷來(lái)實(shí)現(xiàn)及時(shí)切換高低電平。 具體歷程見以下51單片機(jī)部分。

  • 定時(shí)器

??要想使用51單片機(jī)來(lái)產(chǎn)生一路PWM,根據(jù)上述的方法2,首先你應(yīng)該知道什么是定時(shí)器?定時(shí)器是怎么工作的?

??定時(shí)器:和計(jì)數(shù)器說(shuō)的是一個(gè)東西,因?yàn)樗饶苡?jì)時(shí)也能計(jì)數(shù)。定時(shí)器的實(shí)質(zhì)是,由機(jī)器頻率向一個(gè)16位寄存器累加,累加滿溢出時(shí)觸發(fā)中斷。為了產(chǎn)生一個(gè)我們想要的時(shí)間間隔。比如說(shuō)1s,所以我們要在這個(gè)寄存器里設(shè)定一個(gè)初值,以至于讓它在這個(gè)初值上累加可以產(chǎn)生一個(gè)1s的倍數(shù)。這樣我們就得到了穩(wěn)定的時(shí)間間隔。
??這個(gè)寄存器分為TH(高八位)和TL(低八位)。所以我們需要把計(jì)算好的初值分成兩部分分別放入TH和TL。

??過(guò)程
??首先,我們通過(guò)單片機(jī)的晶振頻率得知其時(shí)鐘周期,再尤其乘以12得到機(jī)器周期。每一個(gè)機(jī)器周期在寄存器內(nèi)+1,直到加滿溢出產(chǎn)生中斷。

??舉例說(shuō)明
??若單片機(jī)頻率為12Mhz,其時(shí)鐘周期就是1/12μs,機(jī)器周期為1μs,也就是每1μs寄存器+1。16位的寄存器加到溢出最多需要(2^16)-1=65535μs,溢出也需要一個(gè)機(jī)器周期,所以總共要65536μs。但這個(gè)值太別扭,和我們要的1s沒什么關(guān)系。我們最好讓它記50000μs產(chǎn)生一次中斷,所以其初值就設(shè)為65536-50000=15536。但我們還要將這個(gè)值分別放在高八位和低八位,所以要將這個(gè)十進(jìn)制數(shù),轉(zhuǎn)換為4位十六進(jìn)制數(shù)再分開賦值。十進(jìn)制計(jì)算法:TH = 15536/256; TL = 15536%256;,進(jìn)制計(jì)算問題這里不細(xì)討論。這樣的話,每50ms就會(huì)產(chǎn)生一次中斷。我們只要用程序判斷其中斷20次就記1s。
??定時(shí)器部分摘自:https://www.jianshu.com/p/90ea43a7b4fd

  • PWM的應(yīng)用

1 輸出模擬電壓(通過(guò)電壓的高低來(lái)控制如LED的亮度,直流電機(jī)的速度等)
??PWM對(duì)模擬信號(hào)電平進(jìn)行數(shù)字編碼的方法,計(jì)算機(jī)只能輸出0或5V的數(shù)字電壓值而不能輸出模擬電壓,而我們?nèi)绻氆@得一個(gè)模擬電壓值(介于0 - 5V的電壓值),則需通過(guò)使用高分辨率計(jì)數(shù)器,改變方波的占空比來(lái)對(duì)一個(gè)模擬信號(hào)的電平進(jìn)行編碼。電壓是以一種連接(1)或斷開(0)的重復(fù)脈沖序列被夾到模擬負(fù)載上去的,連接即是直流供電輸出,斷開即是直流供電斷開。通過(guò)對(duì)連接和斷開時(shí)間的控制,只要帶寬足夠,可以輸出任意不大于最大電壓值的模擬電壓。

??輸出電壓=(接通時(shí)間/脈沖時(shí)間)*最大電壓值12


?? PWM輸出等效電壓
解釋部分引自 http://www.eeworld.com.cn/mcu/article_2018061939827.html

2 控制舵機(jī)
??大一大二期間做項(xiàng)目經(jīng)常用到的一個(gè)元件就是舵機(jī),而舵機(jī)的控制就是通過(guò)一個(gè)固定周期但是不同占空比來(lái)控制舵機(jī)擺角的位置的。
??舵機(jī)的控制一般需要一個(gè)20ms左右的時(shí)基脈沖(頻率為50HZ),該脈沖的高電平部分一般為0.5ms-2.5ms范圍內(nèi)的角度控制脈沖部分,總間隔為2ms。以180度角度伺服為例,那么對(duì)應(yīng)的控制關(guān)系是這樣的:
0.5ms--------------0度;
1.0ms------------45度;
1.5ms------------90度;
2.0ms-----------135度;
2.5ms-----------180度;

此圖可以表現(xiàn)脈沖寬度(也可以轉(zhuǎn)換成占空比)和舵機(jī)擺臂的位置圖
3 控制步進(jìn)電機(jī)
??之前在做項(xiàng)目的過(guò)程中,一般涉及到精確控制位移的時(shí)候,這個(gè)時(shí)候往復(fù)式驅(qū)動(dòng)原件(舵機(jī))就不適合了,所以就會(huì)經(jīng)常用到步進(jìn)電機(jī)。
??步進(jìn)電機(jī)把電脈沖信號(hào)變換成角位移以控制轉(zhuǎn)子轉(zhuǎn)動(dòng)的微特電機(jī)。在自動(dòng)控制裝置中作為執(zhí)行元件。每輸入一個(gè)脈沖信號(hào),步進(jìn)電動(dòng)機(jī)前進(jìn)一步,故又稱脈沖電動(dòng)機(jī)。 !!!這里注意一點(diǎn),直接控制單片機(jī)的話是脈沖控制,就是進(jìn)來(lái)一個(gè)脈沖信號(hào),步進(jìn)電機(jī)轉(zhuǎn)動(dòng)一個(gè)步進(jìn)角(一般為1.8°)。所以控制步進(jìn)電機(jī)速度的方式就是通過(guò)控制 頻率 (占空比一般都是50%)但是!!!現(xiàn)在可以通過(guò)接入步進(jìn)電機(jī)驅(qū)動(dòng)板的方式(比如博主之前使用的一款步進(jìn)電機(jī)驅(qū)動(dòng)板Tb6560)細(xì)分步進(jìn)角。比如細(xì)分為2,一個(gè)脈沖步進(jìn)電機(jī)就轉(zhuǎn)動(dòng)半個(gè)脈沖(0.9°)

PS:這里由于篇幅原因,舵機(jī)、步進(jìn)電機(jī)的控制代碼就不上傳了,網(wǎng)上一搜一大堆,也可以聯(lián)系博主私法給你嘍!


實(shí)戰(zhàn)篇

??這里使用51和STM32實(shí)現(xiàn)呼吸燈的功能,同樣原理也可以控制直流電機(jī),舵機(jī)是頻率一定的情況下控制占空比來(lái)控制擺臂的方向,而步進(jìn)電機(jī)是通過(guò)控制頻率的方式來(lái)控制速度。

51部分
??例程使用51單片機(jī)將P1.0接一個(gè)二極管。運(yùn)用PWM輸出等效模擬電壓完成呼吸燈功能。引

unsigned char PWM_COUNT; //計(jì)數(shù) unsigned int HUXI_COUNT; //占空比更新時(shí)間 unsigned char PWM_VLAUE; //占空比比對(duì)值 bit direc_flag; //占空比更新方向void timer0_init() {TMOD=0x02; //模式設(shè)置,00010000,定時(shí)器0,工作于模式2(M1=1,M0=0)TH0=0x47; //定時(shí)器溢出值設(shè)置,每隔200us發(fā)起一次中斷。TL0=0X47;TR0=1; //定時(shí)器0開始計(jì)時(shí)ET0=1; //開定時(shí)器0中斷EA=1; //開總中斷PWM_COUNT =0; }void time0() interrupt 1 { PWM_COUNT++;HUXI_COUNT++;if(PWM_COUNT == PWM_VLAUE) //判斷是否到了點(diǎn)亮LED的時(shí)候LED = 1; //點(diǎn)亮LEDif(PWM_COUNT == 10) //當(dāng)前周期結(jié)束{LED = 0; //熄滅LEDPWM_COUNT = 0; //重新計(jì)時(shí)}if((HUXI_COUNT == 600) && (direc_flag == 0)){ //占空比增加10%HUXI_COUNT = 0;PWM_VLAUE++;if(PWM_VLAUE == 9) //占空比更改方向direc_flag = 1; }if((HUXI_COUNT == 600) && (direc_flag == 1)){ //占空比減少10%HUXI_COUNT = 0;PWM_VLAUE--;if(PWM_VLAUE == 1) //占空比更改方向direc_flag = 0; } } void main() {HUXI_COUNT = 0;PWM_COUNT = 0;PWM_VLAUE = 5;direc_flag = 0;LED = 1; //默認(rèn)LED熄滅 timer0_init(); //定時(shí)器0初始化while(1); }

??例程部分引自 http://www.eeworld.com.cn/mcu/article_2018061939827.html 有刪改

32部分
??轉(zhuǎn)自正點(diǎn)原子庫(kù)函數(shù)手冊(cè)PWM部分教程
??這里用到了 TIM3 的部分重映射功能(重映射:可以理解成把管腳的外設(shè)功能映射到另一個(gè)管腳,具體哪個(gè)引腳可以映射見參考手冊(cè)), 例程把 TIM3_CH2 直接映射到了 PB5 上。

//TIM3 PWM 部分初始化 //PWM 輸出初始化 //arr:自動(dòng)重裝值 //psc:時(shí)鐘預(yù)分頻數(shù) 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); //①使能定時(shí)器 3 時(shí)鐘RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE); //①使能 GPIO 和 AFIO 復(fù)用功能時(shí)鐘GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //②重映射 TIM3_CH2->PB5//設(shè)置該引腳為復(fù)用輸出功能,輸出 TIM3 CH2 的 PWM 脈沖波形 GPIOB.5GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //TIM_CH2GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復(fù)用推挽輸出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure); //①初始化 GPIO//初始化 TIM3TIM_TimeBaseStructure.TIM_Period = arr; //設(shè)置在自動(dòng)重裝載周期值TIM_TimeBaseStructure.TIM_Prescaler =psc; //設(shè)置預(yù)分頻值TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設(shè)置時(shí)鐘分割:TDTS = Tck_timTIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM 向上計(jì)數(shù)模式TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //③初始化 TIMx//初始化 TIM3 Channel2 PWM 模式TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //選擇 PWM 模式 2TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //輸出極性高TIM_OC2Init(TIM3, &TIM_OCInitStructure); //④初始化外設(shè) TIM3 OC2TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能預(yù)裝載寄存器TIM_Cmd(TIM3, ENABLE); //⑤使能 TIM3 }int main(void) {u16 led0pwmval=0;u8 dir=1;delay_init(); //延時(shí)函數(shù)初始化NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設(shè)置 NVIC 中斷分組 2uart_init(115200); //串口初始化波特率為 115200LED_Init(); //LED 端口初始化TIM3_PWM_Init(899,0); //不分頻,PWM 頻率=72000/900=80Khzwhile(1){delay_ms(10);if(dir)led0pwmval++;else led0pwmval--;if(led0pwmval>300)dir=0;if(led0pwmval==0)dir=1;TIM_SetCompare2(TIM3,led0pwmval);} } //實(shí)驗(yàn)現(xiàn)象:我們將看 DS0 不停的由暗變到亮,然后又從亮變到暗。每個(gè)過(guò)程持續(xù)時(shí)間大概為 3 秒鐘左右。

皮一下,歡迎交流啊! 共同學(xué)習(xí),共同進(jìn)步。

總結(jié)

以上是生活随笔為你收集整理的单片机_PWM输出原理详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

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