簡介
本應(yīng)用筆記介紹ADSP-CM408F模數(shù)轉(zhuǎn)換器控制器(ADCC)模塊的主要特性,重點討論該產(chǎn)品在高性能電機(jī)控制應(yīng)用的電流反饋系統(tǒng)中的相關(guān)性與可用性。
本應(yīng)用筆記的目的是為了強(qiáng)調(diào)模數(shù)轉(zhuǎn)換器(DAC)模塊的關(guān)鍵功能,并提供針對電機(jī)控制應(yīng)用的配置指南。本文提供演示ADI ADCC驅(qū)動器的代碼示例。
有關(guān)此ADCC的所有功能、配置寄存器和應(yīng)用程序接口(API)的更多詳細(xì)信息,請參閱ADSP-CM402F/ADSP-CM403F/ADSP-CM407F/ADSP-CM408F產(chǎn)品頁面和采用ARM Cortex-M4和16位ADC開發(fā)產(chǎn)品的ADSP-CM40x混合信號控制處理器的產(chǎn)品頁面上提供的《采用ARM Cortex-M4的ADSP-CM40x混合信號控制處理器硬件參考指南》。
雖然本應(yīng)用筆記重點討論電流反饋,類似的配置和應(yīng)用原理同樣適用于其他信號的反饋與測量。
同樣,雖然本應(yīng)用筆記重點討論ADSP-CM408F,但原理在本質(zhì)上同樣適用于ADSP-CM402F/ ADSP-CM403F/ADSP-CM407F/ADSP-CM408F系列的其他產(chǎn)品。
電流反饋系統(tǒng)概述
電機(jī)控制應(yīng)用中的電流反饋示例如圖1所示。該配置常用于高性能電機(jī)驅(qū)動,并針對電機(jī)相位繞組電流采樣,而非對逆變器低端相位引腳采樣。中高電平時,電流傳感器或變壓器(CT0和CT1)必須用于電流測量路徑,因為阻性分流器尺寸過大而低效。
在圖1的配置中,處理器位于安全的隔離柵低壓側(cè),而信號隔離通常為CT0和CT1所固有,且微處理器的脈沖寬度調(diào)制PWM輸出和柵極驅(qū)動器之間還存在數(shù)字隔離。
通常需要在電流傳感器輸出和ADC輸入之間進(jìn)行一些信號調(diào)理,以便實現(xiàn)范圍匹配和高頻噪聲濾波。隨后將調(diào)理的電流測量信號施加于ADC輸入,用來采樣和轉(zhuǎn)換。對每個ADC輸入進(jìn)行一次繞組電流測量將使能電流測量的同步采樣以獲得更高的控制環(huán)路精度,從而增強(qiáng)性能。另外,還可在硬件內(nèi)直接配置采樣時間與PWM sync脈沖的同步。
圖1. 電機(jī)控制中ADSP-CM408F ADC的電流反饋
這些特性可使能PWM周期中相位電流測量點的精密時序。將這些測量時刻與零矢量的中間點或PWM周期的中間點對齊,確保電流采樣電平等效于忽略開關(guān)紋波的瞬時平均電流。
圖2中顯示了零矢量中點和PWM周期中點處的同步U相位和V相位采樣。
圖2. 平均電流采樣圖解
完成數(shù)據(jù)轉(zhuǎn)換后,便可將其通過直接存儲器訪問(DMA)傳輸至控制器靜態(tài)隨機(jī)存取存儲器(SRAM),完成傳輸后會生成一個中斷。在內(nèi)核模式下,通過存儲器映射寄存器,還可實現(xiàn)直接ADC狀態(tài)和數(shù)據(jù)讀取,但這種方法需消耗更多的處理器開銷。
通常還會采樣其他模擬信號,例如直流總線電壓、隔離式柵極雙極性晶體管(IGBT)溫度和電機(jī)位置正弦與余弦輸出。雖然本應(yīng)用筆記重點討論電流反饋,但很多信息也與系統(tǒng)中的其他測量參數(shù)有關(guān)。
ADC模塊概述
該ADC采用雙通道、16位、高速、低功耗、逐次逼近型寄存器(SAR)設(shè)計,精度高達(dá)14位。
輸入多路復(fù)用器最多支持連接兩個獨立受控ADC的26個模擬輸入源組合(每個ADC的12路模擬輸入加上1路DAC回送輸入),任意時刻都對兩個通道同步采樣。 ADC轉(zhuǎn)換時間快達(dá)380 ns。單端模擬輸入所需的電壓輸入范圍為0 V至2.5 V。
多路復(fù)用器和ADC之間提供片內(nèi)緩沖器,無需使用額外的外部信號調(diào)理ADSP-CM408F。此外,每個ADC都有一個片內(nèi)2.5 V基準(zhǔn)電壓源,當(dāng)優(yōu)先選擇外部基準(zhǔn)電壓源時可將其過驅(qū)(通過ADCC_CFG寄存器選擇該選項)。
ADSP-CM408F中的總模擬子系統(tǒng)的圖形概述如圖3所示。ADSP-CM408F采用多芯片系統(tǒng)級封裝(SiP),而ADC硅片制造工藝與處理器硅片工藝有所不同,如圖3所示。
ADCC負(fù)責(zé)ADC中與處理器的時序同步,并管理DMA,將采樣數(shù)據(jù)傳輸?shù)絊RAM。
圖3. ADSP-CM408F模擬子系統(tǒng)
電流反饋調(diào)整
若要最大限度地正確利用ADC的能力,正確調(diào)整反饋信號非常重要。信號通過反饋路徑處理,如圖5所示。雙極性相位繞組電流IW通過電流傳感器(或變壓器)和信號調(diào)理電路的組合功能轉(zhuǎn)換為ADC輸入端的單極性電壓。
電流傳感器的傳遞函數(shù)由下式表示:
其中:
為輸出電壓;
是傳感器的線性增益系數(shù);
是傳感器的零電流失調(diào)電壓。
? KCT在不同傳感器類型的某些電流水平下表現(xiàn)出非線性,且為了獲得更佳的精度,應(yīng)當(dāng)與IW成函數(shù)關(guān)系,即KCT (IW)。之后,ADC輸入電壓可表示為:
? 其中,KSIG是信號調(diào)理電路的低頻增益。
? 該單極性電壓轉(zhuǎn)換為16位無符號整數(shù),并由DMA傳輸至處理器存儲器,然后發(fā)出中斷,提醒控制程序新數(shù)據(jù)樣本可用。ADC理想化的傳遞函數(shù)如下所示:
?
? 其中:
? NIW是ADC數(shù)字輸出字。
? KADC表示ADC的線性增益,等于
? 根據(jù)輸入電壓范圍劃分的ADC分辨率,如上所示。
? ADC輸出會產(chǎn)生一些失調(diào);而在軟件內(nèi)進(jìn)行一些失調(diào)補償(NADC_OFFSET)通常是一個好辦法,可將ADC自身的所有失調(diào)以及傳感器和信號調(diào)理電路產(chǎn)生的所有殘余失調(diào)從ADC輸出中去除。該值可在零電流周期(如系統(tǒng)啟動或禁用驅(qū)動輸出)中動態(tài)更新。
? 最后,電流傳感器零電流失調(diào)電壓NCT_OFFSET的數(shù)字表示從ADC輸出信號中去除,使帶符號值IW(與實際相位繞組電流有關(guān))的表達(dá)式為:
? 其中:
?
? 這個帶符號的16位值可轉(zhuǎn)換為浮點值,或直接使用,具體取決于控制器實現(xiàn)方案。若要最大限度地利用ADC的全范圍,則系統(tǒng)中的正峰值受控電流必須與ADC輸入電壓2.5 V相對應(yīng),而負(fù)峰值受控電流與ADC輸入0 V相對應(yīng)。
? 該情況的一個示例如圖4所示。該圖顯示了典型電流波形和相關(guān)的各種零電平、峰值電平以及標(biāo)稱電平,圖4顯示的電流電平將轉(zhuǎn)換為通過信號測量系統(tǒng)傳播(如圖5所示)的比例量(參見表1)。
圖4. 電流反饋信號幅度
表1. 電流反饋信號幅度
本示例采用連接LEM?,的CAS 6-NP霍爾效應(yīng)傳感器,其初級匝數(shù)為3,具有0 V至5 V輸出,后接增益為0.5的信號調(diào)理電路。
圖5. 電流反饋路徑的調(diào)整關(guān)系
?
ADC時序考慮因素
以PWM周期同步采樣事件對于精確電流反饋而言非常重要。ADCC采用PWM周期工作的概念時序如圖6所示。下列事件序列由PWM SYNC脈沖觸發(fā)。
1. PWM sync脈沖觸發(fā)定時器,以便啟動。
2. ADCC不斷將事件信息中的采樣時間與定時器時間比較。
3. 完成定時器匹配,ADCC計劃ADC操作。
4. ADC變?yōu)榭捎煤螅珹DCC便使用事件信息選擇適當(dāng)?shù)耐ǖ馈?/p>
5. ADCC觸發(fā)ADC轉(zhuǎn)換序列,ADC采樣并轉(zhuǎn)換數(shù)據(jù)。
6. 數(shù)據(jù)回流至ADCC。
7. ADCC將數(shù)據(jù)通過DMA傳輸至存儲器位置(LSB優(yōu)先)。
8. 產(chǎn)生中斷(IRQ),提醒CPU數(shù)據(jù)樣本可用。
圖6. ADCC操作序列
ADCC事件時序
控制器管理最多24個采樣事件的配置和時序。這些事件的時序受觸發(fā)限制,該觸發(fā)會啟動兩個定時器(TMR0或TMR1)中的其中一個,并在定時器啟動后啟動一個事件時間。
如圖7所示,觸發(fā)源可從一系列外設(shè)或處理器事件中選取,如PWM SYNC脈沖、定時器或I/O引腳中斷。每次事件都與一個事件號碼(以Event x表示)、一個事件時間(以TIMEx表示)、控制信息(以CTLx表示)及其結(jié)果數(shù)據(jù)相關(guān)聯(lián)。事件控制信息(圖7中以CTLx表示)包含每個采樣事件的信息,如ADC接口和通道號、所用的ADC定時器、同步采樣選擇,以及相關(guān)事件ADC數(shù)據(jù)的存儲器失調(diào)。ADCC使用該信息對正確的ADC通道(CHx)進(jìn)行多路復(fù)用處理、初始化ADC轉(zhuǎn)換(CVST0/CVST1信號)并將正確的數(shù)據(jù)傳輸至適當(dāng)?shù)氖录?shù)據(jù)寄存器中。
然后,可設(shè)置DMA傳輸,將每次事件的ADC數(shù)據(jù)移入SRAM中。完成所有事件和后續(xù)DMA傳輸之后,便產(chǎn)生一個中斷,通知主應(yīng)用代碼新ADC數(shù)據(jù)可用。
圖7. ADCC模塊功能框圖
例如,圖8顯示與ADC定時器0有關(guān)的3個采樣事件。PWM sync脈沖觸發(fā)定時器,事件時間與每一次事件相關(guān)聯(lián)。
事件0和事件1是同步采樣事件,事件時間寄存器中的事件時間置零。事件2稍后發(fā)生,并同樣由事件2時間寄存器確定,表示為ADC時鐘周期(tACLK)的倍數(shù)。若事件2是與定時器0關(guān)聯(lián)的最終事件,則定時器將在事件處理完成后停止運行,以降低功耗。
圖8. 事件時序
ADC操作時序
ADCC控制器觸發(fā)采樣事件后,ADC操作本身具有一個轉(zhuǎn)換時間延遲。圖9顯示單次ADC事件與每個ADC接口相關(guān)聯(lián),且使能兩次事件同步采樣的情況。
有三個獨立的轉(zhuǎn)換周期與ADC操作有關(guān)。
1. 寫入8位控制字,選擇ADC讀取通道(ADCC_EVTCTL.CTLWD)。
2. 置位轉(zhuǎn)換脈沖,使能ADC采樣和轉(zhuǎn)換。
3. 讓16位ADC數(shù)據(jù)回流至ADCC。
ADCC提供這3個事件相位的片選和選通時鐘信號。ADCC與ADC的接口為串行接口,采用雙通道位操作。因此,每個CS脈沖期間提供的最小時鐘周期數(shù)(ADCC時序控制寄存器的NCK段)為8。其他重要的設(shè)置有:ADC時鐘頻率、轉(zhuǎn)換周期片選信號之間的最小延遲(tCSCS)(ACLK周期內(nèi)),以及CS邊沿和ACLK邊沿之間的最小延遲(tCSCK和tCKCS)。因此,單個同步采樣信號對的ADC轉(zhuǎn)換周期時間tCONV_ADC可表示為:
其中,fACLK表示ADCC時鐘頻率。
ADCC時鐘由處理器系統(tǒng)時鐘(fSYSCLK)通過ACKDIV分頻(在時序控制寄存器ADCC_TCA中)在內(nèi)部產(chǎn)生,計算如下:
其結(jié)果是系統(tǒng)時鐘來源于處理器內(nèi)核時鐘(fCORECLK)。當(dāng)fCORECLK為fSYSCLK的整數(shù)倍時,獲得最佳系統(tǒng)性能。完成ADC轉(zhuǎn)換后,額外延遲是因為ADC數(shù)據(jù)通過DMA傳輸至數(shù)據(jù)存儲器,并最終由中斷請求服務(wù)將數(shù)據(jù)幀準(zhǔn)備就緒,供主應(yīng)用程序使用。因此,在應(yīng)用中,從觸發(fā)(例如,PWM SYNC脈沖)到數(shù)據(jù)可用的總時間為:
tCONV_TOTAL = tCONV_ADC + tDMA + tIRQ
其中:
tDMA是DMA傳輸?shù)钠骄鶗r間。
tIRQ是中斷請求服務(wù)的平均時間。
圖9. 單次事件同步采樣的轉(zhuǎn)換時間
典型時序設(shè)置見表2。表中還列出了對時序的一些約束條件。獲得正確ADC性能的絕對約束條件是,允許的ADC采樣和轉(zhuǎn)換周期(tCONV_ADC/3)必須至少為380 ns。單個同步采樣事件的時序結(jié)果如圖10所示,該結(jié)果與電機(jī)繞組電流的采樣有關(guān)(注意,該圖為了突出示例而略為夸大)。
圖10. 采樣延遲時間
采用這些設(shè)置時,在所需的電流波形采樣點與實際采樣點之間存在450 ns失調(diào)。該值等于一個片選脈寬(200 ns + 25 ns + 0 ns)加兩次片選之間的脈寬(225 ns)。 該結(jié)果造成平均電機(jī)繞組電流和實際采樣電流之間的ΔiSAMP產(chǎn)生差異,在時序調(diào)度中需加以考慮,雖然在1 kHz的典型電流控制環(huán)路帶寬環(huán)境中,這表示不超過0.2°的相移。此外,對于10 kHz的典型PWM頻率,ADC數(shù)據(jù)從產(chǎn)生PWM SYNC脈沖(表2中的設(shè)置)起,在不足2%的可用PWM周期時間內(nèi)可供應(yīng)用程序使用。如果在事件發(fā)生時ADC處于空閑狀態(tài),則4至5個SYSCLK周期的額外延遲將存在于事件激活的時刻與ADC開始工作的時刻之間。
圖11. 采樣時刻調(diào)整的實現(xiàn)
表2. 典型ADC設(shè)置的時序設(shè)定
??????
采樣時刻調(diào)整
可能需要進(jìn)一步提高電機(jī)電流采樣時刻的精度并消除所需采樣時刻和實際采樣時刻之間的450 ns失調(diào)。精度提高后對低電感伺服電機(jī)等應(yīng)用案例或者采用較高開關(guān)頻率的情況特別有益。要消除這一較小的時間偏移量,一種方法是使用通用(GP)定時器在PWM sync脈沖前一個ADCC片選脈寬處創(chuàng)建觸發(fā)。這可以通過從前一PWM sync脈沖觸發(fā)GP定時器來實現(xiàn),如圖11所示。使用此方法時,在PWM周期結(jié)束前安排任何采樣事件時必須謹(jǐn)慎。所有采樣事件必須在下一周期開始前一個片選脈寬處完成(圖11中的EVT0標(biāo)記)。
ADC流水線
當(dāng)新事件開始與ADC正在處理的現(xiàn)有事件重疊時,ADCC將新事件作為待處理事件存儲在8深先進(jìn)先出(FIFO)緩沖器中,該緩沖器可用于所有ADC接口。寫入激活事件的控制字后,ADCC立即開始寫入首個待處理事件的控制字,同時進(jìn)入激活事件的采樣階段。同樣,第一個待處理事件的控制字階段執(zhí)行完成后,便進(jìn)入第二個待處理事件的控制字階段。以這種方式,ADCC可在每個ADC接口上通過流水線方式交錯處理三個并行事件。因此,事件能以緊湊高效的方式排列。
配置事件時序使事件以上述流水線方式處理,可獲得最高的ADC吞吐速率。該流水線如圖13所示。圖中,三對同步采樣事件的觸發(fā)時間間隔很短。
圖中,三對同步采樣事件的觸發(fā)時間間隔很短。ADCC開始處理事件0和事件1,同時將事件2至事件5存儲在FIFO中。然后,ADC資源變得可用時,便會對這些事件進(jìn)行處理。
從圖7可知,在CS某次置位期間,ADCC會處理全部6個事件以及每個事件的多個階段,并且兩次連續(xù)采樣之間的時間間隔僅為18個ACLK周期。該時間間隔相當(dāng)于表2設(shè)置中的450 ns,且可通過提高ACLK頻率進(jìn)一步降低。若要在電機(jī)控制應(yīng)用內(nèi)最大化ADC帶寬,最好的方法是有意識地將所有與PWM周期相關(guān)的采樣事件以流水線方式處理。該方法可以確保新的ADC樣本能在PWM周期中可能的最早時刻準(zhǔn)備就緒。要實施圖13中顯示的流水線,則需要所有事件時間均接近零,即緊跟在PWM SYNC脈沖后。
建議在兩個事件時間寄存器ADCC_EVTnn(nn表示0到24的寄存器編號)中存儲的事件時間之間允許一個最小1 ACLK周期,實現(xiàn)正確調(diào)度。
圖12中顯示使用流水線操作時的總轉(zhuǎn)換時間,包括起始延遲、DMA傳輸和中斷服務(wù),可用于采用表2中所示時序設(shè)置的各種同步采樣對數(shù)目。
圖12. 不同采樣對數(shù)目的總轉(zhuǎn)換時間
圖13. ADC中的流水線事件
ADC數(shù)據(jù)訪問
目前為止,本文中的示例都假定ADC數(shù)據(jù)采用自動DMA傳輸從存儲器中訪問。從ADCC存儲器映射寄存器(MMR)的內(nèi)核讀數(shù)中直接訪問數(shù)據(jù)是可行的,如圖14所示。注意,圖14中的ACK表示確認(rèn)信號,而非模擬時鐘。
圖14 內(nèi)核模式的ADC數(shù)據(jù)訪問
在內(nèi)核模式下,CPU通過事件或幀中斷獲取有關(guān)新數(shù)據(jù)就緒的信號,這些中斷可按需獨立屏蔽或解除屏蔽。該模式下還具有額外的靈活性:在整個事件幀結(jié)束前,一旦完成獨立事件,即可對其進(jìn)行讀取。內(nèi)核模式的缺點是中斷服務(wù)以及MMR讀訪問所需的總延遲比DMA模式下要高。采用優(yōu)化的內(nèi)核和時鐘分頻比設(shè)定,則在每個中斷服務(wù)的最高延遲情況下,每次MMR讀操作將花費10至12個SYSCLK周期。
圖15顯示了DMA模式下的數(shù)據(jù)訪問。
在這種情況下,DMA傳輸僅在完成一個定時器幀后才會發(fā)生,且?guī)袛嘈盘杻H在完成DMA傳輸后才發(fā)給CPU。
圖15. DMA模式下的ADC數(shù)據(jù)訪問
兩種情況下,EISTAT和FISTAT寄存器都在激活后提供事件和幀中斷的狀態(tài)指示,且必須在下一次觸發(fā)前經(jīng)由CPU清零相關(guān)位確認(rèn),否則將標(biāo)記一次觸發(fā)溢出條件。
ADCC數(shù)據(jù)故障檢測
ADCC提供多個故障狀態(tài)寄存器位,發(fā)生數(shù)據(jù)故障時可置位;ADCC事件時序和/或不確定事件序列設(shè)置不當(dāng)時,就有可能發(fā)生數(shù)據(jù)故障。這些故障可能使ADCC過載,或造成無效的ADC數(shù)據(jù)。它們包括:
· 觸發(fā)溢出。當(dāng)前幀結(jié)束前便觸發(fā)下一次事件。
· DMA帶寬。幀結(jié)束所需的時間長于用戶定義時間。
· 存儲器錯誤。ADC數(shù)據(jù)寫操作失敗。
· 事件沖突。處理現(xiàn)有事件時發(fā)生新事件。
· 事件錯失。事件未處理。
這些錯誤均可按需配置為內(nèi)核的中斷源,并且它們都會置位ADCC_ERRSTAT寄存器。在電機(jī)控制應(yīng)用中,尤其在電流反饋測量中,與事件錯失、存儲器和觸發(fā)溢出有關(guān)的錯誤對于監(jiān)控核心應(yīng)用非常重要,因為錯誤或錯失的電流環(huán)路數(shù)據(jù)可能會導(dǎo)致控制環(huán)路的不穩(wěn)定。事件沖突在流水線操作中非常普遍,通常影響不大,除非FIFO已滿。
ADCC模塊、觸發(fā)路由和存儲器設(shè)置
使用ADC之前,需執(zhí)行一系列步驟來設(shè)置ADCC模塊以及觸發(fā)路由單元和數(shù)據(jù)緩沖器。完成配置后,假定采用DMA數(shù)據(jù)訪問模式,則DMA引擎會自動將主ADC數(shù)據(jù)傳輸至存儲器,供主應(yīng)用程序進(jìn)行內(nèi)部訪問。當(dāng)數(shù)據(jù)就緒時,ADCC產(chǎn)生中斷,以便處理器執(zhí)行控制算法并更新PWM調(diào)制器寄存器。
圖17顯示ADCC、CPU、SRAM、PWM和外部信號之間所需的互連,可用于在典型電機(jī)控制應(yīng)用中捕捉電機(jī)電流反饋以及其他模擬監(jiān)控信號。在本例中,編碼器正弦和余弦信號、散熱片溫度和直流總線電壓作為額外監(jiān)控輸入示例提供。
設(shè)置ADCC以便正確處理信號反饋的三個步驟如下所示:
1. ADCC事件配置。
2. 中斷和觸發(fā)路由。
3. 數(shù)據(jù)訪問和存儲器分配。
下列子段落描述正確設(shè)置系統(tǒng)所需的步驟與相應(yīng)的寄存器配置。
圖17. 典型電機(jī)控制應(yīng)用中的系統(tǒng)互連
ADCC事件配置
ADCC事件的配置示例如圖17所示,該示例包括為每個事件分配定時器、ADC接口和通道、時間偏移以及同步采樣開關(guān)。這可以通過多種方法實現(xiàn);圖16以及表3所示為其中的一種可能情況。該示例采用全部兩個定時器,僅供參考。
對于此示例,事件可連接至一個定時器,因為所有事件的定時都與PWM SYNC脈沖有關(guān)。
在諸如雙軸電機(jī)控制算法這類用例中,可能必須同時使用兩個定時器,因為該用例采用兩組PWM輸出以及相應(yīng)的PWM sync脈沖。
圖16. 電機(jī)控制應(yīng)用中的典型ADCC
表3. 示例應(yīng)用的事件配置
?
相位電流iV和iW在發(fā)生PWM sync脈沖觸發(fā)后立即同步采樣,它們關(guān)聯(lián)至TMR1。定時器1幀立即通過DMA傳輸至存儲器,且新的電流樣本可供主應(yīng)用程序使用。在PWM周期中的較晚時刻,新的事件幀采樣并關(guān)聯(lián)至TMR0。
編碼器正弦和余弦信號同步采樣,緊隨其后的是直流總線電壓和散熱片溫度信號。
對三個ADC0信號進(jìn)行流水線處理,以最大化吞吐速率。然后,將TMR0幀通過DMA傳輸至存儲器。
這些參數(shù)的配置需設(shè)置ADCC_EVCTLnn事件控制寄存器和ADCC_EVTnn事件時間寄存器,nn表示每個事件的編號。提供本節(jié)內(nèi)容涉及的驅(qū)動程序API,簡化該過程。
中斷和觸發(fā)路由
在圖17中的示例中,所有事件時間均參考PWM周期;因此,兩個定時器都由PWM SYNC脈沖觸發(fā)。PWM sync脈沖作為硬件觸發(fā)與ADCC定時器相關(guān)聯(lián)的前提是配置TRU,使PWM sync脈沖作為主觸發(fā)信號與ADCC觸發(fā)從機(jī)相關(guān)聯(lián)。隨后,ADCC定時器必須與ADCC觸發(fā)相關(guān)聯(lián)。
圖18顯示相應(yīng)觸發(fā)路由的概念圖;該路由涉及觸發(fā)主機(jī)19 (PWM0 SYNC)與觸發(fā)從機(jī)24 (ADCC_TRIG0)之間的連接,本例中該連接可通過將主機(jī)編號寫入適當(dāng)?shù)膹臋C(jī)選擇寄存器TRU_SSR24來實現(xiàn)。之后,通過在ADC_CTL寄存器中為TRIGSEL位設(shè)置相應(yīng)的值,將ADCC_TRIG0觸發(fā)路由至兩個定時器。
圖18. 從PWM SYNC至ADCC定時器的觸發(fā)路由
此觸發(fā)路由配置可以提供硬件的直連鏈路,將PWM時序與ADC采樣相關(guān)聯(lián),而不會在路徑上產(chǎn)生軟件延遲。觸發(fā)主機(jī)也可從其他源路由,如GPIO引腳中斷、定時器和計數(shù)器事件。如此配置便可提供精確同步,比如與ADSP-CM408F控制的其他轉(zhuǎn)換器進(jìn)行采樣同步。
此外,完整的ADCC定時器幀能作為觸發(fā)主機(jī)與其他外設(shè)或核心從機(jī)相關(guān)聯(lián)。
由于本例中采用了DMA傳輸模式,因此所有事件中斷都應(yīng)當(dāng)在ADCC_EIMSK寄存器中屏蔽。同樣,提供驅(qū)動程序API,用來在寄存器中設(shè)置適當(dāng)?shù)闹袛喾?wù)例程,實現(xiàn)DMA模式下的幀中斷。
利用觸發(fā)路由提供增強(qiáng)型精確采樣時序
像上文所述那樣,要從當(dāng)前采樣時序中移除片選脈寬滯后,需要稍微不同的觸發(fā)路由配置。在此情況中,ADCC定時器是通過GP定時器觸發(fā)器觸發(fā)的,而該觸發(fā)器本身是通過PWM sync觸發(fā)的。此序列可參見圖11。
數(shù)據(jù)訪問和存儲器分配
如圖14和圖15所示,可通過讀取內(nèi)核MMR訪問ADC數(shù)據(jù),或通過DMA傳輸使其能在SRAM中訪問。在內(nèi)核模式下,無需配置特定存儲器分配,即可實現(xiàn)除變量外的內(nèi)核MMR讀取數(shù)據(jù)的寫操作。然而在DMA模式下,必須分配特定的存儲器區(qū)域,然后進(jìn)行配置,才能實現(xiàn)DMA訪問,并且每個定時器都必須配置。所需的存儲器大小取決于每個定時器相關(guān)的幀尺寸,以及新的幀覆蓋之前需要在存儲器中存儲多少幀。
表19顯示SRAM映射概念,以及控制SRAM配置的相關(guān)ADCC寄存器。ADCC_BPTR寄存器必須存儲指向存儲器基址的指針,才能存儲ADC樣本。若存儲器緩沖器中需要存儲多個幀,則ADCC_FRINC寄存器中應(yīng)包含指針的偏移值,使其指向下一幀的基址。在線性緩沖模式下(通過向ADCC_CBSIZ寄存器寫入零來激活),會以持續(xù)增加的線性化方式在存儲器中存儲額外的幀,中間隔開一個幀的增量值。若向ADCC_CBSIZ寫入非零值M,則會激活循環(huán)緩沖,且在幀的基址指針返回ADCC_BPTR值并開始覆蓋現(xiàn)有幀數(shù)據(jù)之前向存儲器寫入M幀。
圖19. ADC DMA傳輸?shù)拇鎯ζ髋渲?/p>
在圖17中的電機(jī)控制應(yīng)用示例中,每個PWM周期都會采集ADC樣本,并即刻用于控制和監(jiān)控應(yīng)用中。因此,將樣本以線性方式存儲毫無意義,因為存儲器將很快過載。在此類應(yīng)用中,最好在啟用循環(huán)緩沖時將M限制為1或更小的值,或者將ADCC_FRINC值設(shè)為0并在每個PWM周期中覆蓋幀。簡化這項任務(wù)的驅(qū)動程序應(yīng)用編程接口(API)可在“ADCC軟件支持”部分找到。
ADCC軟件支持
與ADSP-CM40x EZKIT一同提供的ADI Enablement Software軟件包內(nèi)含一系列API函數(shù)調(diào)用命令,可簡化本應(yīng)用筆記中討論的ADCC模塊設(shè)置。這些調(diào)用命令監(jiān)控不同寄存器的正確配置以及需要執(zhí)行的任何狀態(tài)確認(rèn)。
示例代碼
本應(yīng)用筆記中的示例代碼逐步說明配置并使用圖17中電機(jī)控制應(yīng)用的方法。器件驅(qū)動程序會增加額外開銷,但極大地簡化ADCC模塊寄存器編程。
代碼的第一部分定義一系列參數(shù)和配置常數(shù),用于驅(qū)動程序API調(diào)用。
第1行至第10行定義每個定時器的幀和關(guān)聯(lián)的數(shù)據(jù)緩沖器大小。分配樣本緩沖器長度時,將包含系數(shù)2作為安全措施,用于調(diào)試目的。由于ADC樣本傳輸至存儲器的操作完全通過硬件觸發(fā)(包括DMA),因此在將新的緩沖器提交給驅(qū)動程序以及復(fù)位ADC緩沖器指針之前,如果在第122行插入軟件斷點,則可能導(dǎo)致存儲器被覆寫。以一個額外緩沖作為裕量可防止出現(xiàn)此類調(diào)試相關(guān)問題。緩沖器中的幀數(shù)目定義為1,這表示每次收到新幀,API便會覆寫存儲器緩沖器,即每個定時器僅需針對1個幀進(jìn)行存儲器分配。
第11行到第16行以ACLK周期數(shù)形式定義每個事件的采樣時間,如表3所示。
注意,SMP_TIME1、SMP_TIME2和SMP_TIME3僅以一個ACLK周期分隔。該設(shè)置使這些事件在ADC0內(nèi)以流水線方式進(jìn)行處理。
第17行至第44行定義每個ADC通道的控制字、6個采樣事件的通道映射,以及數(shù)據(jù)緩沖器中每個事件的數(shù)組索引。
?
第45行至第59行聲明ADC操作所需的變量和函數(shù)原型。ADCC存儲器緩沖器和ADCC定時器存儲器緩沖器的存儲器分配大小由API預(yù)定義,且不得進(jìn)行更改。一個ADCC設(shè)置函數(shù)、一個TRU設(shè)置函數(shù)以及兩個ISR回調(diào)函數(shù)(每個ADCC定時器各一個回調(diào)函數(shù))對寄存器進(jìn)行設(shè)置。
第60行至91行包含主ADCC配置函數(shù)SetupADC()。第一步是設(shè)置事件配置表,即含有事件編號、ADC控制字、ADC定時器、同步采樣以及每個事件的存儲器偏置的struct。
正確完成ADCC事件配置后,必須開啟ADCC實例,以及與該實例相關(guān)的所有ADCC定時器。然后,必須在寄存器中設(shè)置每個定時器幀中斷的驅(qū)動程序回調(diào)函數(shù)名(第72行至73行)。隨后,使能DMA模式(第74行),配置ADCC時鐘和芯片選擇(第75行至第78行)。
第81行將第62行定義的EventCFG指令傳遞至adi_adcc_ConfigEvent驅(qū)動程序函數(shù),隨后adi_adcc_SetEventMask驅(qū)動程序函數(shù)按需使能或屏蔽事件。本例中,使能全部事件。為了獲得最高的ADC吞吐速率,使能雙位數(shù)據(jù)接口很重要,代碼見第83行,這表示能在8個ADC時鐘周期內(nèi)傳輸ADC的16位數(shù)據(jù)。(注意,如果沒有使能雙位接口,則第76行中的NCK以及第77行和第78行中的tCSCS必須分別設(shè)為16和17)。然后進(jìn)行數(shù)據(jù)緩沖器的存儲器分配,數(shù)據(jù)緩沖器將提交至ADCC,以便通過adi_adcc_SubmitBuffer調(diào)用進(jìn)行填充。adi_adcc_SubmitBuffer API僅在DMA模式下工作;因此使用該API之前必須先設(shè)置DMA模式。該驅(qū)動程序函數(shù)由主應(yīng)用程序再次調(diào)用(第105行),以便應(yīng)用程序完成數(shù)據(jù)提取后將緩沖器歸還給ADCC控制。最終,完成全部配置后,需要使能定時器實例以及ADCC自身。
第92行至第97行包含TRU的設(shè)置步驟。它包括開啟TRU實例、將觸發(fā)從PWM sync主機(jī)路由至ADCC從機(jī),以及使能TRU。
如前文所述,在應(yīng)用層處理ADC數(shù)據(jù)由ADCC定時器回調(diào)函數(shù)實現(xiàn),該回調(diào)函數(shù)后跟一個中斷,此中斷在完成定時器事件以及相關(guān)的DMA傳輸后發(fā)出。
第98至第127行實現(xiàn)回調(diào)函數(shù)。緩沖數(shù)據(jù)在緩沖器的相應(yīng)位置處提取,并保存至適當(dāng)?shù)娜肿兞恐小1纠校潞蟮南辔浑娏鲾?shù)據(jù)立即用于電機(jī)控制算法中,通過第117行中的算法調(diào)用函數(shù)MotorControl()從定時器1回調(diào)函數(shù)中調(diào)用。
注意,ADCC事件定時器中斷服務(wù)是訪問ADCC數(shù)據(jù)時發(fā)生的唯一軟件調(diào)用例程。同步與時序均在硬件層面中實現(xiàn)。
第128行至第136行包含的附加代碼片段可插入TRU和ADCC設(shè)置函數(shù),以使能圖11所示的增強(qiáng)型精確采樣時序功能。第128行至第129行中設(shè)置了從PWM SYNC至GP定時器TMR7再至ADCC定時器0觸發(fā)的硬件觸發(fā)路由路徑。第130行至第136行包含的示例代碼可插入ADC設(shè)置函數(shù),以正確配置和使能GP定時器TMR7,從而提供正確的延遲。
無論何時,都必須在調(diào)用SetupADC函數(shù)前調(diào)用SetupTRU函數(shù)。
P15
/*************************************************
ADCC Module Setup Code Example
*************************************************/
/********************Defines*********************/
1. #define ADCC_DEVICE_NUM 0
2. #define TRU_DEV_NUM 0
3. #define ADI_TRU_REQ_MEMORY
4. #define NUM_SAMPLES0 4
5. #define NUM_SAMPLES1 2 /* Length of ADC buffers */
6. #define FRAME_INC0
2*NUM_SAMPLES0*sizeof(short)
7. #define FRAME_INC1
2*NUM_SAMPLES1*sizeof(short) /* Frame
increment in number of bytes for each buffer*/
8. #define FRAMES_IN_BUFFER 1 /*Number of frames in buffer */
9. #define NO_OF_EVENTS 6 /* Total number of events */
10. #define EVENT_MASK 0xFFFF
/*Event Times in ACLK Cycles*/
11. #define SMP_TIME0 950
12. #define SMP_TIME1 950
13. #define SMP_TIME2 951
14. #define SMP_TIME3 952
15. #define SMP_TIME4 0
16. #define SMP_TIME5 0
/* Control Words for All ADC Channels */
/*Upper Nibble = Chan No. Lower Nibble = 0xF for Sim Sampling, 0xD Otherwise*/
17. #define ADC0_VIN00_CTL 0x0F
18. #define ADC0_VIN01_CTL 0x1F
19. #define ADC0_VIN02_CTL 0x2D
20. #define ADC0_VIN03_CTL 0x3D
21. #define ADC0_VIN04_CTL 0x4D
22. #define ADC0_VIN05_CTL 0x5D
23. #define ADC0_VIN06_CTL 0x6D
24. #define ADC0_VIN07_CTL 0x7D
25. #define ADC1_VIN00_CTL 0x0F
26. #define ADC1_VIN01_CTL 0x1F
27. #define ADC1_VIN02_CTL 0x2D
28. #define ADC1_VIN03_CTL 0x3D
29. #define ADC1_VIN04_CTL 0x4D
30. #define ADC1_VIN05_CTL 0x5D
31. #define ADC1_VIN06_CTL 0x6D
32. #define ADC1_VIN07_CTL 0x7D
/*Mapping the Signals to the Appropriate ADC Channels*/
33. #define ES_CTL ADC0_VIN00_CTL
34. #define EC_CTL ADC1_VIN00_CTL
35. #define VDC_CTL ADC0_VIN02_CTL
36. #define THS_CTL ADC0_VIN03_CTL
37. #define IV_CTL ADC0_VIN01_CTL
38. #define IW_CTL ADC1_VIN01_CTL
/*Locations of ADC Signals in Data Buffer Index*/
39. #define IV_ADC 0
40. #define IW_ADC 1
41. #define ES_ADC 0
42. #define EC_ADC 1
43. #define VDC_ADC 2
44. #define THS_ADC 3
/*******************Variables********************/
45. static ADI_ADCC_HANDLE hADCC; /* ADCC Handle */
46. static ADI_ADCC_HANDLE hADCCTimer0, hADCCTimer1; /*ADCC Timer Handles*/
47. static uint8_t ADCCMemory[ADI_ADCC_MEMORY]; /* Memory buffer for the ADCC device - predefined */
48. static uint8_t ADCCTmr0Memory[ADI_ADCC_TMR_MEMORY];
49. static uint8_t ADCCTmr1Memory[ADI_ADCC_TMR_MEMORY]; /* Memory buffer for the ADCC Timers - predefined*/
50. static uint16_t SampleBuffer0[NUM_SAMPLES0];
51. static uint16_t SampleBuffer1[NUM_SAMPLES1];
/* Memory buffer for the ADC samples */
52. static uint16_t Iv_adc, Iw_adc;
53. static uint16_t Es_adc, Ec_adc, Vdc_adc, Ths_adc;
/*Variables for ADC data*/
54. static uint8_t TruDevMemory[ADI_TRU_REQ_MEMORY];
55. static ADI_TRU_HANDLE hTru;
/*TRU Device Memory and Handle*/
/*************Function Prototypes****************/
56. void SetupADC(void);
57. void SetupTRU(void);
58. static void AdccTmr0Callback(void *pCBParam, uint32_t Event, void *pArg);
59. static void AdccTmr1Callback(void *pCBParam, uint32_t Event, void *pArg);
/******Function to Configure ADCC***************/
60. void SetupADC(void) {
61. static ADI_ADCC_RESULT result;
/*Set Up Event Configuration Table*/
62. ADI_ADCC_EVENT_CFG EventCFG[NO_OF_EVENTS] = {
63. {0, ES_CTL, ADI_ADCC_ADCIF0, ADI_ADCC_TIMER0, true, 0, SMP_TIME0},
64. {1, EC_CTL, ADI_ADCC_ADCIF1, ADI_ADCC_TIMER0, true, 2, SMP_TIME1},
65. {2, VDC_CTL, ADI_ADCC_ADCIF0, ADI_ADCC_TIMER0, false, 4, SMP_TIME2 },
66. {3, THS_CTL, ADI_ADCC_ADCIF0, ADI_ADCC_TIMER0, false, 6, SMP_TIME3 },
67. {4, IV_CTL, ADI_ADCC_ADCIF0, ADI_ADCC_TIMER1, true, 8, SMP_TIME4 },
68. {5, IW_CTL, ADI_ADCC_ADCIF1, ADI_ADCC_TIMER1, true, 10, SMP_TIME5 }}; /*Event#, CTL_WORD, ADC Interface, Timer ID, sim. samp, Mem offset in frame, Event time */
P16
/*ADCC Setup API Functions*/
69. result = adi_adcc_OpenDevice(ADCC_DEVICE_NUM, ADCCMemory, &hADCC);
70. result = adi_adcc_OpenTimer(hADCC, ADI_ADCC_TIMER0, ADCCTmr0Memory, &hADCCTimer0);
71. result = adi_adcc_OpenTimer(hADCC, ADI_ADCC_TIMER1, ADCCTmr1Memory, &hADCCTimer1); /* ADCC Device handle, Timer to open, Timer memory, Pointer to the timer handle */
72. result = adi_adcc_RegisterTmrCallback (hADCCTimer0, AdccTmr0Callback, hADCCTimer0);
73. result = adi_adcc_RegisterTmrCallback (hADCCTimer1, AdccTmr1Callback, hADCCTimer1);/*Register callback functions*/
74. result = adi_adcc_EnableDMAMode(hADCC,true);
75. result = adi_adcc_ConfigADCCClock(hADCC, ADI_ADCC_ADCIF0, false,1u, 8u);
76. result = adi_adcc_ConfigADCCClock(hADCC, ADI_ADCC_ADCIF1, false,1u, 8u ); /*For each ADC interface: ADCC handle, ADC Interface number, falling edge, ACLK Clock divide, NCK*/
77. result = adi_adcc_ConfigChipSelect(hADCC, ADI_ADCC_ADCIF0, false, 1u, 0u, 9);
78. result = adi_adcc_ConfigChipSelect(hADCC, ADI_ADCC_ADCIF1, false, 1u, 0u, 9);/*For each interface: ADCC handle, ADC interface, active low, TCSCK, TCKCS, TCSCS*/
79. result = adi_adcc_ConfigTimer(hADCCTimer0, ADI_ADCC_TRIG0, true, false);
80. result = adi_adcc_ConfigTimer(hADCCTimer1, ADI_ADCC_TRIG0, true, false); /*For each timer: Timer handle, Timer trigger source, falling edge trigger, No trigger output */
81. result = adi_adcc_ConfigEvent(hADCC, &EventCFG[0], NO_OF_EVENTS); /*ADCC handle, Pointer to the event configuration table, Number of events in the table */
82. result = adi_adcc_SetEventMask(hADCC, EVENT_MASK); /* Handle to the device, Enable all events */
83. adi_adcc_EnableDualBitDataIF(hADCC, true); /*Dual bit interface allows highest throughput*/
84. memset((void *)SampleBuffer0, 0, NUM_SAMPLES0 * sizeof(short));
85. memset((void *) SampleBuffer1, 0, NUM_SAMPLES1 * sizeof(short));
86. result = adi_adcc_SubmitBuffer(hADCCTimer0, SampleBuffer0, FRAME_INC0, FRAMES_IN_BUFFER);
87. result = adi_adcc_SubmitBuffer(hADCCTimer1, SampleBuffer1, FRAME_INC1, FRAMES_IN_BUFFER);
/*For each timer: timer handle, Pointer to the buffer, Frame increment, Number of frames that fits into the given buffer */
88. result = adi_adcc_EnableTimer(hADCCTimer0, true);
89. result = adi_adcc_EnableTimer(hADCCTimer1, true);
90. result = adi_adcc_EnableDevice(hADCC, true);
/*Enable everything*/
91. }
/*******Function to Configure TRU****************/
92. void SetupTRU(void){
93. ADI_TRU_RESULT result;
94. result = adi_tru_Open (TRU_DEV_NUM, &TruDevMemory[0], ADI_TRU_REQ_MEMORY, &hTru); /* Setup TRU for ADCC. Slave is ADCC0 trig 1 and master is PWM0 SYNC pulse*/
95. result = adi_tru_TriggerRoute (hTru, TRGS_ADCC0_TRIG0, TRGM_PWM0_SYNC); /*TRU device, slave, master*/
96. result = adi_tru_Enable (hTru, true); /*Enable TRU*/
97. }
/***********ADCC Timer Callbacks*****************/
98. static void AdccTmr0Callback(void *pCBParam, uint32_t Event, void *pArg){
99. switch(Event){
100. case ADI_ADCC_EVENT_FRAME_PROCESSED:
101. Es_adc= SampleBuffer0[ES_ADC];
102. Ec_adc = SampleBuffer0[EC_ADC];
103. Vdc_adc = SampleBuffer0[VDC_ADC];
104. Ths_adc = SampleBuffer0[THS_ADC];
/*Store all of the data sampled in appropriate global variables*/
105. _adcc_SubmitBuffer(hADCCTimer0, SampleBuffer0, FRAME_INC0, FRAMES_IN_BUFFER); /*Return the buffer to the ADCC for use in the next events*/
106. break;
107. case ADI_ADCC_EVENT_BUFFER_PROCESSED:
108. break;
109. default:
110. break;
111. }
112. static void AdccTmr1Callback(void *pCBParam, uint32_t Event, void *pArg){
113. switch(Event){
114. case ADI_ADCC_EVENT_FRAME_PROCESSED:
115. Iv_adc = SampleBuffer1[IV_ADC];
116. Iw_adc = SampleBuffer1[IW_ADC];
117. MotorControl(); /*Run the current control algorithm*/
118.
119.
120. break;
121. case ADI_ADCC_EVENT_BUFFER_PROCESSED:
122. adi_adcc_SubmitBuffer(hADCCTimer1, SampleBuffer1,
FRAME_INC1, FRAMES_IN_BUFFER);
123. break;
124. default:
125. break;
126. }
127. return;
}
P17
/*************************************************
Enhanced Precision Timing Code
*************************************************/
/*Setup TRU for ADCC enhanced timing precision. Slave is ADCC0 trig 1 and master is GP timer 7
Added to SetpTRU() function in place of line 95 */
128. result = adi_tru_TriggerRoute(hTru, TRGS_ADCC0_TRIG0, TRGM_TIMER0_TMR7); // TRU device, slave, master
129. result = adi_tru_TriggerRoute(hTru, TRGS_TIMER0_TMR7, TRGM_PWM0_SYNC); // TRU device, slave, master
/*Setup GP timer 7 timer used to advance frame by one CS. Add to SetupADC() function after line 91*/
130. *pREG_TIMER0_STOP_CFG_SET = BITM_TIMER_STOP_CFG_TMR07;
131. *pREG_TIMER0_RUN_CLR = BITM_TIMER_RUN_SET_TMR07; /*Disable Timer First*/
132. *pREG_TIMER0_TMR7_CFG = ENUM_TIMER_TMR_CFG_PWMSING_MODE|ENUM_TIMER_TMR_CFG_IRQMODE1 |ENUM_TIMER_TMR_CFG_TRIGSTART | ENUM_TIMER_TMR_CFG_POS_EDGE|ENUM_TIMER_TMR_CFG_PADOUT_EN | ENUM_TIMER_TMR_CFG_EMU_CNT;
133. *pREG_TIMER0_TMR7_DLY = (uint32_t)(fsysclk / F_SW - 0.00000045 * fsysclk); /* Delay must be Tsw minus one ADC chip-select. Chip select is 18 ACLKs*/
134. *pREG_TIMER0_TMR7_WID = 16; /*Be careful here... DLY+WID must be smaller than one PWM period. In other words, WID must be smaller than one ADC chip select. If WID>CS, trigger pulse stretches into next PWM period. */
135. *pREG_TIMER0_TRG_MSK &= ~(BITM_TIMER_TRG_MSK_TMR07);
136. *pREG_TIMER0_TRG_IE |= BITM_TIMER_TRG_IE_TMR07; /*Enable TMR7*/
示例實驗結(jié)果
“示例代碼”部分提供的電流采樣代碼部分已在閉環(huán)永磁同步電機(jī)控制應(yīng)用電路中進(jìn)行了測試。應(yīng)用電路采用通用交流線輸入以及?6.8 A至+6.8 A的受控電機(jī)電流范圍,并利用了電流傳感器;該電流傳感器參數(shù)圖4中的電流調(diào)整數(shù)據(jù)。圖20至圖23還顯示了應(yīng)用電路的采樣結(jié)果。
圖20顯示了參考速度為1500 rpm且電機(jī)空載時測得的電機(jī)相位電流。電機(jī)電流水平極低,并且高度不連續(xù)。
圖21顯示采用正確同步采樣方法的平均效應(yīng),由圖中可見電機(jī)相位電流具有平滑的正弦平均波形,即便電流水平低于最大值的2%時亦是如此。圖21和圖22(即跟蹤IQ參考電流的控制環(huán)路工作曲線)均通過ADSP-CM408F產(chǎn)生的數(shù)據(jù)流獲得,該產(chǎn)品通過RS-232連接MATLAB?接口。
在圖23中,PWM sync脈沖位置以及后續(xù)的采樣觸發(fā)顯示在相位電流PWM周期的中央,該處電流等于瞬時平均值。為便于說明,該圖顯示的是較高的負(fù)載。
圖20. 測量電機(jī)相位電流
圖21. ADC采樣電機(jī)相位電流:上圖為調(diào)整至真實值;下圖為數(shù)字字輸出
圖22. Q軸參考電流和實際電流
最后,在圖22中,PWM SYNC脈沖位置以及后續(xù)的采樣觸發(fā)顯示在相位電流PWM周期的中央,該處電流等于瞬時平均值。為便于說明,該圖顯示的是較高的負(fù)載。
圖23. 與相位電流有關(guān)的采樣
注釋
I2C指最初由Philips Semiconductors(現(xiàn)為NXP Semiconductors)開發(fā)的一種通信協(xié)議。
?
評論