2017-12-17
光るカセットテープで活躍するWS2812Bを、LPC810を使って自在に点灯できたら簡単、気軽にカセットテープ内にボタン電池も含めて収められてうれしいかも? (IchigoJamを書き込んだLPC1114を使って光るカセットテープを作った例 by JO3GBDさん)


LPC810から制御したWS2812B。
拡大してみると、信号が来るDI側から順に、緑、赤、青と小さく光っている様子が分かります。
データを送信する順も緑、赤、青!

プログラムはこの通り、マシン語部分が長くなってきたら、100行以降を別プログラムとして保存しましょう。

10 POKE#700,0,4,0,16,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,223,251,255,239,24,72,223,33,1,96,24,72 20 POKE#728,1,104,3,34,210,67,17,64,1,96,22,72,22,73,1,96,22,72,12,33,1,96,22,76,4,34,3,32,22,161,128,37,11,120,34,96,43,66,8,208 30 POKE#750,0,0,0,0,0,0,0,0,0,0,0,0,0,0,34,96,7,224,0,0,34,96,0,0,0,0,0,0,0,0,0,0,0,0,109,8,233,209,1,49 40 POKE#778,1,56,228,209,7,79,1,63,253,209,222,231,128,128,4,64,16,0,4,64,192,193,0,64,191,255,255,255,0,32,0,160,0,35,0,160,64,66,15,0 50 POKE#7A0,2,2,2,0 60 A=#700:L=164:LRUN1 'FILE1 100 'LPC810 Writer 256byte from ADR:A 110 UART3,2:OUT2,0:OUT1,0:WAIT9:OUT1,1 120 CLS:?"?";:GSB@R 130 ?"Synchronized":GSB@R 140 ?12000:?:GSB@R:GSB@R 150 ?"A 0":GSB@R:GSB@R 160 ?"U 23130":GSB@R 170 ?"W 268436096 ";256:GSB@R:UART1,2:LC0,-1:FORI=0TO255:?CHR$(PEEK(A+I));:NEXT:UART3,2:LC0,6 180 ?"P 0 0":GSB@R 190 ?"E 0 0":GSB@R 200 ?"P 0 0":GSB@R 210 ?"C 0 268436096 256":GSB@R 215 '?"G 268436128 T":GSB@R:END 220 OUT2,1:OUT1,0:OUT1,1:END 500 @R:K=INKEY():IF K=13 K=INKEY():WAIT9:RTN ELSE CONT

ちょうど50行、#7A0からの3byteがG(緑)、R(赤)、B(青)の数を指定しています。
書き換えて、実験してみましょう。


LPC810と光ったWS2812B!

マシン語プログラムの解説

asm15でWS2812Bの制御用マシン語プログラムは、LPC1114用を元に、LPC810用に修正します。
Cortex-M0+のLPC810では、OUTポートの扱いがNOTを使えるので短く、1クロックで読み書きできるので高速!
ただ、標準動作の12MHz用に、ウェイトはループではなく、NOPコマンドで調整しました。
厳密にはデータの区切りで速度が追いついていないので、たくさん光らせようとするとおかしくなってしまうため、周波数を上げるかSPIでの制御にしないといけなさそうです。(追記、勘違いでした12MHzでもいけました!

DATA L #10000400 ' stack DATA L #21 ' entry point DATA L 0, 0, 0, 0, 0 DATA L #EFFFFBDF ' VALID_CODE = 0x100000000-0x10000400-0x21 @ENTRY R0=[@SYSAHBCLKCTRL]L R1=#DF 'SWM, GPIO, I2C:off, FLASH, FLASHREG, RAM, ROM, SYS [R0]L=R1 R0=[@FLASHCFG]L R1=[R0]L R2=3 ' flash no wait: set 0b00 R2=~R2 R1&=R2 [R0]L=R1 R0=[@PINENABLE0]L R1=[@PINENABLE0_DATA]L [R0]L=R1 R0=[@GPIO_DIR0]L R1=`1100 ' PIO0_2 and PIO0_3 [R0]L=R1 R4=[@GPIO_NOT0]L R2=`100 ' PIO0_2 ' WS2812B driver ' R0 - data count ' R1 - data address (G1,R1,B1,G2,R2,B2 ....) ' R2 - OUT value ' R3 - data value ' R4 - GPIO address ' R5 - bit count ' R7 - wait count @WS2812B R0=3 R1=@DATA_LED @LOOP_DATA R5=#80 R3=[R1] @LOOP_BIT [R4]L=R2 R3&R5 IF 0 GOTO @ZERO NOP NOP NOP NOP NOP NOP NOP [R4]L=R2 GOTO @JOIN @ZERO NOP [R4]L=R2 NOP NOP NOP NOP NOP NOP @JOIN R5=R5>>1 IF !0 GOTO @LOOP_BIT R1+=1 '+6clock R0-=1 IF !0 GOTO @LOOP_DATA @WAIT R7=[@WAIT_N]L R7-=1 'wait R7*3+1 clock IF !0 GOTO -1 GOTO @WS2812B ' init @SYSAHBCLKCTRL DATA L #40048080 @FLASHCFG DATA L #40040010 @PINENABLE0 DATA L #4000C1C0 @PINENABLE0_DATA DATA L #FFFFFFBF @GPIO_DIR0 DATA L #A0002000 @GPIO_NOT0 DATA L #A0002300 ' WS2812B @WAIT_N DATA L 1000000 @DATA_LED DATA B 2, 2, 2

開始アドレスを0に変えて、hexファイルに変換したものがこちら。
こちらをLPC810に直接書き込んでも動きます!

:1000000000040010210000000000000000000000BB :10001000000000000000000000000000DFFBFFEF18 :100020001848DF210160184801680322D2431140BB :10003000016016481649016016480C210160164CF3 :100040000422032016A180250B7822602B4208D0C1 :10005000000000000000000000000000000022601E :1000600007E0000022600000000000000000000027 :1000700000006D08E9D101310138E4D1074F013F9B :10008000FDD1DEE78080044010000440C0C1004084 :10009000BFFFFFFF002000A0002300A040420F0090 :0400A0000202020056 :00000001FF

links
- IchigoJamでLPC810マイコン開発!(デプロイ・完結編)
- IchigoJamでも光る大五郎! 300コのフルカラーLEDを簡単コントロール! IchigoJam x WS2812B/SK6812/NeoPixel
- はじめてのマシン語 - IchigoJamではじめるArmマシン語その1

Tweet
クリエイティブ・コモンズ・ライセンス
本ブログの記事や写真は「Creative Commons — CC BY 4.0」の下に提供します。記事内で紹介するプログラムや作品は、それぞれに記載されたライセンスを参照ください。
CC BY / @taisukef / アイコン画像 / プロフィール画像 / 「一日一創」画像 / RSS