Categories: mbed

mbed 基礎教學實驗 – 類比訊號輸出

認識了 mbed 的類比訊號輸入之後,我們接下來要看的是 mbed 的類比輸出啦~

類比輸出

稍有基礎的朋友應該會把類比訊號輸出和 PWM 輸出連想在一起,但這兩者的動作實際上是不相同的。

PWM 是藉由調整脈波寬度來達到調整電壓高低的目的(可參考 Arduino 之軟體 PWM 這篇文章的內容),而 AnalogOut 則是直接將電壓輸出至指定比例的電壓,兩者在根本上有非常大的差距。

不過,最後輸出結果都屬於類比訊號的一種,也因此今天的文章將會把 mbed 的類比輸出以及 PWM 輸出一併介紹給你認識。

開始之前

這次要準備的東西比較麻煩一些,因為有個設備不容易取得,但這個可以不準備沒關係。

  • mbed LPC1768
  • 三用電表 (數位、類比皆可)
  • 示波器 (可忽略)

硬體接線

類比輸出 – AnalogOut

#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 以互補的方式交替漸亮與漸暗。

#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

#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 應該可以做出一個相當不錯的隨身聽?改天來試試。

duye.chen

Recent Posts

[教學] 打造你的 NFT 智能合約 – ERC721A

GM!前些日子在幣圈亂玩,一路...

2 年 ago

JavaScript – Singleton 設計模式

前言 在設計程式時,我們有時會...

4 年 ago

PlaidML 讓你的 Mac 也能加速 Tensorflow 機器學習!

相信很多使用 Mac 或者手上...

4 年 ago

RESTful API 測試很煩,只好動手寫屬於自己的測試了

寫在最前面 嗨,大家好久不見!...

4 年 ago

Node.js 與 Socket.io – 即時聊天室實作:資料庫

經過前兩篇(一、二)文章,我們...

7 年 ago