●ワンチップマイコンのSAMPLEプログラムを修正してみよう

 @はじめに・・・

  アセンブラの知識がない初心者が、アセンブラのプログラミングをするのは難しいので、
  簡単なプログラム修正をして、オブジェクト・ファイル(HEX)を作成する手順の練習
  です。

    → まずは、イメージを・・・

  尚、このSAMPLEプログラム(SAMPLE.ASM)を、マイクロチップテクノロ
  ジー社純正のアセンブラ(MPASM)で実行した結果、アセンプラ・エラーが検出され
  ました。どうやら、このプログラムは、秋月電子通商製作アセンブラ(PA)である。
  PAは、便利な拡張命令を追加しているものであり、他でアセンブルできない模様です。

  1.SAMPLEプログラム(SAMPLE.ASM)を、エディター(メモ帳)で修正
    したものを、SAMPLE【変更版】プログラム(SAMPLEK1.ASM)とし
    て作成する。
    *コメントは、誤りがあると思われますが、解かる範囲で、追記しています。

    ■変更内容

     LEDの点灯順序を、LED(12→01→12)をLED(01→12→01)へ変更する。
               ___________________ ____________________
              |                   V                    |
              |                                        |
   LED(02) <--+ 1 RA2 PORTA(BIT2) | PORTA(BIT1) RA1 18 +--> LED(03)
   LED(01) <--+ 2 RA3 PORTA(BIT3) | PORTA(BIT0) RA0 17 +--> LED(04)
   ミシヨウ     --+ 3 RA4 PORTA(BIT4) |            OSC1 16 +--< オシレータ端子/外部クロック入力
           >--+ 4 MCLR            |            OSC2 15 +--> オシレータ端子/クロック出力
   0V       --+ 5 Vss (-)         |         (+) Vdd 14 +--  3〜5V+
   LED(12) <--+ 6 RB0 PORTB(BIT0) | PORTB(BIT7) RB7 13 +--> LED(05)
   LED(11) <--+ 7 RB1 PORTB(BIT1) | PORTB(BIT6) RB6 12 +--> LED(06)
   LED(10) <--+ 8 RB2 PORTB(BIT2) | PORTB(BIT5) RB5 11 +--> LED(07)
   LED(09) <--+ 9 RB3 PORTB(BIT3) | PORTB(BIT4) RB4 10 +--> LED(08)
              |                                        |
              +----------------------------------------+ 

    ■LED点燈パターンの凡例 : RB0(BIT0が1)のみLED点燈する場合

          _PORTA_   ____PORTB______

          B B B B   B B B B B B B B
          I I I I   I I I I I I I I
          T T T T   T T T T T T T T
          3 2 1 0   7 6 5 4 3 2 1 0

          R R R R   R R R R R R R R
          A A A A   B B B B B B B B
          3 2 1 0   7 6 5 4 3 2 1 0

          ↓ ↓ ↓ ↓   ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓

     retw 0 0 0 0 b、0 0 0 0 0 0 0 1 b

          ↑ ↑ ↑ ↑   ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑
          ○ ○ ○ ○   ○ ○ ○ ○ ○ ○ ○ ●

                            (○:消燈 ●:点燈)
    ■プログラム修正部分

           ((((((((変更前))))))))     ((((((((変更後)))))))

      retw 0000b,00000001b → retw 1000b,00000000b
      retw 0000b,00000010b → retw 0100b,00000000b
      retw 0000b,00000100b → retw 0010b,00000000b
      retw 0000b,00001000b → retw 0001b,00000000b
      retw 0000b,00010000b → retw 0000b,10000000b
      retw 0000b,00100000b → retw 0000b,01000000b
      retw 0000b,01000000b → retw 0000b,00100000b
      retw 0000b,10000000b → retw 0000b,00010000b
      retw 0001b,00000000b → retw 0000b,00001000b
      retw 0010b,00000000b → retw 0000b,00000100b
      retw 0100b,00000000b → retw 0000b,00000010b
      retw 1000b,00000000b → retw 0000b,00000001b

      retw 1000b,00000000b → retw 0000b,00000001b
      retw 0100b,00000000b → retw 0000b,00000010b
      retw 0010b,00000000b → retw 0000b,00000100b
      retw 0001b,00000000b → retw 0000b,00001000b
      retw 0000b,10000000b → retw 0000b,00010000b
      retw 0000b,01000000b → retw 0000b,00100000b
      retw 0000b,00100000b → retw 0000b,01000000b
      retw 0000b,00010000b → retw 0000b,10000000b
      retw 0000b,00001000b → retw 0001b,00000000b
      retw 0000b,00000100b → retw 0010b,00000000b
      retw 0000b,00000010b → retw 0100b,00000000b
      retw 0000b,00000001b → retw 1000b,00000000b

  2.DOSコマンドラインで、アセンブラする。・・・PA −L SAMPLEK1

    ■SAMPLEK1.ASM ・・・ プログラムのソース・ファイル
       |■16F84.H ・・・・ PIC16F84のヘッダー・ファイル
       ↓
    【PA.EXE】(秋月電子通商製作アセンブラ)
       |
       ↓
    ■SAMPLEK1.HEX ・・・ プログラムのオブジェクト・ファイル
    ■SAMPLEK1.LST ・・・ プログラムのアセンブルリスト・ファイル


    *エラーが無ければ、以下のメッセージが表示されます。

         PIC Assembler Version 2.02.02 Copyright (c) 1996-1998 by X.XXXXXX
         SAMPLEK1.asm
         ***** pass 1 *****
         ***** pass 2 *****

         ** Error(s) 0 **
         ** Warning(s) 0 **


 ASAMPLE【変更版】プログラムのソース      (SAMPLEK1.ASM)

;------------------------------------------------------------------------------------------
; ●プログラム : SAMPLEK1  ●言語 : PA(秋月電子通商製作アセンブラ)
; ●タイトル  : LED(12個)点灯サンプル プログラム(LED点灯順序の変更版)
;          LED点灯順序の変更 LED(12→01)をLED(01→12)へ変更
;                   ___________________ ____________________
;                  |                   V                    |
;                  |                                        |
;       LED(02) <--+ 1 RA2 PORTA(BIT2) | PORTA(BIT1) RA1 18 +--> LED(03)
;       LED(01) <--+ 2 RA3 PORTA(BIT3) | PORTA(BIT0) RA0 17 +--> LED(04)
;       ミシヨウ     --+ 3 RA4 PORTA(BIT4) |            OSC1 16 +--< オシレータ端子/外部クロック入力
;               >--+ 4 MCLR            |            OSC2 15 +--> オシレータ端子/クロック出力
;       0V       --+ 5 Vss (-)         |         (+) Vdd 14 +--  3〜5V+
;       LED(12) <--+ 6 RB0 PORTB(BIT0) | PORTB(BIT7) RB7 13 +--> LED(05)
;       LED(11) <--+ 7 RB1 PORTB(BIT1) | PORTB(BIT6) RB6 12 +--> LED(06)
;       LED(10) <--+ 8 RB2 PORTB(BIT2) | PORTB(BIT5) RB5 11 +--> LED(07)
;       LED(09) <--+ 9 RB3 PORTB(BIT3) | PORTB(BIT4) RB4 10 +--> LED(08)
;                  |                                        |
;                  +----------------------------------------+ 
; 1ピン(20mA)              PIC16F84-20/P                Copyright (c) 2001 by T.EJIRI
;------------------------------------------------------------------------------------------
		INCLUDE	16F84.H			;プロセッサの仕様の変数宣言
;------------------------------------------------------------------------------------------
;	コンフィギュレーション・レジスタの設定
;------------------------------------------------------------------------------------------
		.OSC            HS              ;オシレータ・タイプ(HS:高速クリスタル)の設定
		.PWRT           ON              ;パワーアップ・タイマ(ON:有効)の設定
		.WDT            OFF             ;ウォッチドッグ・タイマ(OFF:無効)の設定
		.PROTECT        OFF             ;コード・プロテクト(OFF:無効)の設定
;------------------------------------------------------------------------------------------
;	汎用レジスタ エリア 68バイト (SRAM) 変数定義
;------------------------------------------------------------------------------------------
		ORG	0CH                     ;汎用レジスタ開始アドレス(000C番地)

POI		DS	1                       ;          エリア (1バイト)
WK		DS	1                       ;Wレジスタ・ワーク エリア (1バイト)
TM1		DS	1                       ;タイマーカウント1 エリア (1バイト)
TM2		DS	1                       ;タイマーカウント2 エリア (1バイト)
;------------------------------------------------------------------------------------------
;	リセット処理
;------------------------------------------------------------------------------------------
		ORG	0                       ;リセット・ベクタ  アドレス(0000番地)
		GOTO	START                   ;プログラムの開始点(START)へジャンプ
;------------------------------------------------------------------------------------------
;	外部割り込み処理
;------------------------------------------------------------------------------------------
		ORG	4                       ;外部割り込みベクタ アドレス(0004番地)
		GOTO	START                   ;プログラムの開始点(START)へジャンプ
;------------------------------------------------------------------------------------------
;	ゲット パターン ルーチン LEDの点灯パターン
;------------------------------------------------------------------------------------------
GETPATTERN
		JMP	PC+W                    ;Wレジスタに?をセットして、RETURNする
		RETW	1000b,00000000b         ;PC+=W+1 テーブル参照		
		RETW	0100b,00000000b         ;プログラム・カウンタ
		RETW	0010b,00000000b         ;
		RETW	0001b,00000000b         ;
		RETW	0000b,10000000b         ;
		RETW	0000b,01000000b         ;
		RETW	0000b,00100000b         ;
		RETW	0000b,00010000b         ;
		RETW	0000b,00001000b         ;
		RETW	0000b,00000100b         ;
		RETW	0000b,00000010b         ;
		RETW	0000b,00000001b         ;

		RETW	0000b,00000001b         ;
		RETW	0000b,00000010b         ;
		RETW	0000b,00000100b         ;
		RETW	0000b,00001000b         ;
		RETW	0000b,00010000b         ;
		RETW	0000b,00100000b         ;
		RETW	0000b,01000000b         ;
		RETW	0000b,10000000b         ;
		RETW	0001b,00000000b         ;
		RETW	0010b,00000000b         ;
		RETW	0100b,00000000b         ;
		RETW	1000b,00000000b         ;
;------------------------------------------------------------------------------------------
;	開始プログラム
;------------------------------------------------------------------------------------------
START                                              ;プログラムの始まり
		CLR	ra                      ;RA=0		
		CLR	rb                      ;RB=0	
		MOV	!ra,#0                  ;Aポート出力設定
		MOV	!rb,#0                  ;Bポート出力設定

MAIN0
		CLR	POI                     ;POI=0

MAIN
		MOV	WK,POI                  ;WK=POI
		CLC                              ;CF=0
		RL	WK                      ;WKを左へシフト(1ビット)

		MOV	W,WK                    ;W=WK
		CALL	GETPATTERN              ;ゲットパターンルーチン呼び出し
		MOV	ra,W                    ;RA=W
		
		INC	WK                      ;WK++

		MOV	W,WK                    ;W=WK
		CALL	GETPATTERN              ;ゲットパターンルーチン呼び出し
		MOV	rb,W                    ;RB=W
		
		CALL	WAIT                    ;ループ・タイマールーチンの呼び出し
		
		INC	POI                     ;POI++
		CJB	POI,#24,MAIN            ;IF POI <24 の時 mainへジャンプ
		GOTO	MAIN0                   ;main0へジャンプ
;------------------------------------------------------------------------------------------
;	ループ・タイマー ルーチン
;------------------------------------------------------------------------------------------
WAIT
		CLR	TM1                     ;TM1=0
WAIT0
		CLR	TM2                     ;TM2=0
WAIT1
		NOP                              ;1クロック時間を消費する

		DJNZ	TM2,WAIT1               ;TM2=TM2-1 IF TM2 NOT= 0 の時 wait1へジャンプ
		DJNZ	TM1,WAIT0               ;TM1=TM1-1 IF TM1 NOT= 0 の時 wait0へジャンプ

		RET                              ;ループ・タイマー ルーチンの出口
;------------------------------------------------------------------------------------------
                                                  ;プログラムの終了
;------------------------------------------------------------------------------------------

 BSAMPLE【変更版】プログラムのアセンブルリスト (SAMPLEK1.LST)

** PIC Assembler Version 2.02.02 assembled. **

   1                            ;------------------------------------------------------------------------------------------
   2                            ; ●プログラム : SAMPLEK1  ●言語 : PA(秋月電子通商製作アセンブラ)
   3                            ; ●タイトル  : LED(12個)点灯サンプル プログラム(LED点灯順序の変更版)
   4                            ;          LED点灯順序の変更 LED(12→01)をLED(01→12)へ変更
   5                            ;                   ___________________ ____________________
   6                            ;                  |                   V                    |
   7                            ;                  |                                        |
   8                            ;       LED(02) <--+ 1 RA2 PORTA(BIT2) | PORTA(BIT1) RA1 18 +--> LED(03)
   9                            ;       LED(01) <--+ 2 RA3 PORTA(BIT3) | PORTA(BIT0) RA0 17 +--> LED(04)
  10                            ;       ミシヨウ     --+ 3 RA4 PORTA(BIT4) |            OSC1 16 +--< オシレータ端子/外部クロック入力
  11                            ;               >--+ 4 MCLR            |            OSC2 15 +--> オシレータ端子/クロック出力
  12                            ;       0V       --+ 5 Vss (-)         |         (+) Vdd 14 +--  3〜5V+
  13                            ;       LED(12) <--+ 6 RB0 PORTB(BIT0) | PORTB(BIT7) RB7 13 +--> LED(05)
  14                            ;       LED(11) <--+ 7 RB1 PORTB(BIT1) | PORTB(BIT6) RB6 12 +--> LED(06)
  15                            ;       LED(10) <--+ 8 RB2 PORTB(BIT2) | PORTB(BIT5) RB5 11 +--> LED(07)
  16                            ;       LED(09) <--+ 9 RB3 PORTB(BIT3) | PORTB(BIT4) RB4 10 +--> LED(08)
  17                            ;                  |                                        |
  18                            ;                  +----------------------------------------+ 
  19                            ; 1ピン(20mA)              PIC16F84-20/P                Copyright (c) 2001 by T.EJIRI
  20                            ;------------------------------------------------------------------------------------------
  21 +16F84.H                   		INCLUDE	16F84.H                   ;プロセッサの仕様の変数宣言
  21 +16F84.H                   		.list
  22                            ;------------------------------------------------------------------------------------------
  23                            ;	コンフィギュレーション・レジスタの設定
  24                            ;------------------------------------------------------------------------------------------
  25 =OSC:HS                    		.OSC            HS		;オシレータ・タイプ(HS:高速クリスタル)の設定
  26 =PWRT:ON                   		.PWRT           ON		;パワーアップ・タイマ(ON:有効)の設定
  27 =WDT:OFF                   		.WDT            OFF		;ウォッチドッグ・タイマ(OFF:無効)の設定
  28 =PROTECT:OFF               		.PROTECT        OFF		;コード・プロテクト(OFF:無効)の設定
  29                            ;------------------------------------------------------------------------------------------
  30                            ;	汎用レジスタ エリア 68バイト (SRAM) 変数定義
  31                            ;------------------------------------------------------------------------------------------
  32  000C                      		ORG	0CH                     ;汎用レジスタ開始アドレス(000C番地)
  33                            
  34  000C                      POI		DS	1                       ;          エリア (1バイト)
  35  000D                      WK		DS	1                       ;Wレジスタ・ワーク エリア (1バイト)
  36  000E                      TM1		DS	1                       ;タイマーカウント1 エリア (1バイト)
  37  000F                      TM2		DS	1                       ;タイマーカウント2 エリア (1バイト)
  38                            ;------------------------------------------------------------------------------------------
  39                            ;	リセット処理
  40                            ;------------------------------------------------------------------------------------------
  41  0000                      		ORG	0                       ;リセット・ベクタ  アドレス(0000番地)
  42  0000 2836                 		GOTO	START                   ;プログラムの開始点(START)へジャンプ
  43                            ;------------------------------------------------------------------------------------------
  44                            ;	外部割り込み処理
  45                            ;------------------------------------------------------------------------------------------
  46  0004                      		ORG	4                       ;外部割り込みベクタ アドレス(0004番地)
  47  0004 2836                 		GOTO	START                   ;プログラムの開始点(START)へジャンプ
  48                            ;------------------------------------------------------------------------------------------
  49                            ;	ゲット パターン ルーチン LEDの点灯パターン
  50                            ;------------------------------------------------------------------------------------------
  51  0005                      GETPATTERN
  52  0005 0782                 		JMP	PC+W                    ;Wレジスタに?をセットして、RETURNする
  53  0006 3408 3400            		RETW	1000b,00000000b         ;PC+=W+1 テーブル参照		
  54  0008 3404 3400            		RETW	0100b,00000000b         ;プログラム・カウンタ
  55  000A 3402 3400            		RETW	0010b,00000000b         ;
  56  000C 3401 3400            		RETW	0001b,00000000b         ;
  57  000E 3400 3480            		RETW	0000b,10000000b         ;
  58  0010 3400 3440            		RETW	0000b,01000000b         ;
  59  0012 3400 3420            		RETW	0000b,00100000b         ;
  60  0014 3400 3410            		RETW	0000b,00010000b         ;
  61  0016 3400 3408            		RETW	0000b,00001000b         ;
  62  0018 3400 3404            		RETW	0000b,00000100b         ;
  63  001A 3400 3402            		RETW	0000b,00000010b         ;
  64  001C 3400 3401            		RETW	0000b,00000001b         ;
  65                            
  66  001E 3400 3401            		RETW	0000b,00000001b         ;
  67  0020 3400 3402            		RETW	0000b,00000010b         ;
  68  0022 3400 3404            		RETW	0000b,00000100b         ;
  69  0024 3400 3408            		RETW	0000b,00001000b         ;
  70  0026 3400 3410            		RETW	0000b,00010000b         ;
  71  0028 3400 3420            		RETW	0000b,00100000b         ;
  72  002A 3400 3440            		RETW	0000b,01000000b         ;
  73  002C 3400 3480            		RETW	0000b,10000000b         ;
  74  002E 3401 3400            		RETW	0001b,00000000b         ;
  75  0030 3402 3400            		RETW	0010b,00000000b         ;
  76  0032 3404 3400            		RETW	0100b,00000000b         ;
  77  0034 3408 3400            		RETW	1000b,00000000b         ;
  78                            ;------------------------------------------------------------------------------------------
  79                            ;	開始プログラム
  80                            ;------------------------------------------------------------------------------------------
  81  0036                      START                                                   ;プログラムの始まり
  82  0036 0185                 		CLR	ra                      ;RA=0		
  83  0037 0186                 		CLR	rb                      ;RB=0	
  84  0038 3000 0065            		MOV	!ra,#0                  ;Aポート出力設定
  85  003A 3000 0066            		MOV	!rb,#0                  ;Bポート出力設定
  86                            
  87  003C                      MAIN0
  88  003C 018C                 		CLR	POI                     ;POI=0
  89                            
  90  003D                      MAIN
  91  003D 080C 008D            		MOV	WK,POI                  ;WK=POI
  92  003F 1003                 		CLC                                  ;CF=0
  93  0040 0D8D                 		RL	WK                      ;WKを左へシフト(1ビット)
  94                            
  95  0041 080D                 		MOV	W,WK                    ;W=WK
  96  0042 2005                 		CALL	GETPATTERN              ;ゲットパターンルーチン呼び出し
  97  0043 0085                 		MOV	ra,W                    ;RA=W
  98                            		
  99  0044 0A8D                 		INC	WK                      ;WK++
 100                            
 101  0045 080D                 		MOV	W,WK                    ;W=WK
 102  0046 2005                 		CALL	GETPATTERN              ;ゲットパターンルーチン呼び出し
 103  0047 0086                 		MOV	rb,W                    ;RB=W
 104                            		
 105  0048 204F                 		CALL	WAIT                    ;ループ・タイマールーチンの呼び出し
 106                            		
 107  0049 0A8C                 		INC	POI                     ;POI++
 108  004A 3018 020C 1C03 283D  		CJB	POI,#24,MAIN            ;IF POI <24 の時 mainへジャンプ
 109  004E 283C                 		GOTO	MAIN0                   ;main0へジャンプ
 110                            ;------------------------------------------------------------------------------------------
 111                            ;	ループ・タイマー ルーチン
 112                            ;------------------------------------------------------------------------------------------
 113  004F                      WAIT
 114  004F 018E                 		CLR	TM1                     ;TM1=0
 115  0050                      WAIT0
 116  0050 018F                 		CLR	TM2                     ;TM2=0
 117  0051                      WAIT1
 118  0051 0000                 		NOP                                  ;1クロック時間を消費する
 119                            
 120  0052 0B8F 2851            		DJNZ	TM2,WAIT1               ;TM2=TM2-1 IF TM2 NOT= 0 の時 wait1へジャンプ
 121  0054 0B8E 2850            		DJNZ	TM1,WAIT0               ;TM1=TM1-1 IF TM1 NOT= 0 の時 wait0へジャンプ
 122                            
 123  0056 0008                 		RET                                  ;ループ・タイマー ルーチンの出口
 124                            ;------------------------------------------------------------------------------------------


	PIC Assembler 2.02.02 symbol list

  indirect         = 0000    rtcc             = 0001  
  tmr0             = 0001    option           = 0001  
  ps0              = 0001.0  ps1              = 0001.1
  ps2              = 0001.2  psa              = 0001.3
  rte              = 0001.4  rts              = 0001.5
  intedg           = 0001.6  rbpu             = 0001.7
  pc               = 0002    pcl              = 0002  
  status           = 0003    c                = 0003.0
  dc               = 0003.1  z                = 0003.2
  pd               = 0003.3  to               = 0003.4
  rp0              = 0003.5  rp1              = 0003.6
  irp              = 0003.7  fsr              = 0004  
  porta            = 0005    ra               = 0005  
  portb            = 0006    rb               = 0006  
  eedata           = 0008    eeadr            = 0009  
  pclath           = 000A    intcon           = 000B  
  rbif             = 000B.0  intf             = 000B.1
  t0if             = 000B.2  rbie             = 000B.3
  inte             = 000B.4  t0ie             = 000B.5
  eeie             = 000B.6  gie              = 000B.7
  eecon1           = 0008    rd               = 0008.0
  wr               = 0008.1  wren             = 0008.2
  wrerr            = 0008.3  eeif             = 0008.4
  eecon2           = 0009    POI              = 000C  
  WK               = 000D    TM1              = 000E  
  TM2              = 000F    GETPATTERN       = 0005  
  START            = 0036    MAIN0            = 003C  
  MAIN             = 003D    WAIT             = 004F  
  WAIT0            = 0050    WAIT1            = 0051  

  CPIC16F84 Header file Vers.1.00 (16F84.H)

		.nlist

;
;	PIC16F84 Header file Vers.1.00
;

		.16f84			; PIC16F84に設定

indirect	equ	0
rtcc		equ	1		; RTCC = TMR0 = 1
tmr0		equ	1
option		equ	1		; OPTION

ps0		equ	1.0
ps1		equ	1.1
ps2		equ	1.2
psa		equ	1.3
rte		equ	1.4
rts		equ	1.5
intedg		equ	1.6
rbpu		equ	1.7

pc		equ	2		; PC = PCL = 2
pcl		equ	2

status		equ	3		; STATUS
c		equ	3.0		; carry/borrow flag
dc		equ	3.1		; digit carry/borrow flag
z		equ	3.2		; zero flag
pd		equ	3.3		; power down bit
to		equ	3.4		; time out bit
rp0		equ	3.5		; page select
rp1		equ	3.6		;
irp		equ	3.7

fsr		equ	4
porta		equ	5
ra		equ	5

portb		equ	6
rb		equ	6

eedata		equ	8
eeadr		equ	9

pclath		equ	0ah
intcon		equ	0bh
rbif		equ	0bh.0
intf		equ	0bh.1
t0if		equ	0bh.2
rbie		equ	0bh.3
inte		equ	0bh.4
t0ie		equ	0bh.5
eeie		equ	0bh.6
gie		equ	0bh.7

eecon1		equ	8
rd		equ	8.0
wr		equ	8.1
wren		equ	8.2
wrerr		equ	8.3
eeif		equ	8.4
eecon2		equ	9

		.list