久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 10558|回復: 1
打印 上一主題 下一主題
收起左側

Arduino學習4-Arduino軟件模擬PWM以及提高軟PWM效率

[復制鏈接]
跳轉到指定樓層
樓主
注:
1.這篇文章斷斷續續寫了很久,畫圖技術也不精,難免錯漏,大家湊合看.有問題可以留言.
2.論壇排版把我的代碼縮進全弄沒了,大家將代碼粘貼到arduino編譯器,然后按ctrl+T重新格式化代碼格式即可看的舒服.


一、什么是PWM

PWM即Pulse Wavelength Modulation脈寬調制波,通過調整輸出信號占空比,從而達到改變輸出平均電壓的目的。相信Arduino的PWM大家都不陌生,在Arduino Duemilanove 2009中,有6個8位精度PWM引腳,分別是3, 5, 6, 9, 10, 11腳。我們可以使用analogWrite()控制PWM腳輸出頻率大概在500Hz的左右的PWM調制波。分辨率8位即2的8次方等于256級精度。但是有時候我們會覺得6個PWM引腳不夠用。比如我們做一個10路燈調光,就需要有10個PWM腳。Arduino Duemilanove 2009有13個數字輸出腳,如果它們都可以PWM的話,就能滿足條件了。于是本文介紹用軟件模擬PWM。

二、Arduino軟件模擬PWM

Arduino PWM調壓原理:PWM有好幾種方法。而Arduino因為電源和實現難度限制,一般使用周期恒定,占空比變化的單極性PWM。
通過調整一個周期里面輸出腳高/低電平的時間比(即是占空比)去獲得給一個用電器不同的平均功率。

如圖所示,假設PWM波形周期1ms(即1kHz),分辨率1000級。那么需要一個信號時間精度1ms/1000=1us的信號源,即1MHz。所以說,PWM的實現難點在于需要使用很高頻的信號源,才能獲得快速與高精度。下面先由一個簡單的PWM程序開始:
  1.     const int PWMPin = 13;
  2.     int bright = 0;
  3.     void setup()
  4.     {
  5.         pinMode(PWMPin, OUTPUT);
  6.     }
  7.     void loop()
  8.     {
  9.         if((bright++) == 255) bright = 0;
  10.      
  11.         for(int i = 0; i < 255; i++)
  12.         {
  13.             if(i < bright)
  14.             {
  15.                 digitalWrite(PWMPin, HIGH);
  16.                 delayMicroseconds(30);
  17.             }
  18.             else
  19.             {
  20.                 digitalWrite(PWMPin, LOW);
  21.                 delayMicroseconds(30);
  22.             }
  23.         }
  24.     }
復制代碼

這是一個軟件PWM控制Arduino D13引腳的例子。只需要一塊Arduino即可測試此代碼。

程序解析:由for循環可以看出,完成一個PWM周期,共循環255次。
假設bright=100時候,在第0~100次循環中,i等于1到99均小于bright,于是輸出PWMPin高電平;
然后第100到255次循環里面,i等于100~255大于bright,于是輸出PWMPin低電平。無論輸出高低電平都保持30us。
那么說,如果bright=100的話,就有100次循環是高電平,155次循環是低電平。
如果忽略指令執行時間的話,這次的PWM波形占空比為100/255,如果調整bright的值,就能改變接在D13的LED的亮度。
這里設置了每次for循環之后,將bright加一,并且當bright加到255時歸0。所以,我們看到的最終效果就是LED慢慢變亮,到頂之后然后突然暗回去重新變亮。
這是最基本的PWM方法,也應該是大家想的比較多的想法。

然后介紹一個簡單一點的。思維風格完全不同。不過對于驅動一個LED來說,效果與上面的程序一樣。
  1.     const int PWMPin = 13;
  2.     int bright = 0;
  3.     void setup()
  4.     {
  5.         pinMode(PWMPin, OUTPUT);
  6.     }
  7.     void loop()
  8.     {
  9.         digitalWrite(PWMPin, HIGH);
  10.         delayMicroseconds(bright * 30);
  11.         digitalWrite(PWMPin, LOW);
  12.         delayMicroseconds((255 - bright) * 30);
  13.         if((bright++) == 255) bright = 0;
  14.     }
復制代碼

可以看出,這段代碼少了一個For循環。它先輸出一個高電平,然后維持(bright*30)us。然后輸出一個低電平,維持時間((255-bright)*30)us。這樣兩次高低就能完成一個PWM周期。分辨率也是255。

三、多引腳PWM

Arduino本身已有PWM引腳并且運行起來不占CPU時間,所以軟件模擬一個引腳的PWM完全沒有實用意義。我們軟件模擬的價值在于:他能將任意的數字IO口變成PWM引腳。當一片Arduino要同時控制多個PWM,并且沒有其他重任務的時候,就要用軟件PWM了。

