PIC16F18346の基本動作から応用プログラムまでを学びます。

ホーム
12F1822
16F1455
16F1459
18F14K50
18F26J50
dsPIC
その他
    
16F18313
16F18325
16F18346
16F1619
Curiosity
---
---
pic-as アセンブラでLEDを点滅
2021-11-03

Microchip社は、今までの標準アセンブラソフトであった MPASM から、新たにXC8_AS または、PIO_AS と言われる XC8 Cコンパイラと親和性の高いアセンブラソフトへの切り替えを行いました。このため今までMPLABに必ず付属していた MPASM が最新のMPLAB X 5.40以降には付属していません。

また、MPASM は32ビットソフトウエアのため、MAC OS も、Mpjaveまでしか対応しません。最新のMACでは、MPASM を動作させる環境を作るのは大変困難になっています。

変更からまだ一年程度しか経っていないため、pic-as に関する情報は少ないのですが、手に入るmicrochio社のmanualやインターネット上の記事から、MPASMからの移植や使い方をまとめました。

MPASM から pic-as への変更

MPASMとpic-asの注意が必要な差を以下に示します。LEDを点滅させるプログラムを、C言語、MPASM、pic-as の3種類の言語で作成しました。これらのソースリストを見比べながら、MPASM から pic-as への変更箇所をを確認してください。

  1. ラベル文字の最後に ':' をつける
  2. 0x以外の数値識別子が異なる
  3. cblock は使えないので、equ を使用する
  4. org の代わりに、psect を使用する
  5. コンフィグ指定は、xc8 で使用の形式とする
  6. オペランドでの SFR の表記に注意する
ラベル文字の最後に ':' をつける

MPASMでもラベル文字列の最後に ':' をつけることが許容されていましたが、プログラムの多くは、ラベル文字の最後に ':' は付けていません。しかし、pic-as では必ず':' をつける必要があります。

    === MPASM ===                            === picーas ===
  Loop    decfsz  count,F                   Loop:   decfsz  count,F
          bra     Loop                              bra     Loop
0x以外の数値識別子が異なる

主要な表記法を下の表にまとめました。プログラムでは、0x を使用した16進表記が多いので、書き換えは少ないかもしれません。

MPASM種類pic-assembler
 B'01001111'2進数 01001111B
 O'72'8進数 72Q
 D'34' または .3410進数 34 または 34D
 H'4F' または 0x4F16進数 04FH または 0x4F
cblock は使えないので、equ を使用する

MPASMでもequ を使用してプログラムする例が多くあり、それほで違和感なく書き換えできました。

      === MPASM ===                            === picーas ===
      cblock 0x70
        count_1                                count_2  equ  0x70
        count_2                                count_2  equ  0x71
      endc			
org の代わりに、psect を使用する

pic-as は、プログラムを再配置可能なモジュール化して、大規模なプログラムや、他言語のプログラムと共存するために, psect(program section)単位で処理されているようです。

ここに掲載したプログラム例では、Por_Vec という program section を作成し、その開始番地を、0x0 にするよう、 pic-as linker を設定します。

電源投入時のプログラム開始を指定する org 0 と同等な具体的な記述法は、

MPLAB X の設定手順は以下のとおり

  1. project propaty ボタンを押し、プロパティーウインドを開く
  2. pic-as Linker をクリック
  3. Custom linker options の入力欄をクリックしてから "-pPor_Vec=0h" と入力
  4. 正しく入力がされていることを確認して [OK] をクリックする
コンフィグ指定は、xc8 で使用の形式とする

コンフィグビットの指定は、__CONFIG を使用して各項目を "&" で繋ぐ方法ではなく。xc8C言語で使用している指定方法になりました。

オペランドでの SFR の表記に注意する

例えば、「 bsf  LATC, 0x5 」 命令を例にとり考えてみます。

これを2進数で表すと 「01 01bb bfff ffff」 b = bit address   f = file register address

LATCは、<xc.inc> 内部で、バンク情報と組み合わせて0x10E と処理されているので
                 「1 0000 1110」です。

つまり、命令bsfが求めているバンク内オフセット情報の7ビットより大きい数値が、アセンブラに渡されることになります。一応機械語に翻訳する際にオフセット情報だけに丸める処理がされているようですが、完全ではないようで、マニュアルには、バンク内オフセット情報だけにして、コーディングすることを推奨しています。

この目的で、マクロ BANKMASK( ) が準備されています。このマクロを使用すると、例の命令文は
    「 bsf  BANKMASK( LATC ), 0x5 」

とするのが良いようです。

 

ただし「bsf  LATC, 0x5 」 命令は、LATC5 をセットする目的で使用しているの命令ですが、<xc.inc>には、LATC5 が以下のように定義されています。
     #define    LATC5    BANKMASK(LATC), 5

