一個(gè)可以同時(shí)用串口顯示字符和數(shù)字地C程序。我畢業(yè)設(shè)計(jì)中的一段。好使的。
標(biāo)簽: 串口顯示 C程序 字符 數(shù)字地
上傳時(shí)間: 2017-09-24
上傳用戶(hù):semi1981
可以不要看我可以不要看我可以不要看我可以不要看我可以不要看我可以不要看我可以不要看我
標(biāo)簽: 可以不要看我
上傳時(shí)間: 2015-12-21
上傳用戶(hù):wxxujian
這是我以前用過(guò) 的別人設(shè)計(jì)的已款MP3電路圖,感覺(jué)還可以
上傳時(shí)間: 2013-09-18
上傳用戶(hù):3到15
最近幾年新出的一些MCU,有很多都具有ISP(In System Programming:在系統(tǒng)編程)特性,利用這一特性可以在無(wú)需通用編程器的情況下,方便地對(duì)芯片執(zhí)行各種操作(擦除,讀取,編程等操作);如果進(jìn)一步配上一些軟件(如Keil的ISD51),即可實(shí)現(xiàn)一些簡(jiǎn)單的在線(xiàn)調(diào)試功能(當(dāng)然要損失一個(gè)串口)。一些開(kāi)發(fā)者,也經(jīng)常在自己的系統(tǒng)上預(yù)留ISP接口,以供日后升級(jí)之用。可以說(shuō)ISP的廣泛應(yīng)用,標(biāo)志著單片機(jī)開(kāi)發(fā)技術(shù)的進(jìn)步。 但是ISP功能的實(shí)現(xiàn)也有一定的限制,如需要一個(gè)串口,需要一定的駐留代碼空間,或者需要一定外部電路。于是有一些經(jīng)驗(yàn)不足的朋友,在實(shí)現(xiàn)ISP功能的時(shí)候便經(jīng)常出問(wèn)題,要么是外部電路的問(wèn)題,要么是串口的問(wèn)題。比如:為什么軟件老是報(bào)“通信出錯(cuò)”;為什么我的系統(tǒng),第一次可以進(jìn)ISP,第二次就不行了;為什么我在Win98下無(wú)法進(jìn)入ISP,換了WinXP就可以了。這些問(wèn)題總是出現(xiàn)于一些細(xì)微的地方,一些被人忽略的地方,如果你沒(méi)有充足的時(shí)間,充足的精力,充足的耐心去尋找這些根源;如果你有一臺(tái)CP900編程器(當(dāng)然其他的某些編程器也可以);如果你不想在那塊可憐的小電路板上,再擠進(jìn)一堆器件;如果你不想在購(gòu)料單上再增加一批Max232,或者一批xx型電容,yy型電阻,那么請(qǐng)使用ICP吧(InCircuit Programming:在電路編程)。
上傳時(shí)間: 2013-11-19
上傳用戶(hù):pol123
拿到這本教程您首先就會(huì)想,什么是IAP教學(xué)法?是不是一種什么全新的教學(xué)方法?當(dāng)然不是,我可沒(méi)有那么大的本事,其實(shí)這只是我杜撰的一個(gè)新名詞,意思就是InApplicationsProgram(在應(yīng)用中編程),當(dāng)然這只是針對(duì)單片機(jī)教學(xué),說(shuō)法是否正確,還得您說(shuō)了算。 至于為什么要提這種說(shuō)法,那我倒想說(shuō)幾句。大家都知道,學(xué)習(xí)電子技術(shù)是一件非常無(wú)聊和枯燥的事情,為什么會(huì)有這種想法,就是因?yàn)槲覀儌鹘y(tǒng)的教學(xué)方法只重理論而忽略了實(shí)踐,要一個(gè)人記住那些空洞而有無(wú)聊的理論知識(shí)實(shí)在不是一件容易的事,好在我們總算熬過(guò)來(lái)了,不管如何,也多多少少的學(xué)習(xí)了一些電子基礎(chǔ)知識(shí)。 接下來(lái)我們應(yīng)該進(jìn)一步掌握些什么知識(shí)呢,凡涉足此行的朋友都知道,那就是單片機(jī)。不過(guò)這可不是一件容易的事,倒不是因?yàn)閱纹瑱C(jī)很難學(xué),而實(shí)在是我們身邊很難找到一本專(zhuān)為單片機(jī)入門(mén)者而編寫(xiě)的教材。翻一下傳統(tǒng)的單片機(jī)教材,都好象是為已經(jīng)懂單片機(jī)的人而寫(xiě)的,一般總是以單片機(jī)的結(jié)構(gòu)為主線(xiàn),先講硬件原理,然后是指令,接著講軟件編程,再是系統(tǒng)擴(kuò)展和外圍器件,最后舉一些實(shí)例(隨便說(shuō)一點(diǎn):很多書(shū)中的實(shí)例都是有錯(cuò)誤的),很少涉及單片機(jī)的基礎(chǔ)知識(shí),如果按照此種學(xué)習(xí)方法,想進(jìn)行產(chǎn)品開(kāi)發(fā),就必須先把所有的知識(shí)全部掌握了才可以進(jìn)行實(shí)際應(yīng)用。孰不知,單片機(jī)不象模擬電路和數(shù)字電路那樣,只要搞懂了電路原理,再按照產(chǎn)品要求設(shè)計(jì)好相應(yīng)的電路就可以了。它是一種以簡(jiǎn)單的硬件結(jié)構(gòu),復(fù)雜而有靈活的軟件系統(tǒng)來(lái)完成設(shè)計(jì)的通用性產(chǎn)品,不同的設(shè)計(jì)者只會(huì)使用其不同的功能,幾乎沒(méi)有人會(huì)把它的全部指令都使用起來(lái),所以學(xué)習(xí)使用單片機(jī)只能靠循序漸進(jìn)的積累,而不可能先把它全部掌握了再去做產(chǎn)品開(kāi)發(fā)(當(dāng)然天才就例外了*_*)。 基于以上原因,本人想嘗試一種全新的單片機(jī)教學(xué)方法,打破傳統(tǒng)的循序漸進(jìn)式的教學(xué)方法,以單片機(jī)的應(yīng)用為藍(lán)本,結(jié)合基本的工業(yè)控制系統(tǒng)和實(shí)踐工作中的具體應(yīng)用,不分先后順序,將各條指令貫串于一個(gè)又一個(gè)的實(shí)驗(yàn)中,通過(guò)所見(jiàn)即所得的實(shí)驗(yàn)來(lái)講解各種指令的編程方法,順便講解相關(guān)的基本概念,使您盡快地熟悉單片機(jī)應(yīng)用的基本步驟,掌握軟件編程的基本方法。
上傳時(shí)間: 2014-02-27
上傳用戶(hù):shen_dafa
學(xué)習(xí)單片機(jī)總結(jié)寶典 基于本人學(xué)習(xí)單片機(jī)的痛苦經(jīng)歷,特編寫(xiě)本教程,以此獻(xiàn)給廣大 的單片機(jī)初學(xué)者,希望您能從中受益。 作者提示:本教程乃最通俗易懂之單片機(jī)教材也,如果您還是看 不懂,請(qǐng)千萬(wàn)不要涉足此行,以免誤入歧途,耽誤您的前程*_* 拿到這本教程您首先就會(huì)想,什么是 IAP 教學(xué)法?是不是一種什么全新的教學(xué)方法?當(dāng)然不是, 我可沒(méi)有那么大的本事,其實(shí)這只是我杜撰的一個(gè)新名詞,意思就是In Applications Program(在應(yīng) 用中編程),當(dāng)然這只是針對(duì)單片機(jī)教學(xué),說(shuō)法是否正確,還得您說(shuō)了算。 至于為什么要提這種說(shuō)法,那我倒想說(shuō)幾句。大家都知道,學(xué)習(xí)電子技術(shù)是一件非常無(wú)聊和枯燥 的事情,為什么會(huì)有這種想法,就是因?yàn)槲覀儌鹘y(tǒng)的教學(xué)方法只重理論而忽略了實(shí)踐,要一個(gè)人記住那 些空洞而有無(wú)聊的理論知識(shí)實(shí)在不是一件容易的事,好在我們總算熬過(guò)來(lái)了,不管如何,也多多少少的 學(xué)習(xí)了一些電子基礎(chǔ)知識(shí)。 接下來(lái)我們應(yīng)該進(jìn)一步掌握些什么知識(shí)呢,凡涉足此行的朋友都知道,那就是單片機(jī)。不過(guò)這可 不是一件容易的事,倒不是因?yàn)閱纹瑱C(jī)很難學(xué),而實(shí)在是我們身邊很難找到一本專(zhuān)為單片機(jī)入門(mén)者而編 寫(xiě)的教材。翻一下傳統(tǒng)的單片機(jī)教材,都好象是為已經(jīng)懂單片機(jī)的人而寫(xiě)的,一般總是以單片機(jī)的結(jié)構(gòu) 為主線(xiàn),先講硬件原理,然后是指令,接著講軟件編程,再是系統(tǒng)擴(kuò)展和外圍器件,最后舉一些實(shí)例(隨 便說(shuō)一點(diǎn):很多書(shū)中的實(shí)例都是有錯(cuò)誤的),很少涉及單片機(jī)的基礎(chǔ)知識(shí),如果按照此種學(xué)習(xí)方法,想 進(jìn)行產(chǎn)品開(kāi)發(fā),就必須先把所有的知識(shí)全部掌握了才可以進(jìn)行實(shí)際應(yīng)用。孰不知,單片機(jī)不象模擬電路 和數(shù)字電路那樣,只要搞懂了電路原理,再按照產(chǎn)品要求設(shè)計(jì)好相應(yīng)的電路就可以了。它是一種以簡(jiǎn)單 的硬件結(jié)構(gòu),復(fù)雜而有靈活的軟件系統(tǒng)來(lái)完成設(shè)計(jì)的通用性產(chǎn)品,不同的設(shè)計(jì)者只會(huì)使用其不同的功能, 幾乎沒(méi)有人會(huì)把它的全部指令都使用起來(lái),所以學(xué)習(xí)使用單片機(jī)只能靠循序漸進(jìn)的積累,而不可能先把 它全部掌握了再去做產(chǎn)品開(kāi)發(fā)(當(dāng)然天才就例外了*_*)。
上傳時(shí)間: 2013-10-15
上傳用戶(hù):小碼農(nóng)lz
地彈的形成:芯片內(nèi)部的地和芯片外的PCB地平面之間不可避免的會(huì)有一個(gè)小電感。這個(gè)小電感正是地彈產(chǎn)生的根源,同時(shí),地彈又是與芯片的負(fù)載情況密切相關(guān)的。下面結(jié)合圖介紹一下地彈現(xiàn)象的形成。 簡(jiǎn)單的構(gòu)造如上圖的一個(gè)小“場(chǎng)景”,芯片A為輸出芯片,芯片B為接收芯片,輸出端和輸入端很近。輸出芯片內(nèi)部的CMOS等輸入單元簡(jiǎn)單的等效為一個(gè)單刀雙擲開(kāi)關(guān),RH和RL分別為高電平輸出阻抗和低電平輸出阻抗,均設(shè)為20歐。GNDA為芯片A內(nèi)部的地。GNDPCB為芯片外PCB地平面。由于芯片內(nèi)部的地要通過(guò)芯片內(nèi)的引線(xiàn)和管腳才能接到GNDPCB,所以就會(huì)引入一個(gè)小電感LG,假設(shè)這個(gè)值為1nH。CR為接收端管腳電容,這個(gè)值取6pF。這個(gè)信號(hào)的頻率取200MHz。雖然這個(gè)LG和CR都是很小的值,不過(guò),通過(guò)后面的計(jì)算我們可以看到它們對(duì)信號(hào)的影響。先假設(shè)A芯片只有一個(gè)輸出腳,現(xiàn)在Q輸出高電平,接收端的CR上積累電荷。當(dāng)Q輸出變?yōu)榈碗娖降臅r(shí)候。CR、RL、LG形成一個(gè)放電回路。自諧振周期約為490ps,頻率為2GHz,Q值約為0.0065。使用EWB建一個(gè)仿真電路。(很老的一個(gè)軟件,很多人已經(jīng)不懈于使用了。不過(guò)我個(gè)人比較依賴(lài)它,關(guān)鍵是建模,模型參數(shù)建立正確的話(huà)仿真結(jié)果還是很可靠的,這個(gè)小軟件幫我發(fā)現(xiàn)和解決過(guò)很多實(shí)際模擬電路中遇到的問(wèn)題。這個(gè)軟件比較小,有比較長(zhǎng)的歷史,也比較成熟,很容易上手。建議電子初入門(mén)的同學(xué)還是熟悉一下。)因?yàn)橹魂P(guān)注下降沿,所以簡(jiǎn)單的構(gòu)建下面一個(gè)電路。起初輸出高電平,10納秒后輸出低電平。為方便起見(jiàn),高電平輸出設(shè)為3.3V,低電平是0V。(實(shí)際200M以上芯片IO電壓會(huì)比較低,多采用1.5-2.5V。)
標(biāo)簽: 分
上傳時(shí)間: 2013-10-17
上傳用戶(hù):zhishenglu
第1 章 體系結(jié)構(gòu) ARM經(jīng)典300問(wèn)與答第1 問(wèn):Q:請(qǐng)問(wèn)在初始化CPU 堆棧的時(shí)候一開(kāi)始在執(zhí)行mov r0, LR 這句指令時(shí)處理器是什么模式A:復(fù)位后的模式,即管理模式.第2 問(wèn):Q:請(qǐng)教:MOV 中的8 位圖立即數(shù),是怎么一回事 0xF0000001 是怎么來(lái)的A:是循環(huán)右移,就是一個(gè)0—255 之間的數(shù)左移或右移偶數(shù)位的來(lái)的,也就是這個(gè)數(shù)除以4一直除, 直到在0-255 的范圍內(nèi)它是整數(shù)就說(shuō)明是可以的!A:8 位數(shù)(0-255)循環(huán)左移或循環(huán)右移偶數(shù)位得到的,F0000001 既是0x1F 循環(huán)右移4 位,符合規(guī)范,所以是正確的.這樣做是因?yàn)橹噶铋L(zhǎng)度的限制,不可能把32 位立即數(shù)放在32 位的指令中.移位偶數(shù)也是這個(gè)原因.可以看一看ARM 體系結(jié)構(gòu)(ADS 自帶的英文文檔)的相關(guān)部分.第3 問(wèn):Q:請(qǐng)教:《ARM 微控制器基礎(chǔ)與實(shí)戰(zhàn)》2.2.1 節(jié)關(guān)于第2 個(gè)操作數(shù)的描述中有這么一段:#inmed_8r 常數(shù)表達(dá)式.該常數(shù)必須對(duì)應(yīng)8 位位圖,即常熟是由一個(gè)8 位的常數(shù)循環(huán)移位偶數(shù)位得到.合法常量:0x3FC,0,0xF0000000,200,0xF0000001.非法常量:0x1FE,511,0xFFFF,0x1010,0xF0000010.常數(shù)表達(dá)式應(yīng)用舉例:......LDR R0,[R1],#-4 ;讀取 R1 地址上的存儲(chǔ)器單元內(nèi)容,且 R1 = R1-4針對(duì)這一段,我的疑問(wèn):1. 即常數(shù)是由一個(gè)8 位的常數(shù)循環(huán)移位偶數(shù)位得到,這句話(huà)如何理解2. 該常數(shù)必須對(duì)應(yīng)8 位位圖,既然是8 位位圖,那么取值為0-255,怎么0x3FC 這種超出255 的數(shù)是合法常量呢3. 所舉例子中,合法常量和非法常量是怎么區(qū)分的 如0x3FC 合法,而0x1FE 卻非法0xF0000000,0xF0000001 都合法,而0xF0000010 又變成了非法4. 對(duì)于匯編語(yǔ)句 LDR R0,[R1],#-4,是先將R1 的值減4 結(jié)果存入R1,然后讀取R1 所指單元的 值到R0,還是先讀取R1 到R0,然后再將R1 減4 結(jié)果存入R1A:提示,任何常數(shù)都可用底數(shù)*2 的n 次冪 來(lái)表示.1. ARM 結(jié)構(gòu)中,只有8bits 用來(lái)表示底數(shù),因此底數(shù)必須是8 位位圖.2. 8 位位圖循環(huán)之后得到常數(shù),并非只能是8 位.3. 0xF0000010 底數(shù)是9 位,不能表示.4. LDR R0, [R1], #-4 是后索引,即先讀,再減.可以看一看ARM 體系結(jié)構(gòu)對(duì)相關(guān)尋址方式的說(shuō)明.
上傳時(shí)間: 2013-11-22
上傳用戶(hù):1109003457
注:1.這篇文章斷斷續(xù)續(xù)寫(xiě)了很久,畫(huà)圖技術(shù)也不精,難免錯(cuò)漏,大家湊合看.有問(wèn)題可以留言. 2.論壇排版把我的代碼縮進(jìn)全弄沒(méi)了,大家將代碼粘貼到arduino編譯器,然后按ctrl+T重新格式化代碼格式即可看的舒服. 一、什么是PWM PWM 即Pulse Wavelength Modulation 脈寬調(diào)制波,通過(guò)調(diào)整輸出信號(hào)占空比,從而達(dá)到改 變輸出平均電壓的目的。相信Arduino 的PWM 大家都不陌生,在Arduino Duemilanove 2009 中,有6 個(gè)8 位精度PWM 引腳,分別是3, 5, 6, 9, 10, 11 腳。我們可以使用analogWrite()控 制PWM 腳輸出頻率大概在500Hz 的左右的PWM 調(diào)制波。分辨率8 位即2 的8 次方等于 256 級(jí)精度。但是有時(shí)候我們會(huì)覺(jué)得6 個(gè)PWM 引腳不夠用。比如我們做一個(gè)10 路燈調(diào)光, 就需要有10 個(gè)PWM 腳。Arduino Duemilanove 2009 有13 個(gè)數(shù)字輸出腳,如果它們都可以 PWM 的話(huà),就能滿(mǎn)足條件了。于是本文介紹用軟件模擬PWM。 二、Arduino 軟件模擬PWM Arduino PWM 調(diào)壓原理:PWM 有好幾種方法。而Arduino 因?yàn)殡娫春蛯?shí)現(xiàn)難度限制,一般 使用周期恒定,占空比變化的單極性PWM。 通過(guò)調(diào)整一個(gè)周期里面輸出腳高/低電平的時(shí)間比(即是占空比)去獲得給一個(gè)用電器不同 的平均功率。 如圖所示,假設(shè)PWM 波形周期1ms(即1kHz),分辨率1000 級(jí)。那么需要一個(gè)信號(hào)時(shí)間 精度1ms/1000=1us 的信號(hào)源,即1MHz。所以說(shuō),PWM 的實(shí)現(xiàn)難點(diǎn)在于需要使用很高頻的 信號(hào)源,才能獲得快速與高精度。下面先由一個(gè)簡(jiǎn)單的PWM 程序開(kāi)始: const int PWMPin = 13; int bright = 0; void setup() { pinMode(PWMPin, OUTPUT); } void loop() { if((bright++) == 255) bright = 0; for(int i = 0; i < 255; i++) { if(i < bright) { digitalWrite(PWMPin, HIGH); delayMicroseconds(30); } else { digitalWrite(PWMPin, LOW); delayMicroseconds(30); } } } 這是一個(gè)軟件PWM 控制Arduino D13 引腳的例子。只需要一塊Arduino 即可測(cè)試此代碼。 程序解析:由for 循環(huán)可以看出,完成一個(gè)PWM 周期,共循環(huán)255 次。 假設(shè)bright=100 時(shí)候,在第0~100 次循環(huán)中,i 等于1 到99 均小于bright,于是輸出PWMPin 高電平; 然后第100 到255 次循環(huán)里面,i 等于100~255 大于bright,于是輸出PWMPin 低電平。無(wú) 論輸出高低電平都保持30us。 那么說(shuō),如果bright=100 的話(huà),就有100 次循環(huán)是高電平,155 次循環(huán)是低電平。 如果忽略指令執(zhí)行時(shí)間的話(huà),這次的PWM 波形占空比為100/255,如果調(diào)整bright 的值, 就能改變接在D13 的LED 的亮度。 這里設(shè)置了每次for 循環(huán)之后,將bright 加一,并且當(dāng)bright 加到255 時(shí)歸0。所以,我們 看到的最終效果就是LED 慢慢變亮,到頂之后然后突然暗回去重新變亮。 這是最基本的PWM 方法,也應(yīng)該是大家想的比較多的想法。 然后介紹一個(gè)簡(jiǎn)單一點(diǎn)的。思維風(fēng)格完全不同。不過(guò)對(duì)于驅(qū)動(dòng)一個(gè)LED 來(lái)說(shuō),效果與上面 的程序一樣。 const int PWMPin = 13; int bright = 0; void setup() { pinMode(PWMPin, OUTPUT); } void loop() { digitalWrite(PWMPin, HIGH); delayMicroseconds(bright*30); digitalWrite(PWMPin, LOW); delayMicroseconds((255 - bright)*30); if((bright++) == 255) bright = 0; } 可以看出,這段代碼少了一個(gè)For 循環(huán)。它先輸出一個(gè)高電平,然后維持(bright*30)us。然 后輸出一個(gè)低電平,維持時(shí)間((255-bright)*30)us。這樣兩次高低就能完成一個(gè)PWM 周期。 分辨率也是255。 三、多引腳PWM Arduino 本身已有PWM 引腳并且運(yùn)行起來(lái)不占CPU 時(shí)間,所以軟件模擬一個(gè)引腳的PWM 完全沒(méi)有實(shí)用意義。我們軟件模擬的價(jià)值在于:他能將任意的數(shù)字IO 口變成PWM 引腳。 當(dāng)一片Arduino 要同時(shí)控制多個(gè)PWM,并且沒(méi)有其他重任務(wù)的時(shí)候,就要用軟件PWM 了。 多引腳PWM 有一種下面的方式: int brights[14] = {0}; //定義14個(gè)引腳的初始亮度,可以隨意設(shè)置 int StartPWMPin = 0, EndPWMPin = 13; //設(shè)置D0~D13為PWM 引腳 int PWMResolution = 255; //設(shè)置PWM 占空比分辨率 void setup() { //定義所有IO 端輸出 for(int i = StartPWMPin; i <= EndPWMPin; i++) { pinMode(i, OUTPUT); //隨便定義個(gè)初始亮度,便于觀察 brights[ i ] = random(0, 255); } } void loop() { //這for 循環(huán)是為14盞燈做漸亮的。每次Arduino loop()循環(huán), //brights 自增一次。直到brights=255時(shí)候,將brights 置零重新計(jì)數(shù)。 for(int i = StartPWMPin; i <= EndPWMPin; i++) { if((brights[i]++) == PWMResolution) brights[i] = 0; } for(int i = 0; i <= PWMResolution; i++) //i 是計(jì)數(shù)一個(gè)PWM 周期 { for(int j = StartPWMPin; j <= EndPWMPin; j++) //每個(gè)PWM 周期均遍歷所有引腳 { if(i < brights[j])\ 所以我們要更改PWM 周期的話(huà),我們將精度(代碼里面的變量:PWMResolution)降低就行,比如一般調(diào)整LED 亮度的話(huà),我們用64 級(jí)精度就行。這樣速度就是2x32x64=4ms。就不會(huì)閃了。
上傳時(shí)間: 2013-10-08
上傳用戶(hù):dingdingcandy
注:1.這篇文章斷斷續(xù)續(xù)寫(xiě)了很久,畫(huà)圖技術(shù)也不精,難免錯(cuò)漏,大家湊合看.有問(wèn)題可以留言. 2.論壇排版把我的代碼縮進(jìn)全弄沒(méi)了,大家將代碼粘貼到arduino編譯器,然后按ctrl+T重新格式化代碼格式即可看的舒服. 一、什么是PWM PWM 即Pulse Wavelength Modulation 脈寬調(diào)制波,通過(guò)調(diào)整輸出信號(hào)占空比,從而達(dá)到改 變輸出平均電壓的目的。相信Arduino 的PWM 大家都不陌生,在Arduino Duemilanove 2009 中,有6 個(gè)8 位精度PWM 引腳,分別是3, 5, 6, 9, 10, 11 腳。我們可以使用analogWrite()控 制PWM 腳輸出頻率大概在500Hz 的左右的PWM 調(diào)制波。分辨率8 位即2 的8 次方等于 256 級(jí)精度。但是有時(shí)候我們會(huì)覺(jué)得6 個(gè)PWM 引腳不夠用。比如我們做一個(gè)10 路燈調(diào)光, 就需要有10 個(gè)PWM 腳。Arduino Duemilanove 2009 有13 個(gè)數(shù)字輸出腳,如果它們都可以 PWM 的話(huà),就能滿(mǎn)足條件了。于是本文介紹用軟件模擬PWM。 二、Arduino 軟件模擬PWM Arduino PWM 調(diào)壓原理:PWM 有好幾種方法。而Arduino 因?yàn)殡娫春蛯?shí)現(xiàn)難度限制,一般 使用周期恒定,占空比變化的單極性PWM。 通過(guò)調(diào)整一個(gè)周期里面輸出腳高/低電平的時(shí)間比(即是占空比)去獲得給一個(gè)用電器不同 的平均功率。 如圖所示,假設(shè)PWM 波形周期1ms(即1kHz),分辨率1000 級(jí)。那么需要一個(gè)信號(hào)時(shí)間 精度1ms/1000=1us 的信號(hào)源,即1MHz。所以說(shuō),PWM 的實(shí)現(xiàn)難點(diǎn)在于需要使用很高頻的 信號(hào)源,才能獲得快速與高精度。下面先由一個(gè)簡(jiǎn)單的PWM 程序開(kāi)始: const int PWMPin = 13; int bright = 0; void setup() { pinMode(PWMPin, OUTPUT); } void loop() { if((bright++) == 255) bright = 0; for(int i = 0; i < 255; i++) { if(i < bright) { digitalWrite(PWMPin, HIGH); delayMicroseconds(30); } else { digitalWrite(PWMPin, LOW); delayMicroseconds(30); } } } 這是一個(gè)軟件PWM 控制Arduino D13 引腳的例子。只需要一塊Arduino 即可測(cè)試此代碼。 程序解析:由for 循環(huán)可以看出,完成一個(gè)PWM 周期,共循環(huán)255 次。 假設(shè)bright=100 時(shí)候,在第0~100 次循環(huán)中,i 等于1 到99 均小于bright,于是輸出PWMPin 高電平; 然后第100 到255 次循環(huán)里面,i 等于100~255 大于bright,于是輸出PWMPin 低電平。無(wú) 論輸出高低電平都保持30us。 那么說(shuō),如果bright=100 的話(huà),就有100 次循環(huán)是高電平,155 次循環(huán)是低電平。 如果忽略指令執(zhí)行時(shí)間的話(huà),這次的PWM 波形占空比為100/255,如果調(diào)整bright 的值, 就能改變接在D13 的LED 的亮度。 這里設(shè)置了每次for 循環(huán)之后,將bright 加一,并且當(dāng)bright 加到255 時(shí)歸0。所以,我們 看到的最終效果就是LED 慢慢變亮,到頂之后然后突然暗回去重新變亮。 這是最基本的PWM 方法,也應(yīng)該是大家想的比較多的想法。 然后介紹一個(gè)簡(jiǎn)單一點(diǎn)的。思維風(fēng)格完全不同。不過(guò)對(duì)于驅(qū)動(dòng)一個(gè)LED 來(lái)說(shuō),效果與上面 的程序一樣。 const int PWMPin = 13; int bright = 0; void setup() { pinMode(PWMPin, OUTPUT); } void loop() { digitalWrite(PWMPin, HIGH); delayMicroseconds(bright*30); digitalWrite(PWMPin, LOW); delayMicroseconds((255 - bright)*30); if((bright++) == 255) bright = 0; } 可以看出,這段代碼少了一個(gè)For 循環(huán)。它先輸出一個(gè)高電平,然后維持(bright*30)us。然 后輸出一個(gè)低電平,維持時(shí)間((255-bright)*30)us。這樣兩次高低就能完成一個(gè)PWM 周期。 分辨率也是255。 三、多引腳PWM Arduino 本身已有PWM 引腳并且運(yùn)行起來(lái)不占CPU 時(shí)間,所以軟件模擬一個(gè)引腳的PWM 完全沒(méi)有實(shí)用意義。我們軟件模擬的價(jià)值在于:他能將任意的數(shù)字IO 口變成PWM 引腳。 當(dāng)一片Arduino 要同時(shí)控制多個(gè)PWM,并且沒(méi)有其他重任務(wù)的時(shí)候,就要用軟件PWM 了。 多引腳PWM 有一種下面的方式: int brights[14] = {0}; //定義14個(gè)引腳的初始亮度,可以隨意設(shè)置 int StartPWMPin = 0, EndPWMPin = 13; //設(shè)置D0~D13為PWM 引腳 int PWMResolution = 255; //設(shè)置PWM 占空比分辨率 void setup() { //定義所有IO 端輸出 for(int i = StartPWMPin; i <= EndPWMPin; i++) { pinMode(i, OUTPUT); //隨便定義個(gè)初始亮度,便于觀察 brights[ i ] = random(0, 255); } } void loop() { //這for 循環(huán)是為14盞燈做漸亮的。每次Arduino loop()循環(huán), //brights 自增一次。直到brights=255時(shí)候,將brights 置零重新計(jì)數(shù)。 for(int i = StartPWMPin; i <= EndPWMPin; i++) { if((brights[i]++) == PWMResolution) brights[i] = 0; } for(int i = 0; i <= PWMResolution; i++) //i 是計(jì)數(shù)一個(gè)PWM 周期 { for(int j = StartPWMPin; j <= EndPWMPin; j++) //每個(gè)PWM 周期均遍歷所有引腳 { if(i < brights[j])\ 所以我們要更改PWM 周期的話(huà),我們將精度(代碼里面的變量:PWMResolution)降低就行,比如一般調(diào)整LED 亮度的話(huà),我們用64 級(jí)精度就行。這樣速度就是2x32x64=4ms。就不會(huì)閃了。
上傳時(shí)間: 2013-10-23
上傳用戶(hù):mqien
蟲(chóng)蟲(chóng)下載站版權(quán)所有 京ICP備2021023401號(hào)-1