STC12C2052(2) <8Queen問題>
aitendoで買ったSTCmicroのSTC12C2052でプログラミングできるようになったので、8Queen問題を解くプログラムを走らせてみた。
以前作った8031SBC用に書いたソースを変更した。 (8Queen2011/09/15)
8031(8051のROM無し)は内臓RAMが128byteしかないので、スタックを消費する再帰プログラムは厳しい。
↓オプション --idata_loc 0x0000 --idata_size 128(8031用)でコンパイルするとスタックは98byteとれた。
-- 8031; ---
Internal RAM layout:
0 1 2 3 4 5 6 7 8 9 A B C D E F
0x00:|0|0|0|0|0|0|0|0|a|b|b|c|d|e|e| |
0x10:| | | | | | | | | | | | | | | | |
0x20:|T|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0x30:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0x40:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0x50:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0x60:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0x70:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0x80:| | | | | | | | | | | | | | | | |
0x90:| | | | | | | | | | | | | | | | |
0xa0:| | | | | | | | | | | | | | | | |
0xb0:| | | | | | | | | | | | | | | | |
0xc0:| | | | | | | | | | | | | | | | |
0xd0:| | | | | | | | | | | | | | | | |
0xe0:| | | | | | | | | | | | | | | | |
0xf0:| | | | | | | | | | | | | | | | |
0-3:Reg Banks, T:Bit regs, a-z:Data, B:Bits, Q:Overlay, I:iData, S:Stack, A:Absolute
STC12C2052は256byteの内臓RAMが載っているので、オプション --idata_size 240でコンパイルするとスタックは192byte確保できている。(なぜ--idata_size 256ではないかは後で)
-- STC12C2052 ---
Internal RAM layout:
0 1 2 3 4 5 6 7 8 9 A B C D E F
0x00:|0|0|0|0|0|0|0|0|a|a|a|a|a|a|a|a|
0x10:|a|b|b|b|b|b|b|b|b|b|b|b|b|b|b|b|
0x20:|b|b|b|b|b|b|b|b|b|c|d|d|e|Q|Q|Q|
0x30:|Q|Q|Q|Q|Q|S|S|S|S|S|S|S|S|S|S|S|
0x40:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0x50:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0x60:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0x70:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0x80:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0x90:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0xa0:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0xb0:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0xc0:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0xd0:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0xe0:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0xf0:| | | | | | | | | | | | | | | | |
0-3:Reg Banks, T:Bit regs, a-z:Data, B:Bits, Q:Overlay, I:iData, S:Stack, A:Absolute
プログラム用のメモリが2kbyteしかないので、printf()は使えない。
↓実行結果
ところで、内蔵のR/C発振器でUARTを使おうとしたら、一発では動かない。ソースはそのままで動くと思っていた。
通信速度の設定はTH1、TL1に設定する値で決まる。
TH1 = TL1 = 256 - (クロック周波数 / 12 / 32 / 通信速度)
SDCCのライブラリに autobaud()という関数がある。この関数を呼んでRxDにCR(0Dh)を送ると1byte(8bit)分の時間を測ってTH1、TL1レジスタを自動的に設定してくれるという便利な関数だ。
この関数を使ってみると、4,800bpsでは文字化けが多い、4,800bpsで動いていも次の日には文字化けが多くて使い物にならなくなる。確実に動かすには1,200bpsまで下げなければならない。
TH1、TL1レジスタにセットされている値を表示させてみると大きい。 (TH1,TL1=FDh @4,800bps)
この値が大きいとズレが大きくなる。または正確なクロック周波数の発振器が必要だ。
データーシートではクロック周波数は18.234MHzと書いてあることが多いので、R/C発振器の周波数も18.234MHzかと思っていた。 よく読むとそんなことは書いてない。
データーシートに「R/C発振器の周波数を知る方法」が載っている。
電源ON直後、内蔵RAMのF8h~FBh、FCh~FFhを読むことで分かるのだそうだ。F8h~FBhに直前の設定値、FCh~FFhに工場出荷時の設定値が書かれている。この領域はRAMとして普通に使えるので当然データを書いたり読んだりできる。
確認してみようと、この領域を読みだすと全て 00hだ。 (?_?
SDCCはstart_up時にIDATA領域をクリアする。 (SDCC/lib/src/mcs51/crtclean.asm) つまり、IDATA領域の末尾の部分(F8h~FFh)も00hでクリアされているようだ。
SDCCは --idata_loc と --idata_size オプションでIDATAのサイズと位置を指定できる。そこで、内蔵RAM(IDATA)は256byteあるけど --idata_size 240 とすると、F8h~FFhがクリアされなくなる。
工場出荷時の設定値は 5,619776MHz、電源投入時の設定値は5,669,485MHzのようだ。
よく見たら、stcgal.pyのメッセージで表示される値だ。
- CPUボード
- 8031/8052 SBC (2017/10/08)
- STC12C2052(2) (2017/10/08)
- STC12C2052(2017/09/25)
- 8Queen(2011/09/15)
【最近の投稿】【最近のCPUボード】【8031/8052 SBC】【2016の投稿】【2015の投稿】
« Excel方眼紙 <一太郎の様式と大して変わらない> | トップページ | 年功制 <時代に適していない> »
「8031/8052 SBC」カテゴリの記事
- 久々の物欲(2022.05.21)
- STC12C2052(2) <8Queen問題>(2017.10.08)
- 8052BASIC(6)(2012.11.11)
- 8052BASIC(4)(2012.10.18)
- 8052BASIC(5)(2012.11.03)
「CPUボード」カテゴリの記事
- 久々の物欲(2022.05.21)
- stcgal <質問に答える>(2021.02.21)
- micro:bitで跳び上がると表示する名札 <ウケ狙い>(2020.11.18)
- micro:bit <BLEが乗った低価格マイコンボード>(2020.09.15)
- Google日本語モールス入力(2020.05.01)
「プログラミング」カテゴリの記事
- GMC-4で動く3連ナイトライダー(2022.12.30)
- プログラミング言語ランキング(2022.11.19)
- AWSでサービス構築(2022.05.29)
- Excelの配列式(2022.01.06)
- ローコード・プログラミング(2021.11.07)
コメント