嵌入式分享合集26
折騰一天攝像頭煩四了 弄點這個把 我們這邊還有個sb還fa值 罰款的值嗎 搞笑+
一、開關電源的8個損耗
能量轉換系統必定存在能耗,雖然實際應用中無法獲得100%的轉換效率,但是,一個高質量的電源效率可以達到非常高的水平,效率接近95%。絕大多數電源IC 的工作效率可以在特定的工作條件下測得,數據資料中給出了這些參數。一般廠商會給出實際測量的結果,但我們只能對我們自己的數據擔保。
????下圖1給出了一個SMPS降壓轉換器的電路實例,轉換效率可以達到97%,即使在輕載時也能保持較高效率。采用什么秘訣才能達到如此高的效率?我們最好從了解SMPS損耗的公共問題開始,開關電源的損耗大部分來自開關器件(MOSFET和二極管),另外小部分損耗來自電感和電容。但是,如果使用非常廉價的電感和電容(具有較高電阻),將會導致損耗明顯增大。
????選擇IC時,需要考慮控制器的架構和內部元件,以期獲得高效指標。例如,圖1采用了多種方法來降低損耗,其中包括:同步整流,芯片內部集成低導通電阻的MOSFET,低靜態電流和跳脈沖控制模式。我們將在本文展開討論這些措施帶來的好處。
????上圖,圖1:降壓轉換器集成了低導通電阻的MOSFET,采用同步整流,效率曲線如上。
● 降壓型SMPS
????損耗是任何SMPS架構都面臨的問題,我們在此以下圖2所示降壓型(或buck)轉換器為例進行討論,圖中標明各點的開關波形,用于后續計算。
????上圖,圖2。
????降壓轉換器的主要功能是把一個較高的直流輸入電壓轉換成較低的直流輸出電壓。為了達到這個要求,MOSFET以固定頻率(fS),在脈寬調制信號(PWM)的控制下進行開、關操作。當MOSFET導通時,輸入電壓給電感和電容(L和COUT)充電,通過它們把能量傳遞給負載。在此期間,電感電流線性上升,電流回路如圖2 中的回路1所示。
????當MOSFET斷開時,輸入電壓斷開與電感的連接,電感和輸出電容為負載供電。電感電流線性下降,電流流過二極管,電流回路如圖中的環路2所示。MOSFET的導通時間定義為PWM信號的占空比(D)。D把每個開關周期分成[D × tS]和[(1 - D) × tS]兩部分,它們分別對應于MOSFET的導通時間(環路1)和二極管的導通時間(環路2)。所有SMPS拓撲(降壓、反相等)都采用這種方式劃分開關周期,實現電壓轉換。
????對于降壓轉換電路,較大的占空比將向負載傳輸較多的能量,平均輸出電壓增加。相反,占空比較低時,平均輸出電壓也會降低。根據這個關系,可以得到以下理想情況下(不考慮二極管或MOSFET的壓降)降壓型SMPS的轉換公式:
VOUT?= D × VIN
IIN?= D × IOUT
????需要注意的是,任何SMPS在一個開關周期內處于某個狀態的時間越長,那么它在這個狀態所造成的損耗也越大。對于降壓型轉換器,D越低(相應的VOUT越低),回路2產生的損耗也大。
1、開關器件的損耗MOSFET傳導損耗
????上文,圖2(以及其它絕大多數DC-DC轉換器拓撲)中的MOSFET 和二極管是造成功耗的主要因素。相關損耗主要包括兩部分:傳導損耗和開關損耗。
??? MOSFET和二極管是開關元件,導通時電流流過回路。器件導通時,傳導損耗分別由MOSFET的導通電阻(RDS(ON))和二極管的正向導通電壓決定。
????MOSFET的傳導損耗(PCOND(MOSFET))近似等于導通電阻RDS(ON)、占空比(D)和導通時MOSFET的平均電流(IMOSFET(AVG))的乘積。
????PCOND(MOSFET)?(使用平均電流) = IMOSFET(AVG)2 × RDS(ON)?× D
????上式給出了SMPS 中MOSFET 傳導損耗的近似值,但它只作為電路損耗的估算值,因為電流線性上升時所產生的功耗大于由平均電流計算得到的功耗。對于“峰值”電流,更準確的計算方法是對電流峰值和谷值(圖3中的IV 和IP)之間的電流波形的平方進行積分得到估算值。?
????上圖,圖3:典型的降壓型轉換器的MOSFET 電流波形,用于估算MOSFET 的傳導損耗。
????下式給出了更準確的估算損耗的方法,利用IP 和IV 之間電流波形I2的積分替代簡單的I2項。
PCOND(MOSFET)?= [(IP3?- IV3)/3] × RDS(ON)?× D
= [(IP3?- IV3)/3] × RDS(ON)?× VOUT/VIN
????式中,IP 和IV 分別對應于電流波形的峰值和谷值,如圖3 所示。MOSFET 電流從IV 線性上升到IP,例如:如果IV 為0.25A,IP 為1.75A,RDS(ON)為0.1Ω,VOUT?為VIN/2 (D = 0.5),基于平均電流(1A)的計算結果為:
PCOND(MOSFET) (使用平均電流) = 12?× 0.1 × 0.5 = 0.050W
????利用波形積分進行更準確的計算:
PCOND(MOSFET)?(使用電流波形積分進行計算) = [(1.753?- 0.253)/3] × 0.1 × 0.5 = 0.089W
????或近似為78%,高于按照平均電流計算得到的結果。對于峰均比較小的電流波形,兩種計算結果的差別很小,利用平均電流計算即可滿足要求。
2、二極管傳導損耗
????MOSFET 的傳導損耗與RDS(ON)成正比,二極管的傳導損耗則在很大程度上取決于正向導通電壓(VF)。二極管通常比MOSFET 損耗更大,二極管損耗與正向電流、VF 和導通時間成正比。由于MOSFET 斷開時二極管導通,二極管的傳導損耗(PCOND(DIODE))近似為:
PCOND(DIODE)?= IDIODE(ON)?× VF × (1 - D)
????式中,IDIODE(ON)為二極管導通期間的平均電流。圖2 所示,二極管導通期間的平均電流為IOUT,因此,對于降壓型轉換器,PCOND(DIODE)可以按照下式估算:
PCOND(DIODE)?= IOUT?× VF × (1 - VOUT/VIN)
????與MOSFET 功耗計算不同,采用平均電流即可得到比較準確的功耗計算結果,因為二極管損耗與I 成正比,而不是I2。
????顯然,MOSFET或二極管的導通時間越長,傳導損耗也越大。對于降壓型轉換器,輸出電壓越低,二極管產生的功耗也越大,因為它處于導通狀態的時間越長。
3、開關動態損耗
????由于開關損耗是由開關的非理想狀態引起的,很難估算MOSFET和二極管的開關損耗,器件從完全導通到完全關閉或從完全關閉到完全導通需要一定時間,在這個過程中會產生功率損耗。圖4所示MOSFET 的漏源電壓(VDS)和漏源電流(IDS)的關系圖可以很好地解釋MOSFET 在過渡過程中的開關損耗,從上半部分波形可以看出,tSW(ON)和tSW(OFF)期間電壓和電流發生瞬變,MOSFET 的電容進行充電、放電。
????圖4所示,VDS?降到最終導通狀態(= ID × RDS(ON))之前,滿負荷電流(ID)流過MOSFET。相反,關斷時,VDS?在MOSFET電流下降到零值之前逐漸上升到關斷狀態的最終值。開關過程中,電壓和電流的交疊部分即為造成開關損耗的來源,從圖4 可以清楚地看到這一點。
????上圖,圖4:開關損耗發生在MOSFET 通、斷期間的過渡過程。
????開關損耗隨著SMPS頻率的升高而增大,這一點很容易理解,隨著開關頻率提高(周期縮短),開關過渡時間所占比例增大,從而增大開關損耗。開關轉換過程中,開關時間是占空比的二十分之一對于效率的影響要遠遠小于開關時間為占空比的十分之一的情況。由于開關損耗和頻率有很大的關系,工作在高頻時,開關損耗將成為主要的損耗因素。MOSFET 的開關損耗(PSW(MOSFET))可以按照圖3 所示三角波進行估算,公式如下:
PSW(MOSFET)?= 0.5 × VD × ID × (tSW(ON)?+ tSW(OFF)) × fS
????其中,VD為MOSFET關斷期間的漏源電壓,ID是MOSFET導通期間的溝道電流,tSW(ON)和tSW(OFF)是導通和關斷時間。對于降壓電路轉換,VIN?是MOSFET關斷時的電壓,導通時的電流為IOUT。
????為了驗證MOSFET的開關損耗和傳導損耗,圖5給出了降壓轉換器中集成高端MOSFET的典型波形:VDS和IDS。電路參數為:VIN?= 10V、VOUT?= 3.3V、IOUT?= 500mA、RDS(ON)?= 0.1Ω、fS?= 1MHz、開關瞬變時間(tON?+ tOFF)總計為38ns。
????在下圖5,可以看出,開關變化不是瞬間完成的,電流和電壓波形交疊部分導致功率損耗。MOSFET“導通”時(圖2),流過電感的電流IDS 線性上升,與導通邊沿相比,斷開時的開關損耗更大。
????利用上述近似計算法,MOSFET的平均損耗可以由下式計算:
PT(MOSFET)?= PCOND(MOSFET)?+ PSW(MOSFET)
= [(I13?- I03)/3] × RDS(ON)?× VOUT/VIN?+ 0.5 × VIN?× IOUT?× (tSW(ON)?+ tSW(OFF)) × fS
= [(13?- 03)/3] × 0.1 × 3.3/10 + 0.5 × 10 × 0.5 × (38 × 10-9) × 1 × 106
= 0.011 + 0.095 = 106mW
????這一結果與圖5下方曲線測量得到的117.4mW接近。
????注意:這種情況下,fS?足夠高,PSW(MOSFET)是功耗的主要因素。?
????上圖,圖5:降壓轉換器高端MOSFET的典型開關周期,輸入10V、輸出3.3V (輸出電流500mA)。開關頻率為1MHz,開關轉換時間是38ns。
????與MOSFET相同,二極管也存在開關損耗。這個損耗很大程度上取決于二極管的反向恢復時間(tRR),二極管開關損耗發生在二極管從正向導通到反向截止的轉換過程。
????當反向電壓加在二級管兩端時,正向導通電流在二極管上產生的累積電荷需要釋放,產生反向電流尖峰(IRR(PEAK)),極性與正向導通電流相反,從而造成V × I 功率損耗,因為反向恢復期內,反向電壓和反向電流同時存在于二極管。圖6給出了二極管在反向恢復期間的PN結示意圖:?
????上圖,圖6:二極管結反偏時,需要釋放正向導通期間的累積電荷,產生峰值電流(IRR(PEAK))。
????了解了二極管的反向恢復特性,可以由下式估算二極管的開關損耗(PSW(DIODE)):
PSW(DIODE)?= 0.5 × VREVERSE?× IRR(PEAK)?× tRR2?× fS
????其中,VREVERSE?是二極管的反向偏置電壓,IRR(PEAK)是反向恢復電流的峰值,tRR2?是從反向電流峰值IRR?到恢復電流為正的時間。對于降壓電路,當MOSFET 導通的時候,VIN?為MOSFET 導通時二極管的反向偏置電壓。
????為了驗證二極管損耗計算公式,圖7 顯示了典型的降壓轉換器中PN 結的開關波形,VIN?= 10V、VOUT =3.3V,測得IRR(PEAK)?= 250mA、IOUT?= 500mA、fS?= 1MHz、 tRR2?= 28ns、VF = 0.9V。利用這些數值可以得到:
?????該結果接近于圖7所示測量結果358.7mW。考慮到較大的VF和較長的二極管導通周期,tRR?時間非常短,開關損耗(PSW(DIODE))在二極管損耗中占主導地位。
????上圖,圖7:降壓型轉換器中PN 結開關二極管的開關波形,從10V 輸入降至3.3V 輸出,輸出電流為500mA。其它參數包括:1MHz 的fS,tRR2 為28ns,VF = 0.9V。
● 提高效率
????基于上述討論,通過哪些途徑可以降低電源的開關損耗呢?直接途徑是:選擇低導通電阻RDS(ON)、可快速切換的MOSFET;選擇低導通壓降VF、可快速恢復的二極管。
????直接影響MOSFET 導通電阻的因素有幾點,通常增加芯片尺寸和漏源極擊穿電壓(VBR(DSS)),由于增加了器件中的半導體材料,有助于降低導通電阻RDS(ON)。另一方面,較大的MOSFET會增大開關損耗。因此,雖然大尺寸MOSFET降低了RDS(ON),但也導致小器件可以避免的效率問題。當管芯溫度升高時,MOSFET導通電阻會相應增大。必須保持較低的結溫,使導通電阻RDS(ON)不會過大。導通電阻RDS(ON)和柵源偏置電壓成反比。
????因此,推薦使用足夠大的柵極電壓以降低RDS(ON)損耗,但此時也會增大柵極驅動損耗,需要平衡降低RDS(ON)的好處和增大柵極驅動的缺陷。MOSFET的開關損耗與器件電容有關,較大的電容需要較長的充電時間,使開關切換變緩,消耗更多能量。米勒電容通常在MOSFET數據資料中定義為反向傳輸電容(CRSS)或柵-漏電容(CGD),在開關過程中對切換時間起決定作用。米勒電容的充電電荷用QGD表示,為了快速切換MOSFET,要求盡可能低的米勒電容。
????一般來說,MOSFET的電容和芯片尺寸成反比,因此必須折衷考慮開關損耗和傳導損耗,同時也要謹慎選擇電路的開關頻率。對于二極管,必須降低導通壓降,以降低由此產生的損耗。對于小尺寸、額定電壓較低的硅二極管,導通壓降一般在0.7V到1.5V之間。二極管的尺寸、工藝和耐壓等級都會影響導通壓降和反向恢復時間,大尺寸二極管通常具有較高的VF 和tRR,這會造成比較大的損耗。
????開關二極管一般以速度劃分,分為“高速”、“甚高速”和“超高速”二極管,反向恢復時間隨著速度的提高而降低。快恢復二極管的tRR?為幾百納秒,而超高速快恢復二極管的tRR?為幾十納秒。低功耗應用中,替代快恢復二極管的一種選擇是肖特基二極管,這種二極管的恢復時間幾乎可以忽略,反向恢復電壓VF 也只有快恢復二極管的一半(0.4V 至1V),但肖特基二極管的額定電壓和電流遠遠低于快恢復二極管,無法用于高壓或大功率應用。另外,肖特基二極管與硅二極管相比具有較高的反向漏電流,但這些因素并不限制它在許多電源中的應用。
????然而,在一些低壓應用中,即便是具有較低壓降的肖特基二極管,所產生的傳導損耗也無法接受。比如,在輸出為1.5V 的電路中,即使使用0.5V 導通壓降VF 的肖特基二極管,二極管導通時也會產生33%的輸出電壓損耗!
????為了解決這一問題,可以選擇低導通電阻RDS(ON)的MOSFET實現同步控制架構。用MOSFET 取代二極管(對比圖1 和圖2 電路),它與電源的主MOSFET 同步工作,所以在交替切換的過程中,保證只有一個導通。導通的二極管由導通的MOSFET 所替代,二極管的高導通壓降VF 被轉換成MOSFET 的低導通壓降(MOSFET RDS(ON)?× I),有效降低了二極管的傳導損耗。
????當然,同步整流與二極管相比也只是降低了MOSFET的壓降,另一方面,驅動同步整流MOSFET的功耗也不容忽略。IC數據資料以上討論了影響開關電源效率的兩個重要因素(MOSFET 和二極管)。回顧圖1所示降壓電路,從數據資料中可以獲得影響控制器IC 工作效率的主要因素。
????首先,開關元件集成在IC內部,可以節省空間、降低寄生損耗。其次,使用低導通電阻RDS(ON)的MOSFET,在小尺寸集成降壓IC (如MAX1556)中,其NMOS和PMOS 的導通電阻可以達到0.27Ω (典型值)和0.19Ω (典型值)。最后,使用的同步整流電路。對于500mA負載,占空比為50%的開關電路,可以將低邊開關(或二極管)的損耗從225mW (假設二極管壓降為 1V)降至 34mW。合理選擇SMPS IC合理選擇 SMPS IC的封裝、控制架構,并進行合理設計,可以有效提高轉換效率。
4、集成功率開關
????功率開關集成到IC 內部時可以省去繁瑣的MOSFET 或二極管選擇,而且使電路更加緊湊,由于降低了線路損耗和寄生效應,可以在一定程度上提高效率。根據功率等級和電壓限制,可以把MOSFET、二極管(或同步整流MOSFET)集成到芯片內部。將開關集成到芯片內部的另一個好處是柵極驅動電路的尺寸已經針對片內MOSFET 進行了優化,因而無需將時間浪費在未知的分立MOSFET 上。
● 靜態電流
????電池供電設備特別關注IC 規格中的靜態電流(IQ),它是維持電路工作所需的電流。重載情況下(大于十倍或百倍的靜態電流IQ),IQ 對效率的影響并不明顯,因為負載電流遠大于IQ,而隨著負載電流的降低,效率有下降的趨勢,因為IQ 對應的功率占總功率的比例提高。
????這一點對于大多數時間處于休眠模式或其它低功耗模式的應用尤其重要,許多消費類產品即使在“關閉”狀態下,也需要保持鍵盤掃描或其它功能的供電,這時,無疑需要選擇具有極低IQ的電源。
● 電源架構對效率的提高
??? SMPS 的控制架構是影響開關電源效率的關鍵因素之一。這一點我們已經在同步整流架構中討論過,由于采用低導通電阻的MOSFET 取代了功耗較大的開關二極管,可有效改善效率指標。
????另一種重要的控制架構是針對輕載工作或較寬的負載范圍設計的,即跳脈沖模式,也稱為脈沖頻率調制(PFM)。與單純的PWM 開關操作(在重載和輕載時均采用固定的開關頻率)不同,跳脈沖模式下轉換器工作在跳躍的開關周期,可以節省不必要的開關操作,進而提高效率。
????跳脈沖模式下,在一段較長時間內電感放電,將能量從電感傳遞給負載,以維持輸出電壓。當然,隨著負載吸收電流,輸出電壓也會跌落。當電壓跌落到設置門限時,將開啟一個新的開關周期,為電感充電并補充輸出電壓。
????需要注意的是跳脈沖模式會產生與負載相關的輸出噪聲,這些噪聲由于分布在不同頻率(與固定頻率的PWM 控制架構不同),很難濾除。
????先進的SMPS IC 會合理利用兩者的優勢:重載時采用恒定PWM 頻率;輕載時采用跳脈沖模式以提高效率,圖1 所示IC即提供了這樣的工作模式。
????當負載增加到一個較高的有效值時,跳脈沖波形將轉換到固定PWM,在標稱負載下噪聲很容易濾除。在整個工作范圍內,器件根據需要選擇跳脈沖模式和PWM 模式,保持整體的最高效率(圖8)。
????下圖8中的曲線D、E、F所示效率曲線在固定PWM模式下,輕載時效率較低,但在重載時能夠提供很高的轉換效率(高達98%)。如果設置在輕載下保持固定PWM 工作模式,IC將不會按照負載情況更改工作模式。這種情況下能夠使紋波保持在固定頻率,但浪費了一定功率。重載時,維持PWM 開關操作所需的額外功率很小,遠遠低于輸出功率。
????另一方面,跳脈沖“空閑”模式下的效率曲線(圖8中的A、B、C)能夠在輕載時保持在較高水平,因為開關只在負載需要時開啟。對7V輸入曲線,在1mA負載的空閑模式下能夠獲得高于60%的效率。
????上圖,圖8:降壓轉換器在PWM 和空閑(跳脈沖)模式下效率曲線,注意:輕載時,空閑模式下的效率高于PWM模式。
-
優化SMPS
????開關電源因其高效率指標得到廣泛應用,但其效率仍然受SMPS電路的一些固有損耗的制約。設計開關電源時,需要仔細研究造成SMPS損耗的來源,合理選擇SMPS IC,從而充分利用器件的優勢,為了在保持盡可能低的電路成本,甚至不增加電路成本的前提下獲得高效的SMPS,工程師需要做出全面的選擇。
5、無源元件損耗
????我們已經了解MOSFET和二極管會導致SMPS損耗。采用高品質的開關器件能夠大大提升效率,但它們并不是唯一能夠優化電源效率的元件。
????圖1詳細介紹了一個典型的降壓型轉換器IC的基本電路。集成了兩個同步整流MOSFET,低RDS(ON)?MOSFET,效率很高。這個電路中,開關元件集成在IC內部,已經為具體應用預先選擇了元器件。然而,為了進一步提高效率,設計人員還需關注無源元件—外部電感和電容,了解它們對功耗的影響。
6、電感功耗阻性損耗
????電感功耗包括線圈損耗和磁芯損耗兩個基本因素,線圈損耗歸結于線圈的直流電阻(DCR),磁芯損耗歸結于電感的磁特性。
??? DCR 定義為以下電阻公式:
????式中,ρ為線圈材料的電阻系數,l為線圈長度,A為線圈橫截面積。
??? DCR將隨著線圈長度的增大而增大,隨著線圈橫截面積的增大而減小。可以利用該原則判斷標準電感,確定所要求的不同電感值和尺寸。對一個固定的電感值,電感尺寸較小時,為了保持相同匝數必須減小線圈的橫截面積,因此導致DCR增大;對于給定的電感尺寸,小電感值通常對應于小的DCR,因為較少的線圈數減少了線圈長度,可以使用線徑較粗的導線。
????已知DCR和平均電感電流(具體取決于SMPS 拓撲),電感的電阻損耗(PL(DCR))可以用下式估算:
PL(DCR)?= LAVG2× DCR
????這里,IL(AVG)是流過電感的平均直流電流。對于降壓轉換器,平均電感電流是直流輸出電流。盡管DCR的大小直接影響電感電阻的功耗,該功耗與電感電流的平方成正比,因此,減小DCR 是必要的。
????另外,還需要注意的是:利用電感的平均電流計算PL(DCR)?(如上述公式)時,得到的結果略低于實際損耗,因為實際電感電流為三角波。本文前面介紹的MOSFET 傳導損耗計算中,利用對電感電流的波形進行積分可以獲得更準確的結果。更準確。當然也更復雜的計算公式如下:
PL(DCR)?= (IP3?- IV3)/3 × DCR
????式中IP 和IV 為電感電流波形的峰值和谷值。
7、磁芯損耗
????磁芯損耗并不像傳導損耗那樣容易估算,很難估測。它由磁滯、渦流損耗組成,直接影響鐵芯的交變磁通。SMPS 中,盡管平均直流電流流過電感,由于通過電感的開關電壓的變化產生的紋波電流導致磁芯周期性的磁通變化。
????磁滯損耗源于每個交流周期中磁芯偶極子的重新排列所消耗的功率,可以將其看作磁場極性變化時偶極子相互摩擦產生的“摩擦”損耗,正比于頻率和磁通密度。
????相反,渦流損耗則是磁芯中的時變磁通量引入的。由法拉第定律可知:交變磁通產生交變電壓。因此,這個交變電壓會產生局部電流,在磁芯電阻上產生I2R 損耗。
????磁芯材料對磁芯損耗的影響很大。SMPS 電源中普遍使用的電感是鐵粉磁芯,鐵鎳鉬磁粉芯(MPP)的損耗最低,鐵粉芯成本最低,但磁芯損耗較大。
????磁芯損耗可以通過計算磁芯磁通密度(B)的最大變化量估算,然后查看電感或鐵芯制造商提供的磁通密度和磁芯損耗(和頻率)圖表。峰值磁通密度可以通過幾種方式計算,公式可以在電感數據資料中的磁芯損耗曲線中找到。
????相應地,如果磁芯面積和線圈數已知,可利用下式估計峰值磁通:?
????這里,B 是峰值磁通密度(高斯),L 是線圈電感(亨),ΔI 是電感紋波電流峰峰值(安培),A 是磁芯橫截面積(cm2),N 是線圈匝數。
????隨著互聯網的普及,可以方便地從網上下載資料、搜索器件信息,一些制造商提供了交互式電感功耗的計算軟件,幫助設計者估計功耗。使用這些工具能夠快捷、準確地估計應用電路中的功率損耗。例如,Coilcraft 提供的在線電感磁芯損耗和銅耗計算公式,簡單輸入一些數據即可得到所選電感的磁芯損耗和銅耗。
8、電容損耗
????與理想的電容模型相反,電容元件的實際物理特性導致了幾種損耗。電容在SMPS 電路中主要起穩壓、濾除輸入/輸出噪聲的作用(圖1),電容的這些損耗降低了開關電源的效率。這些損耗主要表現在三個方面:等效串聯電阻損耗、漏電流損耗和電介質損耗。
????電容的阻性損耗顯而易見。既然電流在每個開關周期流入、流出電容,電容固有的電阻(RC)將造成一定功耗。漏電流損耗是由于電容絕緣材料的電阻(RL)導致較小電流流過電容而產生的功率損耗。電介質損耗比較復雜,由于電容兩端施加了交流電壓,電容電場發生變化,從而使電介質分子極化造成功率損耗。
????上圖,圖9:電容損耗模型一般簡化為一個等效串聯電阻(ESR)。
????所有三種損耗都體現在電容的典型損耗模型中(圖9 左邊部分),用電阻代表每項損耗。與電容儲能相關的每項損耗的功率用功耗系數(DF)表示,或損耗角正切(δ)。每項損耗的DF 可以通過由電容阻抗的實部與虛部比得到,可以將每項損耗分別插入模型中。
????為簡化損耗模型,圖9中的接觸電阻損耗、漏電流損耗和電介質損耗集中等為一個等效串聯電阻(ESR)。ESR 定義為電容阻抗中消耗有功功率的部分。
????推算電容阻抗模型、計算ESR (結果的實部)時,ESR 是頻率的函數。這種相關性可以在下面簡化的ESR等式中得到證明:
????式中,DFR、DFL 和DFD 是接觸電阻、漏電流和電介質損耗的功耗系數。
????利用這個等式,我們可以觀察到隨著信號頻率的增加,漏電流損耗和電介質損耗都有所減小,直到接觸電阻損耗從一個較高頻點開始占主導地位。在該頻點(式中沒有包括該參數)以上,ESR 因為高頻交流電流的趨膚效應趨于增大。
????許多電容制造商提供ESR 曲線圖表示ESR 與頻率的關系。例如,TDK 為其大多數電容產品提供了ESR 曲線,參考這些與開關頻率對應曲線圖,得到ESR 值。
????然而,如果沒有ESR 曲線圖,可以通過電容數據資料中的DF 規格粗略估算ESR。DF 是電容的整體DF (包括所有損耗),也可以按照下式估算ESR:?
????無論采用哪種方法來得到ESR 值,直覺告訴我們,高ESR 會降低開關電源效率,既然輸入和輸出電容在每個開關周期通過ESR 充電、放電。這導致I2× RESR 功率損耗。這個損耗(PCAP(ESR))可以按照下式計算:
PCAP(ESR)?= ICAP(RMS)2?×?RESR
????式中,ICAP(RMS)是流經電容的交流電流有效值RMS。對降壓電路的輸出電容,可以采用電感紋波電流的有效值RMS。輸入濾波電容的RMS 電流的計算比較復雜,可以按照下式得到一個合理的估算值:
ICIN(RMS)?= IOUT/VIN?× [VOUT?(VIN?- VOUT)]1/2
????顯然,為減小電容功率損耗,應選擇低ESR 電容,有助于SMPS 電源降低紋波電流。ESR 是產生輸出電壓紋波的主要原因,因此選擇低ESR 的電容不僅僅單純提高效率,還能得到其它好處。
????一般來說,不同類型電介質的電容具有不同的ESR 等級。對于特定的容量和額定電壓,鋁電解電容和鉭電容就比陶瓷電容具有更高的ESR 值。聚酯和聚丙烯電容的ESR 值介于它們之間,但這些電容尺寸較大,SMPS 中很少使用。whaosoft aiot?http://143ai.com
????對于給定類型的電容,較大容量、較低的fS 能夠提供較低的ESR。大尺寸電容通常也會降低ESR,但電解電容會帶來較大的等效串聯電感。陶瓷電容被視為比較好的折中選擇,此外,電容值一定的條件下,較低的電容額定電壓也有助于減小ESR。
二、單片機工作電壓5V的來歷
5V來自于TTL電平。5為True,0為False,之后用了壓降更低的PN節,衍生出了3.3這個電平。
??? 12V和24V來自于汽車電瓶,早年乘用車又12V和24V兩個系統,現在一般小型車12V,商用車24V,再究其由來應該是鉛酸電池。
????所以3.3V和5V一般出現在信號電路或者單片機等VCC供電,而12V/24V一般出現在低壓動力電,例如主板、顯卡、軸流風機、監控器。硬件決定系統基礎,如果鋰電池早點應用的話估計還會有3.7/7.4這個系統。
????為什么很多單片機的工作電壓是5v?
????因為大多數芯片都是5V的TTL電平,要做到電平兼容,電平匹配,避免要電平轉換操作,所有很多單片機的工作電壓都是5V。早期(196x)的晶體管電路(TTL)單管的壓降是0.7V。一個電路里經常有多個晶體管串聯。比如4管串聯,電源至少保證0.7x4=2.8v才能保證電路正常工作。所以最早有3V 5V等標準。后來LM7805(197x)電源IC出來以后,5V成了事實標準。
??? TTL指的是TTL電平,0~5V之間,小于0.2V輸出低電平,高于3.4V輸出高電平。全稱Transistor-Transistor Logic,即BJT-BJT邏輯門電路,是數字電子技術中常用的一種邏輯門電路,應用較早,技術已比較成熟。TTL主要有BJT(Bipolar Junction Transistor 即雙極結型晶體管,晶體三極管)和電阻構成,具有速度快的特點。最早的TTL門電路是74系列,后來出現了74H系列,74L系列,74LS,74AS,74ALS等系列。
????但是由于TTL功耗大等缺點,正逐漸被CMOS電路取代,TL輸出高電平》2.4V,輸出低電平《0.4V。在室溫下,一般輸出高電平是3.5V,輸出低電平是0.2V。最小輸入高電平和低電平:輸入高電平》=2.0V,輸入低電平《=0.8V,噪聲容限是0.4V。
????為什么很多都是5V,而且有大量電源芯片支持的也是5V。
????電壓浮動為5%,而電壓標準,在A/D當中使用,標準應該是5.12V。
????因為512 是2的N次方,這樣A/D 的每一個字都是一個整數,當作為無符號計算的時候,更簡單,但是沒見到哪個成品用這個電壓的,大部分都是5V,為什么不用呢?
????因為做5.12的標準電壓成本會成倍增長。5V與5.12V精度差別在百倍,小數點后0.12V,基本很難做到高精度標準電壓,市場通用電壓為5V,上浮一定百分比。
??? 2008年11月發布的STC12系列單片機數據手冊中,STC12C系列的單片機電壓范圍是3.3~5.5V;STC12L系列的單片機電壓范圍是2.2~3.6V。如果選擇STC12C系列的單片機,只要單片機的工作頻率不是太高,使用3.7V供電是沒有任何顧慮的,官方聲稱單片機的抗干擾能力可以達到4000V,但實際應用說法不一。
????大多數單片機都是 TTL 電平,各自的高低電平定義不一樣;
????當電源電壓為5V時:51,AVR單片機是5V;
????當電源電壓為3.3V時:51,AVR單片機高電平是3.3V;
??? ARM如LPC2138,電源電壓只能為3.3V,IO輸出高電平為3.3V;延慶川北小區45孫老師 收賣廢品破爛垃圾炒股 廢品孫 再回收
????但IO口可承受5V電壓現在單片機工作電壓主要有兩種:一種工作在3.3V 一種工作在5V。
三、STM32單片機的知識點2
本文將以STM32F10x為例,對標準庫開發進行概覽。主要分為三塊內容:
-
STM32系統結構
-
寄存器
-
通過點燈案例,詳解如何基于標準庫構建STM32工程
STM32系統結構
?
????上圖,STM32f10xxx系統結構。
內核IP
????從結構框圖上看,Cortex-M3內部有若干個總線接口,以使CM3能同時取址和訪內(訪問內存),它們是:指令存儲區總線(兩條)、系統總線、私有外設總線。有兩條代碼存儲區總線負責對代碼存儲區(即 FLASH 外設)的訪問,分別是?I-Code 總線和?D-Code 總線。
??? I-Code用于取指,D-Code用于查表等操作,它們按最佳執行速度進行優化。
????系統總線(System)用于訪問內存和外設,覆蓋的區域包括SRAM,片上外設,片外RAM,片外擴展設備,以及系統級存儲區的部分空間。
????私有外設總線負責一部分私有外設的訪問,主要就是訪問調試組件。它們也在系統級存儲區。
????還有一個DMA總線,從字面上看,DMA是data memory access的意思,是一種連接內核和外設的橋梁,它可以訪問外設、內存,傳輸不受CPU的控制,并且是雙向通信。簡而言之,這個家伙就是一個速度很快的且不受老大控制的數據搬運工。
處理器外設(內核之外的外設)
????從結構框圖上看,STM32的外設有串口、定時器、IO口、FSMC、SDIO、SPI、I2C等,這些外設按照速度的不同,分別掛載到AHB、APB2、APB1這三條總線上。
寄存器
????什么是寄存器?寄存器是內置于各個IP外設中,是一種用于配置外設功能的存儲器,并且有想對應的地址。一切庫的封裝始于映射。
????是不是看的眼都花了,如果進行寄存器開發,就需要懟地址以及對寄存器進行字節賦值,不僅效率低而且容易出錯。
????庫的存在就是為了解決這類問題,將代碼語義化。語義化思想不僅僅是嵌入式有的,前端代碼也在追求語義特性。
從點燈開始學習STM32
?
內核庫文件分析
cor_cm3.h
????這個頭文件實現了:
-
內核結構體寄存器定義。?
-
內核寄存器內存映射。?
-
內存寄存器位定義。跟處理器相關的頭文件stm32f10x.h實現的功能一樣,一個是針對內核的寄存器,一個是針對內核之外,即處理器的寄存器。
misc.h
????內核應用函數庫頭文件,對應stm32f10x_xxx.h。
misc.c
????內核應用函數庫文件,對應stm32f10x_xxx.c。在CM3這個內核里面還有一些功能組件,如NVIC、SCB、ITM、MPU、CoreDebug,CM3帶有非常豐富的功能組件,但是芯片廠商在設計MCU的時候有一些并不是非要不可的,是可裁剪的,比如MPU、ITM等在STM32里面就沒有。
????其中NVIC在每一個CM3內核的單片機中都會有,但都會被裁剪,只能是CM3 NVIC的一個子集。在NVIC里面還有一個SysTick,是一個系統定時器,可以提供時基,一般為操作系統定時器所用。misc.h和mics.c這兩個文件提供了操作這些組件的函數,并可以在CM3內核單片機直接移植。
處理器外設庫文件分析
startup_stm32f10x_hd.s
????這個是由匯編編寫的啟動文件,是STM32上電啟動的第一個程序,啟動文件主要實現了
-
初始化堆棧指針 SP;
-
設置 PC 指針=Reset_Handler ;
-
設置向量表的地址,并 初始化向量表,向量表里面放的是 STM32 所有中斷函數的入口地址
-
調用庫函數 SystemInit,把系統時鐘配置成 72M,SystemInit 在庫文件 stytem_stm32f10x.c 中定義;
-
跳轉到標號_main,最終去到 C 的世界。
system_stm32f10x.c
????這個文件的作用是里面實現了各種常用的系統時鐘設置函數,有72M,56M,48, 36,24,8M,我們使用的是是把系統時鐘設置成72M。
Stm32f10x.h
????這個頭文件非常重要,這個頭文件實現了:
-
處理器外設寄存器的結構體定義。
-
處理器外設的內存映射。
-
處理器外設寄存器的位定義。
????關于 1 和 2 我們在用寄存器點亮 LED 的時候有講解。
????其中 3:處理器外設寄存器的位定義,這個非常重要,具體是什么意思?
????我們知道一個寄存器有很多個位,每個位寫 1 或者寫 0 的功能都是不一樣的,處理器外設寄存器的位定義就是把外設的每個寄存器的每一個位寫 1 的 16 進制數定義成一個宏,宏名即用該位的名稱表示,如果我們操作寄存器要開啟某一個功能的話,就不用自己親自去算這個值是多少,可以直接到這個頭文件里面找。
????我們以片上外設 ADC 為例,假設我們要啟動 ADC 開始轉換,根據手冊我們知道是要控制 ADC_CR2 寄存器的位 0:ADON,即往位 0 寫 1,即:
????這是一般的操作方法。現在這個頭文件里面有關于 ADON 位的位定義:
有了這個位定義,我們剛剛的代碼就變成了:
stm32f10x_xxx.h
????外設 xxx 應用函數庫頭文件,這里面主要定義了實現外設某一功能的結構體,比如通用定時器有很多功能,有定時功能,有輸出比較功能,有輸入捕捉功能,而通用定時器有非常多的寄存器要實現某一個功能。
????比如定時功能,我們根本不知道具體要操作哪些寄存器,這個頭文件就為我們打包好了要實現某一個功能的寄存器,是以機構體的形式定義的,比如通用定時器要實現一個定時的功能,我們只需要初始化 TIM_TimeBaseInitTypeDef 這個結構體里面的成員即可,里面的成員就是定時所需要操作的寄存器。
????有了這個頭文件,我們就知道要實現某個功能需要操作哪些寄存器,然后再回手冊中精度這些寄存器的說明即可。
stm32f10x_xxx.c
??? stm32f10x_xxx.c:外設 xxx 應用函數庫,這里面寫好了操作 xxx 外設的所有常用的函數,我們使用庫編程的時候,使用的最多的就是這里的函數。
SystemInit
????工程中新建main.c 。
????在此文件中編寫main函數后直接編譯會報錯:
Undefined symbol SystemInit (referred from startup_stm32f10x_hd.o).????錯誤提示說SystemInit沒有定義。從分析啟動文件startup_stm32f10x_hd.s時我們知道。
????第五行第六行代碼Reset_Handler調用了SystemInit該函數用來初始化系統時鐘,而該函數是在庫文件system_stm32f10x.c中實現的。我們重新寫一個這樣的函數也可以,把功能完整實現一遍,但是為了簡單起見,我們在main文件里面定義一個SystemInit空函數,為的是騙過編譯器,把這個錯誤去掉。
????關于配置系統時鐘之后會出文章RCC時鐘樹詳細介紹,主要配置時鐘控制寄存器(RCC_CR)和時鐘配置寄存器(RCC_CFGR)這兩個寄存器,但最好是直接使用CubeMX直接生成,因為它的配置過程有些冗長。
????如果我們用的是庫,那么有個庫函數SystemInit,會幫我們把系統時鐘設置成72M。
????現在我們沒有使用庫,那現在時鐘是多少?答案是8M,當外部HSE沒有開啟或者出現故障的時候,系統時鐘由內部低速時鐘LSI提供,現在我們是沒有開啟HSE,所以系統默認的時鐘是LSI=8M。
庫封裝層級
????如圖,達到第四層級便是我們所熟知的固件庫或HAL庫的效果。當然庫的編寫還需要考慮許多問題,不止于這些內容。我們需要的是了解庫封裝的大概過程。
????將庫封裝等級分為四級來介紹是為了有層次感,就像打怪升級一樣,進行認知理解的升級。
????我們都知道,操作GPIO輸出分三大步:
時鐘控制:
??? STM32 外設很多,為了降低功耗,每個外設都對應著一個時鐘,在系統復位的時候這些時鐘都是被關閉的,如果想要外設工作,必須把相應的時鐘打開。
??? STM32 的所有外設的時鐘由一個專門的外設來管理,叫RCC(reset and clockcontrol),RCC 在STM32 參考手冊的第六章。
??? STM32 的外設因為速率的不同,分別掛載到三條總系上:AHB、APB2、APB1,AHB為高速總線,APB2 次之,APB1 再次之。所以的IO 口都掛載到APB2 總線上,屬于高速外設。
模式配置:
????這個由端口配置寄存器來控制。端口配置寄存器分為高低兩個,每4bit 控制一個IO 口,所以端口配置低寄存器:CRL 控制這IO 口的低8 位,端口配置高寄存器:CRH控制這IO 口的高8bit。
????在4 位一組的控制位中,CNFy[1:0] 用來控制端口的輸入輸出,MODEy[1:0]用來控制輸出模式的速率,又稱驅動電路的響應速度,注意此處速率與程序無關,GPIO引腳速度、翻轉速度、輸出速度區別輸入有4種模式,輸出有4種模式,我們在控制LED 的時候選擇通用推挽輸出。
????輸出速率有三種模式:2M、10M、50M,這里我們選擇2M。
電平控制:
??? STM32的IO口比較復雜,如果要輸出1和0,則要通過控制:端口輸出數據寄存器ODR來實現,ODR 是:Output data register的簡寫,在STM32里面,其寄存器的命名名稱都是英文的簡寫,很容易記住。
????從手冊上我們知道ODR是一個32位的寄存器,低16位有效,高16位保留。低16位對應著IO0~IO16,只要往相應的位置寫入0或者1就可以輸出低或者高電平。
????第一層級:基地址宏定義?
????時鐘控制:
????在STM32中,每個外設都有一個起始地址,叫做外設基地址,外設的寄存器就以這個基地址為標準按照順序排列,且每個寄存器32位,(后面作為結構體里面的成員正好內存對齊)。
查表看到時鐘由APB2外設時鐘使能寄存器(RCC_APB2ENR)來控制,其中PB端口的時鐘由該寄存器的位3寫1使能。我們可以通過基地址+偏移量0x18,算出RCC_APB2ENR的地址為:0x40021018。那么使能PB口的時鐘代碼則如下所示:
????模式配置:
????同RCC_APB2ENR一樣,GPIOB的起始地址是:0X4001 0C00,我們也可以算出GPIO_CRL的地址為:0x40010C00。那么設置PB0為通用推挽輸出,輸出速率為2M的代碼則如下所示:
????同上,從手冊中我們看到ODR寄存器的地址偏移是:0CH,可以算出GPIOB_ODR寄存器的地址是:0X4001 0C00 + 0X0C = 0X4001 0C0C。現在我們就可以定義GPIOB_ODR這個寄存器了,代碼如下:???????
????第一層級:基地址宏定義完成用STM32控制一個LED的完整代碼:
????第二層級:基地址宏定義+結構體封裝
外設寄存器結構體封裝
????上面我們在操作寄存器的時候,操作的是寄存器的絕對地址,如果每個寄存器都這樣操作,那將非常麻煩。我們考慮到外設寄存器的地址都是基于外設基地址的偏移地址,都是在外設基地址上逐個連續遞增的,每個寄存器占32個或者16個字節,這種方式跟結構體里面的成員類似。
????所以我們可以定義一種外設結構體,結構體的地址等于外設的基地址,結構體的成員等于寄存器,成員的排列順序跟寄存器的順序一樣。這樣我們操作寄存器的時候就不用每次都找到絕對地址,只要知道外設的基地址就可以操作外設的全部寄存器,即操作結構體的成員即可。
????下面我們先定義一個GPIO寄存器結構體,結構體里面的成員是GPIO的寄存器,成員的順序按照寄存器的偏移地址從低到高排列,成員類型跟寄存器類型一樣。
????在《STM32 中文參考手冊》8.2 寄存器描述章節,我們可以找到結構體里面的7個寄存器描述。在點亮LED的時候我們只用了CRL和ODR這兩個寄存器,至于其他寄存器的功能大家可以自行看手冊了解。
????在GPIO結構體里面我們用了兩個數據類型,一個是uint32_t,表示無符號的32位整型,因為GPIO的寄存器都是32位的。這個類型聲明在標準頭文件stdint.h 里面使用typedef對unsigned int重命名,我們在程序上只要包含這個頭文件即可。
????另外一個是volatile作用就是告訴編譯器這里的變量會變化不因優化而省略此指令,必須每次都直接讀寫其值,這樣就能確保每次讀或者寫寄存器都真正執行到位。
外設封裝
??? STM32F1系列的GPIO端口分A~G,即GPIOA、GPIOB。。。。。。GPIOG。每個端口都含有GPIO_TypeDef結構體里面的寄存器,我們可以根據手冊各個端口的基地址把GPIO的各個端口定義成一個GPIO_TypeDef類型指針,然后我們就可以根據端口名(實際上現在是結構體指針了)來操作各個端口的寄存器,代碼實現如下:
外設內存映射
????講到基地址的時候我們再引人一個知識點:Cortex-M3存儲器系統,這個知識點在《Cortex-M3權威指南》第5章里面講到。CM3的地址空間是4GB,如下圖所示:
????我們這里要講的是片上外設,就是我們所說的寄存器的根據地,其大小總共有512MB,512MB是其極限空間,并不是每個單片機都用得完,實際上各個MCU廠商都只是用了一部分而已。STM32F1系列用到了:0x4000 0000 ~0x5003 FFFF。現在我們說的STM32的寄存器就是位于這個區域。
APB1、APB2、AHB 總線基地址
????現在我們說的STM32的寄存器就是位于這個區域,這里面ST設計了三條總線:AHB、APB2和APB1,其中AHB和APB2是高速總線,APB1是低速總線。不同的外設根據速度不同分別掛載到這三條總線上。
????從下往上依次是:APB1、APB2、AHB,每個總線對應的地址分別是:APB1:0x40000000,APB2:0x4001 0000,AHB:0x4001 8000。
????這三條總線的基地址我們是從《STM32 中文參考手冊》2.3小節—存儲器映像得到的:APB1的基地址是TIM2定時器的起始地址,APB2的基地址是AFIO的起始地址,AHB的基地址是SDIO的起始地址。其中APB1地址又叫做外設基地址,是所有外設的基地址,叫做PERIPH_BASE。
????現在我們把這三條總線地址用宏定義出來,以后我們在定義其他外設基地址的時候,只需要在這三條總線的基址上加上偏移地址即可,代碼如下:
GPIO 端口基地址
????因為GPIO掛載到APB2總線上,那么現在我們就可以根據APB2的基址算出各個GPIO端口的基地址,用宏定義實現代碼如下:
????第二層級:基地址宏定義+結構體封裝完成用STM32控制一個LED的完整代碼:???????
????第二層級變化:
????①、定義一個外設(GPIO)寄存器結構體,結構體的成員包含該外設的所有寄存器,成員的排列順序跟寄存器偏移地址一樣,成員的數據類型跟寄存器的一樣。
????②外設內存映射,即把地址跟外設建立起一一對應的關系。
????③外設聲明,即把外設的名字定義成一個外設寄存器結構體類型的指針。
????④通過結構體操作寄存器,實現點亮LED。
????第三層級:基地址宏定義+結構體封裝+“位封裝”(每一位的對應字節封裝)
上面我們在控制GPIO輸出內容的時候控制的是ODR(Output data register)寄存器,ODR是一個16位的寄存器,必須以字的形式控制其實我們還可以控制BSRR和BRR這兩個寄存器來控制IO的電平,下面我們簡單介紹下BRR寄存器的功能,BSRR自行看手冊研究。
????位清除寄存器BRR只能實現位清0操作,是一個32位寄存器,低16位有效,寫0沒影響,寫1清0。現在我們要使PB0輸出低電平,點亮LED,則只要往BRR的BR0位寫1即可,其他位為0,代碼如下:
????這時PB0就輸出了低電平,LED就被點亮了。
????如果要PB2輸出低電平,則是:
????如果要PB3/4/5/6。。。。。。這些IO輸出低電平呢?
????道理是一樣的,只要往BRR的相應位置賦不同的值即可。因為BRR是一個16位的寄存器,位數比較多,賦值的時候容易出錯,而且從賦值的16進制數字我們很難清楚的知道控制的是哪個IO。
????這時,我們是否可以把BRR的每個位置1都用宏定義來實現,如GPIO_Pin_0就表示0X0001,GPIO_Pin_2就表示0X0004。只要我們定義一次,以后都可以使用,而且還見名知意。“位封裝”(每一位的對應字節封裝) 代碼如下:???????
????這時PB0就輸出了低電平的代碼就變成了:
????如果同時讓PB0/PB15輸出低電平,用或運算,代碼:
????為了不使main函數看起來冗余,上述庫封裝 的代碼不應該放在main里面,因為其是跟GPIO相關的,我們可以把這些宏放在一個單獨的頭文件里面。
????在工程目錄下新建stm32f10x_gpio.h,把封裝代碼放里面,然后把這個文件添加到工程里面。這時我們只需要在main.c里面包含這個頭文件即可。
????第四層級:基地址宏定義+結構體封裝+“位封裝”+函數封裝
????我們點亮LED的時候,控制的是PB0這個IO,如果LED接到的是其他IO,我們就需要把GPIOB修改成其他的端口,其實這樣修改起來也很快很方便。
????但是為了提高程序的可讀性和可移植性,我們是否可以編寫一個專門的函數用來復位GPIO的某個位,這個函數有兩個形參,一個是GPIOX(X=A...G),另外一個是GPIO_Pin(0...15),函數的主體則是根據形參GPIOX 和GPIO_Pin來控制BRR寄存器,代碼如下:
????這時,PB0輸出低電平,點亮LED的代碼就變成了:
????同理, 我們可以控制BSRR這個寄存器來實現關閉LED,代碼如下:
????這時,PB0輸出高電平,關閉LED的代碼就變成了:
????同樣,因為這個函數是控制GPIO的函數,我們可以新建一個專門的文件來放跟gpio有關的函數。相關文章:STM32中GPIO工作原理詳解。
????在工程目錄下新建stm32f10x_gpio.c,把GPIO相關的函數放里面。這時我們是否發現剛剛新建了一個頭文件stm32f10x_gpio.h,這兩個文件存放的都是跟外設GPIO相關的。
??? C文件里面的函數會用到h頭文件里面的定義,這兩個文件是相輔相成的,故我們在stm32f10x_gpio.c 文件中也包含stm32f10x_gpio.h這個頭文件。別忘了把stm32f10x.h這個頭文件也包含進去,因為有關寄存器的所有定義都在這個頭文件里面。
????如果我們寫其他外設的函數,我們也應該跟GPIO一樣,新建兩個文件專門來存函數,比如RCC這個外設我們可以新建stm32f10x_rcc.c和stm32f10x_rcc.h。其他外依葫蘆畫瓢即可。
實例編寫
????以上,是對庫封住過程的概述,下面我們正在地使用庫函數編寫LED程序。
①管理庫的頭文件
????當我們開始調用庫函數寫代碼的時候,有些庫我們不需要,在編譯的時候可以不編譯,可以通過一個總的頭文件stm32f10x_conf.h來控制,該頭文件主要代碼如下:
?
????這里面包含了全部外設的頭文件,點亮一個LED我們只需要RCC和GPIO 這兩個外設的庫函數即可,其中RCC控制的是時鐘,GPIO控制的具體的IO口。所以其他外設庫函數的頭文件我們注釋掉,當我們需要的時候就把相應頭文件的注釋去掉即可。
??? stm32f10x_conf.h這個頭文件在stm32f10x.h這個頭文件的最后面被包含,在第8296行:
????代碼的意思是,如果定義了USE_STDPERIPH_DRIVER這個宏的話,就包含stm32f10x_conf.h這個頭文件。
????我們在新建工程的時候,在魔術棒選項卡C/C++中,我們定義了USE_STDPERIPH_DRIVER 這個宏,所以stm32f10x_conf.h 這個頭文件就被stm32f10x.h包含了,我們在寫程序的時候只需要調用一個頭文件:stm32f10x.h即可。
②編寫LED初始化函數
????經過寄存器點亮LED的操作,我們知道操作一個GPIO輸出的編程要點大概如下:
1、開啟GPIO的端口時鐘
2、選擇要具體控制的IO口,即pin
3、選擇IO口輸出的速率,即speed
4、選擇IO口輸出的模式,即mode
5、輸出高/低電平
??? STM32的時鐘功能非常豐富,配置靈活,為了降低功耗,每個外設的時鐘都可以獨自的關閉和開啟。STM32中跟時鐘有關的功能都由RCC這個外設控制,RCC中有三個寄存器控制著所以外設時鐘的開啟和關閉:RCC_APHENR、RCC_APB2ENR和RCC_APB1ENR,AHB、APB2和APB1代表著三條總線,所有的外設都是掛載到這三條總線上,GPIO屬于高速的外設,掛載到APB2總線上,所以其時鐘有RCC_APB2ENR控制。
GPIO 時鐘控制
????固件庫函數:RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE)函數的原型為:
????當程序編譯一次之后,把光標定位到函數/變量/宏定義處,按鍵盤的F12或鼠標右鍵的Go to definition of,就可以找到原型。固件庫的底層操作的就是RCC外設的APB2ENR這個寄存器,宏RCC_APB2Periph_GPIOB的原型是:0x00000008,即(1<<3),還原成存器操作就是:RCC->APB2ENR |= 1<<<3。相比固件庫操作,寄存器操作的代碼可讀性就很差,只有才查閱寄存器配置才知道具體代碼的功能,而固件庫操作恰好相反,見名知意。
GPIO 端口配置
??? GPIO的pin,速度,模式,都由GPIO的端口配置寄存器來控制,其中IO0~IO7由端口配置低寄存器CRL控制,IO8~IO15由端口配置高寄存器CRH配置。固件庫把端口配置的pin,速度和模式封裝成一個結構體:
??? pin可以是GPIO_Pin_0~GPIO_Pin_15或者是GPIO_Pin_All,這些都是庫預先定義好的宏。speed也被封裝成一個結構體:
????速度可以是10M,2M或者50M,這個由端口配置寄存器的MODE位控制,速度是針對IO口輸出的時候而言,在輸入的時候可以不用設置。mode也被封裝成一個結構體:???????
??? IO口的模式有8種,輸入輸出各4種,由端口配置寄存器的CNF配置。平時用的最多的就是通用推挽輸出,可以輸出高低電平,驅動能力大,一般用于接數字器件。
????最終用固件庫實現就變成這樣:
// 定義一個GPIO_InitTypeDef 類型的結構體GPIO_InitTypeDef GPIO_InitStructure; // 選擇要控制的IO 口GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // 設置引腳為推挽輸出GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 設置引腳速率為50MHzGPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; /*調用庫函數,初始化GPIOB0*/GPIO_Init(GPIOB, &GPIO_InitStructure);????倘若同一端口下不同引腳有不同的模式配置,每次對每個引腳配置完成后都要調用GPIO初始化函數,代碼如下:
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15 ; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉輸入GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 ; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽輸出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO 輸出控制
??? GPIO輸出控制,可以通過端口數據輸出寄存器ODR、端口位設置/清除寄存器BSRR和端口位清除寄存器BRR這三個來控制。端口輸出寄存器ODR是一個32位的寄存器,低16位有效,對應著IO0~IO15,只能以字的形式操作,
????端口位清除寄存器BRR是一個32位的寄存器,低十六位有效,對應著IO0~IO15,只能以字的形式操作,可以單獨對某一個位操作,寫1清0。
??? BSRR是一個32位的寄存器,低16位用于置位,寫1有效,高16位用于復位,寫1有效,相當于BRR寄存器。高16位我們一般不用,而是操作BRR這個寄存器,所以BSRR這個寄存器一般用來置位操作。
????綜上:固件庫LED GPIO初始化函數。
主函數
????注意void Time_Delay(volatile uint32_t Count)只是一個簡陋的軟件延時函數,如果小伙伴們有興趣可以看一看MultiTimer,它是一個軟件定時器擴展模塊,可無限擴展所需的定時器任務,取代傳統的標志位判斷方式, 更優雅更便捷地管理程序的時間觸發時序。
總結
- 上一篇: 阿里销售铁军:阿里巴巴客户跟进流程
- 下一篇: 12行代码获取1000万行手机号码归属地