PFS173-S16 Padauk是一家臺灣超低成本微控制器供應(yīng)商,因“3 美分 MCU”而臭名昭著。
該供應(yīng)商本身僅提供帶有專有 C 語言的封閉工具鏈。與此同時,部分基于逆向工程的開源獨立工具鏈已面世。 仍有一些領(lǐng)域尚未完全理解。其中一個主題是 I/O 寄存器的初始狀態(tài)。實際設(shè)備的行為與數(shù)據(jù)表有些不一致,這可能是由于勘誤表或?qū)S泻烷_放工具鏈的不同行為造成的。
為了詳細(xì)研究 Padauk PFS173-S16 上的這種行為,我們使用一個小程序在啟動后直接將整個 I/O 空間復(fù)制到 RAM。由于無法對 I/O 寄存器進(jìn)行索引訪問,因此必須生成單獨的指令來復(fù)制每個地址。 在對 MCU 外圍設(shè)備進(jìn)行正確初始化后,通過串行端口轉(zhuǎn)儲 I/O 區(qū)域備份。
上圖顯示了重置后整個 I/O 區(qū)域的轉(zhuǎn)儲。有 128 個可能的寄存器,但只有一些被使用和記錄 - 只有少數(shù)寄存器實際上顯示非零值。
一個有趣的方面是一些值是重復(fù)的,例如地址 00 和 01 中的 0xF0。這尤其引人注目,因為 0x01 處的寄存器實際上未使用。更多的實驗表明,最后訪問的寄存器的內(nèi)容實際上是重復(fù)的。
這種行為看起來非常像浮動內(nèi)部總線 - 如果訪問的寄存器不存在,則不會將新信息寫入總線;由于寄生電容,上次訪問的邏輯電平被存儲。如果這是一個安全關(guān)鍵設(shè)備,這當(dāng)然會是一個很好的側(cè)通道。但我們?nèi)匀豢梢岳眠@種效果來識別哪些 I/O 地址實際被使用,哪些沒有被使用。
為了探測未使用的寄存器,我只需在 I/O 讀取之前直接將 0x55 寫入已知寄存器。如果下一次讀訪問是針對未使用的 I/O 位置,它將被讀為 0x55 并且可以輕松識別。如上圖所示,許多 I/O 地址現(xiàn)在讀取為 0x55,因此未使用或只寫。
大多數(shù)使用的寄存器可以輕松地與文檔進(jìn)行交叉檢查。但是,有幾個寄存器無法分配。第一個用紅色標(biāo)記為 0x23,還有一組用綠色標(biāo)記為 0x2d、0x2e、02f。進(jìn)一步探究發(fā)現(xiàn),0x2d 顯然是一個控制寄存器。復(fù)位狀態(tài)為 0xE0。位 7-5、3、1、2 為 R/W,位 4 和 2 為 RO 或 WO。0x2e 和 0x2f 似乎是只讀的。
JS 在 EEVBlog-Forum 上的出色偵查為綠色寄存器提供了非常有趣的解釋:似乎早期的 padauk 微控制器包含一個稱為電阻頻率轉(zhuǎn)換器 (RFC) 的外設(shè),在經(jīng)銷商的舊數(shù)據(jù)表版本中仍可找到。這些寄存器的位配置與調(diào)查結(jié)果完全一致,因此很有可能匹配。目前尚不清楚為什么這個外設(shè)沒有記錄。
它仍然在 Padauk 的目錄中提到,但沒有列出具有此功能集的單個設(shè)備。未記錄的寄存器 0x??23(紅色)的用途很容易識別:它實際上包含 ADC 的額外 LSB。似乎 Padauk 有一個用于 11 位 ADC 的標(biāo)準(zhǔn) IP 塊,該 IP 塊也用于 PFS173。由于某種原因,它被聲明為 8 位 ADC,而低三位未記錄。可能存在噪音問題?
調(diào)查 RFC
JS之前找到的文檔提供了基本的功能說明,并列出了寄存器,但細(xì)節(jié)有些少。沒有什么是不能研究的……
上圖顯示了我對 RFC 的“C 型”操作的理解。它基本上由一個施密特觸發(fā)器和一個接地開關(guān)組成。如果在 IO 引腳和正電源之間連接一個 RC 耦合器(如圖所示),則輸入電壓將根據(jù) RC 時間常數(shù)緩慢增加。如果達(dá)到某個觸發(fā)電壓,接地開關(guān)將使輸入短路至地,直到達(dá)到較低的觸發(fā)電壓。每次發(fā)生這種情況時,計數(shù)器都會增加一。實際上,該電路形成了一個張弛振蕩器。
通過評估固定間隔內(nèi)的計數(shù)次數(shù),可以測量電容或電阻的變化。
上表顯示了寄存器映射。控制寄存器允許選擇特定引腳。需要寫入位 4 才能啟動和停止計數(shù)器。
__sfr __at( 0x2d ) _rfcc;
__sfr __at( 0x2e ) _rfccrh;
__sfr __at( 0x2f ) _rfccrl;
#定義RFCC _rfcc
#定義RFCCRH _rfccrh
#定義RFCCRL _rfccrl
寄存器映射如上所示。使用 RFC 相當(dāng)簡單,如下所示:
RFCC = 0xc0 | 0x08 | 0x02 ; // 選擇 PB6,設(shè)置為 C 模式,啟用輸出
uint16_t結(jié)果;
RFCC | = 1 << 4;// 啟動 RFC
_delay_ms( 50 );
RFCC&=~( 1 << 4 );// 停止 RFC
結(jié)果=(RFCCRH<< 8 )|RFCCRL;
示波器圖片顯示了操作期間 RFC 引腳上的電壓。在這種情況下,100nF 電容和 10 kOhm 電阻并聯(lián)連接到 VDD。
可以清楚地看到,RC 元件的充電遵循指數(shù)規(guī)律。上觸發(fā)電壓為 4V,下觸發(fā)電壓約為 700 mV。我不清楚較低電壓下振鈴的來源,它似乎是 RFC 外圍設(shè)備的產(chǎn)物。
接地開關(guān)的阻抗似乎相對較高。在這種情況下,使用 100nF 電容,大約需要 11 µs 才能放電。
當(dāng)使用較低的電容值時,計數(shù)頻率會相應(yīng)增加。最小放電時間似乎是 1 個 IHRC 周期(此設(shè)備中的 IHRC 為 16 MHz = 62.5 ns)。在這種情況下,觀察到電壓下沖至 0V。很明顯,當(dāng)復(fù)位電壓未正確定義時,RC 振蕩器的運行將不穩(wěn)定。似乎建議調(diào)整電容值,以便復(fù)位時間低于一個 IHRC 周期(復(fù)位電壓為 0V),或明顯高于(復(fù)位電壓為 700 mV)。
另一個值得關(guān)注的參數(shù)是振蕩器頻率如何隨電源電壓的變化而變化。
我測量了 R=10 kOhm 和 C=100nF 的振蕩器在不同 VDD 值下的頻率。
可以看出,頻率有一致的變化。這是因為觸發(fā)電壓根據(jù)電源電壓而變化。較低的觸發(fā)電壓似乎由 0.2 * VDD 定義,而較高的觸發(fā)電壓則定義為約 0.8 * VDD。電壓很可能直接來自帶有電阻分壓器的電源。
真正的對稱松弛振蕩器不會顯示這種電壓依賴性,但由于放電由接地開關(guān)定義,因此引入了對開關(guān)電壓的依賴性。不過,1.5 V 電源差中約 10% 的變化對于許多應(yīng)用來說應(yīng)該足夠了。
太棒了,看起來 RFC 確實像宣傳的那樣好用。我們可以用它做什么?