認識了 mbed 的類比訊號輸入之後,我們接下來要看的是 mbed 的類比輸出啦~
類比輸出
稍有基礎的朋友應該會把類比訊號輸出和 PWM 輸出連想在一起,但這兩者的動作實際上是不相同的。
PWM 是藉由調整脈波寬度來達到調整電壓高低的目的(可參考 Arduino 之軟體 PWM 這篇文章的內容),而 AnalogOut 則是直接將電壓輸出至指定比例的電壓,兩者在根本上有非常大的差距。
不過,最後輸出結果都屬於類比訊號的一種,也因此今天的文章將會把 mbed 的類比輸出以及 PWM 輸出一併介紹給你認識。
開始之前
這次要準備的東西比較麻煩一些,因為有個設備不容易取得,但這個可以不準備沒關係。
- mbed LPC1768
- 三用電表 (數位、類比皆可)
- 示波器 (可忽略)
硬體接線
類比輸出 – AnalogOut
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
#include "mbed.h" // 這個腳位會產生一個正弦波訊號 AnalogOut aout(p18); int main() { const double pi = 3.141592653589793238462; const double amplitude = 0.5f; const double offset = 65535/2; double rads = 0.0; uint16_t sample = 0; while(1) { // 輸出正弦波 for (int i = 0; i < 360; i++) { rads = (pi * i) / 180.0f; sample = (uint16_t)(amplitude * (offset * (cos(rads + pi))) + offset); aout.write_u16(sample); } } } |
這個範例程式的執行結果如下圖:
幾乎完整的重現一個漂亮的正弦波形呢!
下面這個範例程式的版本是用 LED 做為展示,你應該可以看到這兩顆 LED 以互補的方式交替漸亮與漸暗。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
#include "mbed.h" // 這個腳位會產生一個正弦波訊號 AnalogOut aout(p18); int main() { const double pi = 3.141592653589793238462; const double amplitude = 0.5f; const double offset = 65535/2; double rads = 0.0; uint16_t sample = 0; while(1) { // 輸出正弦波 for (int i = 0; i < 360; i++) { rads = (pi * i) / 180.0f; sample = (uint16_t)(amplitude * (offset * (cos(rads + pi))) + offset); aout.write_u16(sample); // 等待 10ms 降低更新速度 wait(0.01); } } } |
接線方式如開頭的硬體接線方式。
會這樣的原因是因為正弦波的特性的關係,這邊產生的正弦波理論上是一個從 0V ~ 3.3V 的一個信號,所以當你利用如上的接法去接時,就會有如影片的效果。
類比輸出 – PwmOut
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#include "mbed.h" PwmOut led(LED1); int main() { while(1) { for(float p = 0.0f; p < 1.0f; p += 0.1f) { led = p; wait(0.1); } for(float p = 1.0f; p > 0.0f; p -= 0.1f) { led = p; wait(0.1); } } } |
在 PwmOut 這個範例程式中,值得注意的是,我用的並非 mbed LPC1768 接線上的外部接腳,而是用板子上的 LED1 來作為輸出。這是因為 mbed LPC1768 LED 1 ~ LED 4 是接於它的 PWM 1 ~ PWM 4 上,所以才能這樣設定,你可以參考如下的對照表格。
PWM H/W Channel | Pinout Options |
---|---|
PWM_1 | p26 or LED1 |
PWM_2 | p25 or LED2 |
PWM_3 | p24 or LED3 |
PWM_4 | p23 or LED4 |
PWM_5 | p22 |
PWM_6 | p21 |
範例執行結果如影片
從影片中你可以發現 LED 雖然也會漸亮漸暗,但在較暗時會有閃爍的現象產生,這原因是因為 PWM 是靠調整脈波來調整整體電壓平均值所造成的。當 LED 較暗時,脈波的工作週期是拉長的,所以人眼暫留視覺看時會覺得 LED 是暗的。
當然,這跟 PWM 預設的頻率有點關係,在 mbed LPC178 中的預設週期是 0.02 秒,預設脈波寬度是 0。
你可以透過它提供的方法來調整這些參數
方法名稱 | 敘述 |
---|---|
write (float value) | 設定工作週期 |
period (float seconds) | 以秒為單位設定週期 |
period_ms (int ms) | 以毫秒為單位設定週期 |
period_us (int us) | 以微秒為單位設定週期 |
pulsewidth (float seconds) | 以秒為單位設定脈寬 |
pulsewidth_ms (int ms) | 以豪秒為單位設定脈寬 |
pulsewidth_us (int us) | 以微秒為單位設定脈寬 |
總結
事實上, mbed 的類比輸出是用模擬的方式達成的,也就是所謂的 DAC 轉換,因此它並沒有辦法作到相當細緻的輸出控制,但對於 LED 的亮度控制以及馬達的轉速控制來說,這樣的方式已經非常的足夠了。
是說這內建的 ADC 應該可以做出一個相當不錯的隨身聽?改天來試試。