作者:Ryan Hu
上次由於篇幅的緣故,和大家分享 8051 的 UART 之後,沒能繼續把 ADC 講完,本篇以最簡單的例子—電壓大小變化,來實作這顆 SN8F5701 埋控的 ADC 功能,文末也會稍微提到我目前正在進行的專案,與 2.4G RF 有關。
類比與數位
我們都知道現實世界是「類比」的,不過類比實在太複雜,於是聰明的人類創造出「數位」來簡化問題。如果不夠清楚,就想像類比是「連續數值的變化」,而數位只有 0 或 1,這之間的轉換牽涉到很多複雜的數學運算,像是傅立葉轉換(fourier tranform),將 time domain 的 data 轉成 frequency domain,讓原本看似沒意義的 function curve 突然間有了生命。ADC的功用就在於將類比形式的連續訊號,轉換為數位形式的離散訊號。

ADC轉換訊號簡易圖(圖片來源:Wikipedia)
ADC(Analog to Digital Converter)
這顆埋控 ADC 的部分是用 SAR 架構(聽說還有很多種),有6 個可以設為 analog input 的 pin 腳位,解析度有 4096 steps。在腦中想像一下長條圖 y 軸的刻度,就是 4096 階;如果 4096 階這個值不變, reference high voltage 和 VSS(通常都是接地 0V)相差的越小(下方會說明),解析度相對就會提高。但這有利有弊,除非進來的 analog 訊號數值和變化真的不大,否則這個情況很難發生。
上述提到的 reference high voltage(參考高電位)和 clock rate 是 ADC 中相當重要的一環,這顆埋控有四個 clock rate 可以選擇,以 datasheet 裡面提到的 converting rate,我目前的理解是每次每個數值轉換(analog to digital)的速率。所以,如果類比訊號進來的很快,但 MCU ADC 的 converting rate 設得太低,讀出來的數值可能會有問題。
之所以說以我目前的理解,是因為我在別顆埋控的 datasheet 裡面有看過 ADC sampling rate,至於這和 converting rate 是否相同,詢問前輩後得知,在大部分的狀況下是一樣的,但有些進階的 ADC 上會不一樣(就我所知 sampling rate 越高,表示越能模擬出真正 analog 訊號的全貌)。
談到參考高電位, SN8F5701 提供 4 個 sources 給開發者選擇,分別是 VDD、4V、3V、2V,以 3V 舉例,因為埋控規定 VSS (0V) <= sampled input voltage 一定要 <= 參考高電位。如果 reference high voltage 設定為 3V ,我只能去測量 0-3V 之間的數值,而 4096 這個解析度,就是將 0-3V 分割成 4096 階,去定義進來的 analog 訊號該對應到什麼二進位的數值,如下圖:

訊號資料轉換圖(圖片來源:類比數位資料轉換器 ADC 介紹)
ADC 中類比與數位的轉換過程
在 initiate ADC 之間,來談談整個轉換流程在這顆埋控中是怎麼進行的。首先要讓 ADC enable (ADENB=1),接著要讓 ADC 開始可以轉換數值(ADS=1),轉換結束後硬體自行將 ADS 變為 0 表示轉換結束,硬體也會把其他兩個 flag – EOC 和 ADCF 拉 HIGH 為 1,另外轉換好的數值就存在 ADB [11:4] 和 ADR [3:0] 兩個 registers。
而上方提到的 ADCF 其實是和 ADC 的 interrput 做搭配的。ADCF 為 1 時,如果開發者有 enable adc interrput(EADC=1),這時 ISR 會被觸發,在觸發「前」ADCF flag 就會被硬體清掉。但我並沒有用 ADC interrupt 的功能,原因下方我會說明。
*ADC 功能的初始設定的程式碼(連結)
要作為 ADC pin 腳位,首先要將 pin 設定為 input mode,再用 POCON 設為 pure analog input pin。重點是,同時間只能有一隻腳位為 analog pin,因為這顆埋控 analog 和 digital I/O 的腳位是共用的,所以非 analog pin 的腳位一律要設定好是 digital,否則會出現問題。
根據四種不同的 clock rate(ADR 的 ADCKS 設定)會對應出不同的 converting time(converting time 的時間是指從開始轉換 <ADS=1> 到結束 <EOC=1> 這段時間),我是直接開到最大,用 fosc / 1 的 clock rate 在跑,至於 reference high voltage 我是用內部 VDD(5V)作為參考高電位,因此可以利用電源供應器給 P01 這隻 pin 腳 0-5V 的類比訊號作為測試。
*部分程式碼(連結)
上方程式碼片段總共有以下三個重點:
- 要讀出來總要看得到是多少,所以需搭配 UART 以顯示在我的 console 上。
- 我之所以沒有開 ADC 的 interrupt 是因為我不需要這個常取值(但還是看如何應用,所以也不一定),我反而是用 timer0 計時,在 main 裡面每隔 1 秒讀一次 ADB 和 ADR 的值
- 因為轉換結束後不僅 EOC 會被系統拉 HIGH,ADS 也會拉 LOW,所以為了啟動下一次的轉換,勢必得清掉 EOC 並且拉 HIGH ADS
小結
理解整個原理且成功運行後,就可以在 PC 的 console 上面看到,隨著電源供應器的旋鈕被轉動,console 上顯示的數值就會跟著改變。那麼 SN8F5701 大致玩完,ADC 的功能測試就告一個段落了,雖然沒有到很深,但該摸的基本上都有摸到,繼續往下一顆埋控前進。
最後提一下我目前手邊正在進行的專案,是利用 Amiccom A8106 2.4G RF module 實作發射與接收器,RF 事實上比我想像中還要複雜,因為它是廠商自定義的 protocol,而且還要 based on 這個 protocol 去做不同的 use case(像是學習模式,接收器可以認得三隻發射器等),屆時再來分享囉!
(責任編輯:賴佩萱)
- 【NB-IoT】菜鳥Maker輕鬆上手DSI2598開發板 - 2019/12/13
- 【Maker電子學】Modbus over TCP 實作(上) - 2019/11/28
- 【Maker電子學】Modbus RTU的傳輸資料格式 - 2019/09/18
訂閱MakerPRO知識充電報
與40000位開發者一同掌握科技創新的技術資訊!
Trackbacks/Pingbacks