つまり、「bsf  LATC, 0x5 」  命令は、
    「bsf LATC5 」   と書くのが最良のようです。

プログラム例

LEDを点滅させるプログラムを、C言語、MPASM、pic-as の3種類の言語で作成しました。

== xc8 C言語 ==

#include <xc.h>
#define _XTAL_FREQ 1000000      // delay_ms(x) のための定義

#define LED    LATC5

#pragma config FEXTOSC = OFF, RSTOSC = HFINT1, CLKOUTEN = OFF
#pragma config CSWEN = ON   , FCMEN = ON     , MCLRE = ON
#pragma config PWRTE = OFF  , WDTE = OFF     , LPBOREN = OFF
#pragma config BOREN = OFF  , BORV = LOW     , PPS1WAY = OFF
#pragma config STVREN = ON  , DEBUG = OFF    , WRT = OFF
#pragma config LVP = ON     , CP = OFF       , CPD = OFF

void main(void) {
    TRISC = 0b11011111;     // RC5:output RC4:input
    ANSELC = 0;             // デジタル I/O pin
    while(1){
         LED = 1;           // 点灯
         __delay_ms(800);   // 100mS遅延
         LED = 0;           // 消灯
         __delay_ms(800);   // 100mS遅延
    }
}
			

== MPASM アセンブラ言語 ==

	LIST		P=PIC16F18346	; 使用するPICを指定
	INCLUDE		"P16F18346.INC"	; 読み込む設定ファイルを指定

 __CONFIG _CONFIG1, _FEXTOSC_OFF & _RSTOSC_HFINT1 & _CLKOUTEN_OFF & _CSWEN_OFF & _FCMEN_OFF
 __CONFIG _CONFIG2, _MCLRE_ON & _PWRTE_OFF & _WDTE_OFF & _LPBOREN_OFF & _BOREN_OFF & _BORV_LOW & _PPS1WAY_OFF & _STVREN_ON & _DEBUG_OFF
 __CONFIG _CONFIG3, _WRT_OFF & _LVP_ON
 __CONFIG _CONFIG4, _CP_OFF & _CPD_OFF

; ******* 共通のRAMエリア *************************
	cblock 0x70
		count_1
		count_2
	endc
 ; ******* main プログラム ***********************
       ORG   0
       movlw 0xDF    ; TRISC = 0b11011111
       movlb 0x1
       movwf TRISC   ; RC5:output
       movlb 0x3
       clrf  ANSELC   ; デジタル I/O pin
Loop
       movlb 0x2
       bsf   LATC, 0x5    ; LED 点灯
       call  Count64k     ; 遅延 (789 ms)
       movlb 0x2
       bcf   LATC, 0x5    ; LED 消灯
       call  Count64k     ; 遅延 (789 ms)
       goto  Loop

; 遅延関数 256 x 256 (789 ms)
Count64k
	clrf    count_1
	clrf    count_2
Count64kLoop
	decfsz  count_1,F
	bra     Count64kLoop
	decfsz  count_2,F
	bra     Count64kLoop
	return
	END
		 			

== pic-as アセンブラ言語 ==

    PROCESSOR 16F18346
#include <xc.inc>

config FEXTOSC = OFF, RSTOSC = HFINT1, CLKOUTEN = OFF
config CSWEN = ON   , FCMEN = ON     , MCLRE = ON
config PWRTE = OFF  , WDTE = OFF     , LPBOREN = OFF
config BOREN = OFF  , BORV = LOW     , PPS1WAY = OFF
config STVREN = ON  , DEBUG = OFF    , WRT = OFF
config LVP = ON     , CP = OFF       , CPD = OFF

; ******* 共通のRAMエリア *************************
       count_1 equ 0x70
       count_2 equ 0x71
; ******* main プログラム ***********************
    PSECT   Por_Vec,class=CODE,delta=2
Start:
       movlw 0xDF                   ; TRISC = 0b11011111
       movlb 0x1
       movwf BANKMASK(TRISC)        ; RC5:output
       movlb 0x3
       clrf  BANKMASK(ANSELC)       ; デジタル I/O pin
Loop:
       movlb 0x2
       bsf   BANKMASK(LATC), 0x5    ; LED 点灯
       call  Count64k               ; 遅延 (789 ms)
       movlb 0x2
       bcf   BANKMASK(LATC), 0x5    ; LED 消灯
       call  Count64k               ; 遅延 (789 ms)
       goto  Loop

; 遅延関数 256 x 256 (789 ms)
Count64k:
       clrf    count_1
       clrf    count_2
Count64kLoop:
       decfsz  count_1,F
       bra     Count64kLoop
       decfsz  count_2,F
       bra     Count64kLoop
       return

       END Start