組込み開発再入門(4) – Lチカ再び

リンカスクリプトが(とりあえず)書けたのでアセンブリでもうちょっと遊んでみる。とりあえずスイッチを押している間 LED を点灯するプログラムを書いてみた。

ところで、諸説あるけど個人的には

  • アセンブリ…アセンブリ言語
  • アセンブラ…処理系
  • アセンブル…機械語への翻訳

だと思ってます。が、アセンブラ=アセンブリ言語とする文脈も多いのでその辺はコンテキストで理解するしかなさそう。

/********************************************************************************/
/* led.s - スイッチ入力/LED出力プログラム
/********************************************************************************/
 
        .h8300h                 ;CPUを指定
 
        /* ラベル定義 */
        .equ    P4DDR,  0xFFFC5
        .equ    P4DR,   0xFFFC7
        .equ    P4PCR,  0xFFFDA
        .equ    P5DDR,  0xFFFC8
        .equ    P5DR,   0xFFFCA
 
        .section    .text
 
        .global     _start
        .type       _start,@function
 
_start:
        /* スタックポインタの設定 */
        mov.l   #0xFFF10, sp        ;使わないけど
 
        /* P4 を入力に設定 */
        mov.b   #0x00, r0l
        mov.b   r0l, @P4DDR
 
        /* P4 の内部プルアップを有効化 */
        mov.b   #0xFF, r0l
        mov.b   r0l, @P4PCR
 
        /* P5 を出力に設定 */
        mov.b   #0xF3, r0l
        mov.b   r0l, @P5DDR
 
SW1LED:
        /* SW1 の状態チェック */
        mov.b   @P4DR,  r0l
        btst.b  #0x04,  r0l
        beq     LED1ON
 
        /* LED1 を消灯 */
        bclr.b  #0x00,  @P5DR:8
        jmp     @SW2LED
 
LED1ON:
        /* LED1 を点灯 */
        bset.b  #0x00,  @P5DR:8
 
SW2LED:
        /* SW2 の状態チェック */
        mov.b   @P4DR,  r0l
        btst.b  #0x05,  r0l
        beq     LED2ON
 
        /* LED2 を消灯 */
        bclr.b  #0x01,  @P5DR:8
        jmp     @SW1LED
 
LED2ON:
        /* LED2 を点灯 */
        bset.b  #0x01,  @P5DR:8
        jmp     @SW1LED
 
        .end
スポンサーリンク

ラベル定義

.equ ラベル名, アドレス

でラベルの定義ができます。H8マイコン謹製アセンブラでは

ラベル名 .equ アドレス

とか書く。まぁアセンブリ言語なんて基本命令さえ知っていればあとは雰囲気で読めるようになるので細かい違いとか割とどうでもいいです。はい。AT&T 記法と Intel 記法で操作元と操作先の記述が逆になったりしてややこしいので、どっちが操作元でどっちが操作先かは意識しておくと良いかも。ちなみに objdump とかでディスアセンブルすると AT&T 記法で吐くのでこっちに慣れておくと便利。

  • P4DR : ポート4のデータ・レジスタ
  • P4DDR: ポート4のデータ・ディレクション・レジスタ
  • P4PCR: ポート4の入力プルアップ MOS コントロール・レジスタ
  • P5DR : ポート5のデータ・レジスタ
  • P5DDR: ポート5のデータ・ディレクション・レジスタ

スタックポインタの設定

別にスタックポインタは使ってないので初期化する必要なんてないんですが、一応初期化しておくのがマナーらしいのでスタックポインタ:sp (ER7 レジスタ) に RAM 領域の底番地 (0x0FFF10) を書き込んでおく。

ポートの設定

ポートを設定するレジスタの使い方はハードウェアマニュアルを読むこと。P4 にはスイッチが接続されているので入力に、P5 には LED が接続されているので出力に、それぞれ設定。P4 は内部プルアップを有効に。

Lチカ

SW1LED: から先はスイッチを押している間だけ対応する LED が光る処理。直接I/Oポートの状態を確認する命令が無いので一旦 r0l レジスタに読み込んでから btst 命令でそれが 1 か 0 かを判断させてます。スイッチが押されていれば LED を点灯させる処理に飛び、押されていなければビットクリアします。この処理を 2 つのスイッチに対して行います。

とりあえずここまで。もう C でいいじゃんって気になってきているけど、今後もマイコンの一通りの機能はアセンブリでいじってみるつもり。

ちなみにアセンブリ書いたのは学生の頃以来でした。

スポンサーリンク

フォローする