使用 Arduino Nano 的示例電路
出處:維庫電子市場網 發(fā)布于:2024-10-31 16:23:15 | 375 次閱讀
您正在使用的 MCU 中有兩個組件:脈沖寬度調制器 (PWM) 輸出和板載模擬比較器。一些具有這些功能的 MCU 系列包括 Microchip 的 PIC、AVR 和 ATmega MCU。此外,TI 的 Piccolo 系列和 STMicroElectronics STM32L5 都具有 PWM 和比較器。
那么,讓我們看看它是如何配置的。

電阻器和電容器形成單極低通濾波器。因此,電路概念采用板載 PWM 的輸出,對其進行濾波以創(chuàng)建由 PWM 占空比設置的直流信號。然后使用板載比較器將直流電平與輸入信號進行比較。該電路非常簡單,所以我們來討論一下用于根據這種布置創(chuàng)建 ADC 的代碼。
為了獲得輸入信號的樣本讀數(shù),我們首先將 PWM 設置為 50% 占空比。該方波 PWM 信號將由 RC 低通濾波器進行濾波,以產生 MCU 系統(tǒng)電壓 1/2 的電壓。如果濾波后的直流電平大于瞬時輸入信號電壓,比較器輸出將變高(或輸出數(shù)字1),否則比較器輸出將變低(輸出數(shù)字0)。
現(xiàn)在,代碼將讀取比較器輸出并執(zhí)行搜索以查找強制比較器輸出相反輸出的新級別。換句話說,如果比較器為 0,則代碼將調整 PWM 占空比,直到比較器輸出 1。如果比較器當前顯示 1,則 PWM 占空比將減小,直到比較器輸出 0。如果PWM 的占空比能夠達到 256 個步長(或更多),此搜索可能需要一些相當長的時間。為了緩解這個問題,我們將進行二分搜索,因此如果 PWM 中有 256 個可用步驟,則只需使用 log 2 (256) 或 8 個步驟來測試級別。
對二分搜索的簡單描述是,在第一個 50% 級別讀取之后,下一次測試將在 25% 或 75% 級別進行,具體取決于比較器輸出的狀態(tài)。此后的步驟將再次測試剩余級別的中間部分。
電路功能示例
讓我們展示一個簡單的示例并假設以下情況:
系統(tǒng)電壓:5V
PWM 可用級別:256
瞬時輸入信號:1V
第一個測試將以約 50% 占空比(設置為 128)的 PWM 執(zhí)行,創(chuàng)建一個應用于比較器“+”輸入的 2.50V 信號。這意味著比較器將輸出高電平,這意味著 PWM 占空比太高。因此,我們將占空比設置為 64,將占空比減半,這會在“+”輸入上產生 1.25 V 電壓。比較器將再次輸出 1…至高電平,因此我們將 PWM 占空比再次降低一半至 32。這給出了 0.625 V 的“+”電平?,F(xiàn)在比較器將輸出 0,因此我們知道我們的電壓太低了,并且我們增加 PWM 占空比。我們知道 64 太高,32 太低,所以我們去中心,或者 (64+32)/2 = 48,給出 0.9375 V。我們仍然太低,所以我們將 64 和 48 的差值分開,得到56 或約 1.094 V……太高了。繼續(xù)下去,得到 (56+48)/2=52,給出 1.016 V……太高了。同樣,PWM 設置為 (52+48)/2=50,給出 0.9766 V。最后一步,(52+50)/2=51,給出 0.9961 V。
這 8 個步驟讓我們盡可能接近答案。因此,我們的 ADC 設置將返回瞬時輸入信號為 0.9961 V 的答案。
使用 Arduino Nano 的示例電路 讓我們看一個現(xiàn)實世界的例子。此示例使用 Arduino Nano,其中使用 ATmega328P,該 ATmega328P 具有多個 PWM 輸出和一個模擬比較器。我們將使用的 PWM 可以以各種速率計時,并且我們希望快速計時,因為這將使過濾更容易。它還將加快濾波器輸出穩(wěn)定到最終水平的時間。我們將選擇大約 31.4 kHz 的 PWM 時鐘速率。圖 2顯示了帶有單極 RC 低通濾波器的原理圖。
在此原理圖中,D11 是 PWM 輸出,D6 是比較器的“+”輸入,而 D7 是比較器的“-”輸入。該濾波器由 20kΩ 電阻器和 0.1F 電容器組成。我通過 LTspice 模擬得出這些值,試圖最大限度地減少 PWM 脈沖(紋波)的殘余,同時保持相當快的穩(wěn)定時間。紋波的目標是 PWM 中 1 位變化的分辨率或更少。使用 5 V 系統(tǒng)電壓和 PWM 具有 8 位(256 個設置)可調性的信息,我們得到 5 V/256 = ~20 mV。在 LTspice 仿真中,我得到了 18 mV 的紋波,而直流電平在 15 ms 時穩(wěn)定在其最終值的幾毫伏以內。因此,在編寫代碼時,我使用 15 毫秒作為樣本之間的延遲(您將在下面看到一個小改動)。由于需要 8 個讀數(shù)才能獲得最終可用樣本,因此需要 8*15 ms = 120 ms,即每秒 8.3 個樣本。正如一開始所指出的,您不會以音頻速率進行采樣,但您當然可以監(jiān)視板上的直流電壓或緩慢移動的模擬信號。
[這可能是一個值得注意的地方,模擬輸入不像大多數(shù) ADC 那樣具有采樣和保持功能,因此讀數(shù)是一個不斷變化的目標。此外,輸入信號沒有抗混疊濾波器。如果需要,抗混疊濾波器可以消除噪聲,還可以充當粗略采樣和保持的作用。]
示例代碼
下面是在 Arduino 開發(fā)環(huán)境中使用的代碼清單。您也可以在這里下載。它將讀取輸入信號,進行二分查找,將其轉換為電壓,然后顯示最終的 8 位 DAC 值、相應的電壓讀數(shù)以及移動較慢的濾波值。
下面對代碼進行更深入的描述:
第 1-8 行定義了我們用于 PWM 的引腳并聲明了我們的變量。請注意,第 3 行設置系統(tǒng)電壓。該值應在 MCU 的 Vcc 引腳上測量。
第 11 行和第 12 行將 PWM 設置為所需的頻率。
第 15 行和第 16 行設置了我們正在使用的板載比較器。
第 18 行初始化我們將在其上打印結果的串行端口。
第 22 行是主代碼開始的地方。首先,我們每次都會初始化一些變量以開始二分搜索。
第 29 行我們開始 8 步二分搜索,第 30 行設置 PWM 的占空比。然后引入 15 毫秒的延遲以使低通濾波器穩(wěn)定下來。
第 34 行是上面暗示的“小轉折”。這會引入 0 到 31 微秒之間的第二個隨機延遲。之所以將其包含在內,是因為濾波器之后出現(xiàn)的 PWM 紋波與 16 MHz MCU 的時鐘相關,因此,為了幫助將其從最終讀數(shù)中濾除,我們注入了此延遲以打破相關性。
第 37 和 38 行將在執(zhí)行延遲后檢查比較器。根據比較檢查,調整下一個 PWM 占空比的范圍。
第 40 行計算這個新范圍內的新 PWM 占空比。然后代碼循環(huán) 8 次以完成二分查找。
第 43 行和第 44 行計算當前瞬時電壓讀數(shù)以及濾波后的平均電壓讀數(shù)的電壓。該電壓平均是使用非常簡單的 IIR 濾波器來完成的。
第46-51行將信息發(fā)送到Arduino串行監(jiān)視器進行顯示。
1 #define PWMpin 11 // pin 11 is D11
2
3 float systemVoltage = 4.766; // Actual voltage powering the MCU for calibrating printedoutput voltage
4 float ADCvoltage = 0; // Final discovered voltage
5 float ADCvoltageAve = 0; // Final discovered voltage averaged
6 uint8_t currentPWMnum = 0; // Number sent to the PWM to generate the requested voltage
7 uint8_t minPWMnum = 0;
8 uint8_t maxPWMnum = 255;
9
10 void setup() {
11 pinMode(PWMpin, OUTPUT); // Set up PWM for output
12 TCCR2B = (TCCR2B & B11111000) | B00000001; // Set timer 1 to 31372.55 Hz which is now the D11 PWM frequency
13
14 // Set up comparator
15 ADCSRB = 0b01000000; // (Disable) ACME: Analog Comparator Multiplexer disabled
16 ACSR = 0b00000000; //enable AIN0 and AIN1 comparison with interrupts disabled
17
18 Serial.begin(9600); // open the serial port at 9600 bps:
19 }
20
21
22 void loop() {
23
24 currentPWMnum = 127; // Start binary search at the halfway point
25 minPWMnum = 0;
26 maxPWMnum = 255;
27
28 // Perform a binary search for matching comparator setting
29 for (int8_t i = 0; i < 8; i++) { // Loop 8 times
30 analogWrite(PWMpin, currentPWMnum); // Adjust PWM to new dutycycle setting
31
32 // Now wait
33 delay(15); // Wait 15 ms to let the low-pass filter to settle.
34 delayMicroseconds(random(0,32)); // Delay a random number of microseconds (0 thru 31) to break possible correlation (dithering)
35
36 // Check to see if comparator shows AIN0 > AIN1 ( if so ACO in ACSR is set to 1)
37 if (ACSR & (1<<ACO)) maxPWMnum = currentPWMnum; // (AIN0 > AIN1) Move max pointer
38 else minPWMnum = currentPWMnum; // Move min pointer
39
40 currentPWMnum= minPWMnum + ((maxPWMnum - minPWMnum) / 2); // Set new test number to the middle of PWMmin and PWMmax
41 }
42
43 ADCvoltage = systemVoltage * ((float)currentPWMnum/255); // Set the PWM for binary search of voltage (assumes 0 to 5v signal
44 ADCvoltageAve = (ADCvoltageAve * 0.95) + (ADCvoltage * 0.05); // Generate an average value to smooth reading
45
46 Serial.print("PWM Setting = ");
47 Serial.print(currentPWMnum);
48 Serial.print(" ADC Voltage = ");
49 Serial.print(ADCvoltage, 4);
50 Serial.print(" ADC Voltage Filtered = ");
51 Serial.println(ADCvoltageAve, 4);
52 }
測試結果
第一步是測量 +5-V 引腳或 Arduino Nano 上的系統(tǒng)電壓。該值 (4.766 V) 在代碼的第 3 行輸入。然后,我在 Arduino Nano V3 上運行代碼并監(jiān)視 Arduino 串行監(jiān)視器上的輸出。為了測試代碼和系統(tǒng),我首先將 2.5V 參考電壓連接到信號輸入。首先對該基準進行預熱,并在校準的 5 ? 位數(shù)字萬用表上讀取電壓讀數(shù)。參考讀數(shù)為 2.5001 V。串行監(jiān)視器顯示瞬時電壓從 2.5232 到 2.4858 V 變化,平均電壓從 2.5061 到 2.5074 V 變化。瞬時電壓讀數(shù)誤差約為 0.9%,平均電壓讀數(shù)誤差約為 0.3% 。這表明我們得到的瞬時電壓讀數(shù)誤差約為 ±1 LSB,濾波讀數(shù)約為 ±0.4 LSB。當輸入各種其他電壓時,我得到了類似的精度。
我還使用 Vcc (4.766 V) 輸入進行測試,并查看了 4.7473 V 的結果,這意味著它可以非常接近上軌工作。輸入接地時,瞬時電壓和濾波電壓顯示為 0.000 V。
上一篇:開關模式熱線恒溫器
版權與免責聲明
凡本網注明“出處:維庫電子市場網”的所有作品,版權均屬于維庫電子市場網,轉載請必須注明維庫電子市場網,http://udpf.com.cn,違反者本網將追究相關法律責任。
本網轉載并注明自其它出處的作品,目的在于傳遞更多信息,并不代表本網贊同其觀點或證實其內容的真實性,不承擔此類作品侵權行為的直接責任及連帶責任。其他媒體、網站或個人從本網轉載時,必須保留本網注明的作品出處,并自負版權等法律責任。
如涉及作品內容、版權等問題,請在作品發(fā)表之日起一周內與本網聯(lián)系,否則視為放棄相關權利。