多引腳PWM有一種下面的方式:
  1.     int brights[14] = {0}; //定義14個引腳的初始亮度,可以隨意設置
  2.     int StartPWMPin = 0, EndPWMPin = 13; //設置D0~D13為PWM引腳
  3.     int PWMResolution = 255; //設置PWM占空比分辨率
  4.      
  5.     void setup()
  6.     {
  7.         //定義所有IO端輸出
  8.         for(int i = StartPWMPin; i <= EndPWMPin; i++)
  9.         {
  10.             pinMode(i, OUTPUT);
  11.             //隨便定義個初始亮度,便于觀察
  12.             brights[ i ] = random(0, 255);
  13.         }
  14.     }
  15.     void loop()
  16.     {
  17.         //這for循環是為14盞燈做漸亮的。每次Arduino loop()循環,
  18.         //brights自增一次。直到brights=255時候,將brights置零重新計數。
  19.         for(int i = StartPWMPin; i <= EndPWMPin; i++)
  20.         {
  21.             if((brights[i]++) == PWMResolution) brights[i] = 0;
  22.         }
  23.      
  24.         for(int i = 0; i <= PWMResolution; i++) //i是計數一個PWM周期
  25.         {
  26.             for(int j = StartPWMPin; j <= EndPWMPin; j++) //每個PWM周期均遍歷所有引腳
  27.             {
  28.                 if(i < brights[j])
  29.                 {
  30.                     digitalWrite(j, HIGH);
  31.                     delayMicroseconds(2);
  32.                 }
  33.                 else
  34.                 {
  35.                     digitalWrite(j, LOW);
  36.                     delayMicroseconds(2);
  37.                 }
  38.             }
  39.         }
  40.     }
復制代碼

這個程序比較簡單,但是能演示基本的PWM功能。我們看loop(){}段,里面第一個for循環是做亮度漸增的,跟上面程序一樣,每次循環自增,然后到255就置零重來。下面的for循環是外層循環組成一個PWM周期的,每個周期用255次循環完成。就是說,PWM精度255級。

看內層for循環,每個PWM周期都包含由StartPWMPin到EndPWMPin的遍歷。就是說,按照brights數組里面的元素去設置每個引腳的PWM值。由于每個PWM周期都要遍歷14個引腳,所以我們使用的delayMicroseconds); 延時要降低到2us左右。每個PWM周期就是2usx14只腳=28us左右,在加上代碼執行時間誤差。大概與原來的30us接近了。

四、提高PWM速度
由上面可以看出,多引腳PWM的周期大致為
每引腳PWM周期=每引腳判定后延時*要PWM的引腳數*每周期PWM判定次數(PWM精度)
上面的代碼不包括指令執行時間,大概是2us x 14 x 255≈7ms=一個周期,頻率142Hz。如果使用Arduino Mega 2560這樣的大板,我們或者會用更多的引腳,比如32個。周期就變成2us x 32 x 255≈16ms一個周期,頻率就是62Hz了。大概實驗可以看到,如果周期超過12ms以上,驅動LED我們會看到明顯的閃爍。所以必須降低三個值中的隨便一個加快PWM速度。

所以我們要更改PWM周期的話,我們將精度(代碼里面的變量:PWMResolution)降低就行,比如一般調整LED亮度的話,我們用64級精度就行。這樣速度就是2x32x64=4ms。就不會閃了。


ArduinoPWM以及提高PWM性能代碼例子打包下載.rar (1.09 KB, 下載次數: 47)


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:296803 發表于 2018-4-21 08:18 | 只看該作者
PDE文檔怎么打開?
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 日韩视频二区 | 欧美一区二区激情三区 | 热99在线| 日韩免费网站 | 国产一级视频在线观看 | 欧美狠狠操 | 91免费视频 | 亚洲精品二区 | 成人av在线播放 | 超碰97免费观看 | 精品国产一区二区国模嫣然 | 国产精品久久久久无码av | 久久精品国产99国产精品亚洲 | 99精品免费在线观看 | 亚洲成人999 | www.天天操.com | 成人福利片 | 欧美一级二级视频 | 午夜91 | 国产一区2区 | 福利精品 | www.日本在线观看 | 国产乱码精品一品二品 | 成人免费观看男女羞羞视频 | 韩日一区二区 | 1000部精品久久久久久久久 | 日本成人久久 | 亚洲一二三区精品 | 日韩毛片在线观看 | 国产成人精品一区二区三区四区 | 免费啪啪 | 欧美一区二区三区大片 | 日韩三级在线 | 日韩av在线不卡 | 亚洲精品电影网在线观看 | 热99| 91免费小视频| 99福利视频导航 | 欧美成人免费在线视频 | 亚洲成人三级 | 日日日视频 |