首先,這個小 MCU 沒有做很多事情。它沒有大量的代碼空間(1K 字),沒有大量的 RAM(64 字節),甚至不進行硬件乘法。 它也沒有從 ROM 加載數據的指令(盡管有一些方法可以解決這個問題 - 但這是另一篇文章的主題)。當然,您只能對其進行一次編程
PMS150C U06 不適合 SOIC8 突破
Padauk IDE“代碼生成器”
那么..它能做什么?閃爍燈?嗯,是的……還有更多。
盡管它有其局限性,但實際上只需使用 8Mhz 微控制器進行 bitbanging 就可以做很多事情。正如您在下面 IDE 的屏幕截圖中看到的,它實際上旨在與一堆外圍設備一起工作 - 盡管其中任何一個都沒有硬件支持。
Padauk IDE“代碼生成器”
當然,EEVBlog 論壇上有一些非常聰明的人正在努力為這些芯片創建開放工具鏈,但我決定迫不及待地開始使用制造商 IDE、ICE 和程序員。
為了充分利用手頭的工具,IDE 似乎希望您混合使用純 C、宏和匯編指令,所有這些都混合在一些看起來非常有趣的代碼中。我可能不會因為這樣說而受到歡迎,但當你習慣它時,它實際上感覺非常直觀。這很奇怪,但卻很“有趣”。
在我最初的強制性“閃爍測試”之后,我決定嘗試一些稍微有用的東西 - 控制 WS2812B LED。由于協議本身依賴于時間非常緊迫的位敲擊,我認為這是一個很好的測試。
在我們繼續之前,這里有劇透!成功:
但如何呢? Adafruit 的 Arduino 庫為每個 LED 使用 3 字節 RAM,那么如何僅用 64 字節 RAM 運行 300 個 LED?
事實證明,這個問題有一個簡單的解決方案:不要將每個 LED 都放入 RAM 中。
由于 WS2812B 的時序不是那么嚴格,因此在為每個 LED 發送 24 位值之間實際上有很多空閑周期的空間。基本上只是動態執行邏輯,而不是將每個 LED 存儲在 RAM 中。唯一的缺點是您不能只更改單個 LED 值而保留其余部分。
一旦您了解了 LED 的控制邏輯,就會發現它非常簡單。為每個 LED 發送 24 位,并以足夠長的延遲結束以使數據鎖存。在這種情況下,將每個位保持在 1.25uS 左右,“0”是短高,然后是“長”低,“1”是長高,然后是短低。簡單來說:高->低 24 次。長高表示 1,短高表示 0。
以下是數據表中的片段:
對于我來說,+/- 150ns 有足夠的余量,PMS150C 運行在 8mhz 下。每個位的+/- 600ns 的情況也是如此。我預計我可以輕松運行 3000 個 LED,而不是 300 個 – 但我沒有電源來承受周圍那么多的熱量
Tim“cpldcpu”早在 2014 年就寫了一篇詳細的文章,但要么事情發生了變化,要么他弄錯了細節,因為在我的測試中,RES 信號需要至少 50uS,當遇到故障時,復位信號越長,更好的。我有一種感覺,如果我沒有看到Big Josh 的關于協議實際上有多么簡單的帖子,
我永遠不會完成這個項目,但遺憾的是他的代碼需要一些認真的操作才能移植到 Padauk IDE,所以我最終完全重寫了它從頭開始,手里拿著 WorldSemi 數據表,對 BigJosh 做了什么有模糊的記憶。非常感謝 Tim 和 BigJosh 的啟發!
Padauk PMS150C 成功驅動 300 個 WS2812B LED
那么..代碼呢?
下面是我用來與 LED 串對話的最小代碼。還有優化的空間,如果您習慣在 AVR 上看到純 C 項目,我確信其中很多看起來很有趣。首先,Padauk IDE 在數據類型方面有點模糊。不存在“long”這樣的東西,在我看來,默認情況下所有類型都是無符號的——盡管我還沒有徹底研究過這一點。
Padauk IDE 中唯一可用的數據類型是:
位(1 位)
字節(8 位)
整數(8 位(!))
字(16 位)
EWORD(24 位)
雙字(32 位)
不過,關于類型的方便之處在于,可以通過宏訪問各個位和字節,而無需對它們進行移位進行任何模糊處理。
例如:
mybyte.4 = 0; //清除mybyte的位4
myEWORD$1 = mybyte; //設置24位EWORD的中間字節
此外,內置宏也非常方便。請參閱下面的代碼。控制 WS2812B 所需的所有代碼都包含在宏“send1”、“send0”和函數 SendRGB() 中;
SendRGB() 函數是 Padauk IDE 怪異的一個典型例子,包含匯編指令、宏和普通的舊 C。但我能說什么呢:它有效。我可能可以在 while 循環中移動 rgb EWORD x(比 24 個宏 if 更有效),但我決定嘗試一下該宏,它對于此目的來說已經足夠高效了。其余的代碼(我沒有在這里包含)是 r、g 和 b 值的基本操作,后跟 show();設置正確的顏色。如果你想看請發表評論,我會把完整的項目放在github上。
根據大眾的需求,完整的源代碼可以在這里找到:
https://github.com/AndersBNielsen/pms150c-projects
byte red, green, blue; //Could save these three RAM bytes by using the rgb EWORD directly ( rgb$0, rgb$1, rgb$2)
EWORD rgb;
word pixels; //Only has to be a word if number of pixels > 255
define definedPIXELS 300;send1 MACRO
SET1 LED;
.DELAY 5; //Around 0.85uS
$ LED low; //Same as SET0 LED;
// .DELAY 1; //Going around is enough delay 1.25uS in total
ENDM
send0 MACRO
SET1 LED;
.DELAY 2; //Around 0.40uS
$ LED low;
.DELAY 2; //With the loop around 0.85uS
ENDM
void SendRGB (void) {
DISGINT; //Let’s not get interrupted
.FOR bitno, <23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0> //Regular for() loop doesn't work, but at least the compiler can do the hard work
if (rgb.bitno == 0) {
send0;
} else {
send1;
}
.ENDM
ENGINT;
}
void show (void) {
rgb$0 = blue; //I lost track of MSB, LSB and endians.. This is what works.
rgb$1 = red;
rgb$2 = green;
SendRGB();
}
void clearLED (void) {
rgb = 0;
pixels = definedPIXELS;
do {
SendRGB();
} while (–pixels);
.delay 2000; //If you want to make sure the LED-reset is caught, use a longer one.
}
字節紅、綠、藍; //可以直接使用rgb EWORD保存這三個RAM字節(rgb$0, rgb$1, rgb$2)
EWORD rgb;
文字像素; //僅當像素數> 255時才必須是一個單詞
定義defineedPIXELS 300;
發送 1 宏
設置 1 LED;
.延遲5; //大約 0.85uS
$ LED 低電平; //與SET0 LED相同;
// .延遲1; //繞一圈就足夠
ENDM總共延遲1.25uS
發送 0 宏
設置 1 LED;
.延遲2; //大約 0.40uS
$ LED 低電平;
.延遲2; //循環大約0.85uS
ENDM
無效SendRGB (無效) {
DISGINT; //我們不要被打擾
.FOR bitno, <23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0> //Regular for() loop doesn't work, but at least the compiler can do the hard work
if (rgb.bitno == 0) {
send0;
} else {
send1;
}
.ENDM
ENGINT;
}
void show (void) {
rgb$0 = 藍色; //我失去了 MSB、LSB 和字節序的蹤跡。這就是有效的。
rgb$1 = 紅色;
rgb$2 = 綠色;
發送RGB();
}
無效clearLED (void) {
rgb = 0;
像素=定義的PIXELS;
執行 {
SendRGB();
while (-像素);
.延遲2000; //如果你想確保 LED 復位被捕獲,請使用更長的。
}
那么.. 為什么我會選擇這個而不是大品牌的MCU?
顯然,該微控制器的主要賣點是價格。每個 3 美分,比 Pic 同類產品(3000 MOQ)便宜十倍 - pic10f200(34 美分)或 ATtiny10(28 美分 @ 4500 MOQ)。 //Digikey
另外,客戶服務也很不錯——我在 12 小時內就收到了 Padauk 的電子郵件回復。
PMS150c 的缺點是 OTP 性質、有限的指令集以及有時令人好奇且看似隨機的 IDE 文檔 - 僅部分翻譯成英文。 (雖然從 0.84 到 0.86,每個版本都會變得更好)
如果您正在考慮制作一個帶有 ATTiny10 的玩具,并且它不需要做大量繁重的數學運算 – 這可能能夠為成本的十分之一。這并不意味著我會很高興在起搏器中看到它。
它還能做什么?
我的猜測是:比你想象的要多。我有一種感覺,我的下一個項目可能涉及控制nrf24L01+SI24R01 2.4Ghz 無線電模塊或經濟型 Raspberry Pi 模塊。
不管怎樣,請告訴我你的想法,指出我的錯誤,并在評論中讓我知道你希望我將來如何處理這件事