common.incで提供される機能の説明です。
目次
テーブルジャンプ
プログラムカウンタとRETLW命令を利用したテーブル機能を提供します。引数は変数のみです。
on_goto_U1 MACRO varU1
このマクロ呼出しに続けてRETLW命令でテーブルを構成します。
例では、変数varの値(0〜3)によって'A' 'B' 'C' 'D'のいずれかを返すようになっています。
on_goto_U1 var RETLW 'A' RETLW 'B' RETLW 'C' RETLW 'D'
0〜255までの値に対応、テーブル領域がxxFFhとxx00hの境を含む場合も考慮してます。
メモリクリア
指定のメモリブロックを任意の値で埋める機能を提供します。
memset_V1V1V1 MACRO start, c, n
start番地からn個のメモリブロックを、値cで埋めます。ゼロクリアなどに利用できます。
下記の例では、0x20〜0x3fまでを0xffで埋めています。
memset_V1V1V1 0x20, 0xff, 16
直アドレスではなく、ラベルでも構いません。
テンポラリ変数を使用しているので
COMMON_functions
という記述をソースの最後に付けて、自動定義されるようにしておきます。
間接参照
PICのちょっと面倒なメモリ間接参照を簡単に使えるような機能を提供します。C言語のイメージとしては、「start[index] 」こんな感じです。
読出し系
先頭番地、加算値ともに定数の場合
W_read_ram_V1V1 MACRO start, index
読み出し結果ははWレジスタに入ります。
U1_read_ram_V1V1 MACRO varU1, start, index
読み出し結果はvarU1で指定する変数に入ります。
先頭番地が定数、加算値が変数の場合
idxU1に加算値が格納されている変数を指定します。
W_read_ram_V1U1 MACRO start, idxU1
読み出し結果ははWレジスタに入ります。
U1_read_ram_V1U1 MACRO varU1, start, idxU1
読み出し結果はvarU1で指定する変数に入ります。
書込み系
先頭番地、加算値、書込み値が定数の場合
write_ram_V1V1V1 MACRO start, index, value
先頭番地が定数、加算値・書込み値が変数の場合
write_ram_V1U1U1 MACRO start, idxU1, varU1
テーブルジャンプの例
- リロケータブル形式となりますので、16f819.lkrファイルをプロジェクトに加える必要があります。
- 簡単に記述するため、intr.incとope.incを使っています。詳しくはそれぞれの使い方を参照してください。
- ヘッダファイルはソースファイルの一つ上の階層に置かれているので、'../common.inc'のように相対パスで記述しています。
- dec2hexというラベル部分でテーブルジャンプを使用しています。変数tempの値によって、'0'〜'F'までの16進数文字に変換する機能を作ってみました。
- MPLABで_NOP_部分などにブレークポイントを置いて、正常に動作していることを確認してみてください。
- dtマクロの他にdataマクロも使えます。
; Title : common.inc test 1 ; By : komi ; Last update : 2007.04.21 ; Version : 0.1 ;------------------------------------------------------------------ ; use MPLAB IDE v7.52 ;------------------------------------------------------------------ PROCESSOR PIC16F819 INCLUDE P16F819.INC __CONFIG _CP_OFF & _DEBUG_ON & _WRT_ENABLE_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_IO ERRORLEVEL -302 ; bank message 抑制 ERRORLEVEL -312 ; page message 抑制 RADIX DEC ; base 10 ;------------------------------------------------------------------ #define CLOCK_FREQ 20000000 ;------------------------------------------------------------------ INCLUDE "../common.inc" INCLUDE "../intr.inc" INCLUDE "../ope.inc" #define _NOP_ NOP ;------------------------------------------------------------------ ; 変数定義 UDATA temp RES 1 ;------------------------------------------------------------------ ; スタートコード START_VECTOR ;------------------------------------------------------------------ ; メイン MAIN_ROUTINE move_U1V1 temp, 0 loop1: CALL dec2hex _NOP_ inc_U1 temp if_U1V1_goto temp, _IsNotEqualTo_, 16, loop1 stop_loop: GOTO stop_loop dec2hex: on_goto_U1 temp dt '0', '1', '2', '3', '4', '5', '6', '7' dt '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' ;------------------------------------------------------------------ ; 割り込み処理 INTERRUPT_START SAVE_CONTEXT LOAD_CONTEXT INTERRUPT_END ;------------------------------------------------------------------ END
メモリクリアの例
- リロケータブル形式となりますので、16f819.lkrファイルをプロジェクトに加える必要があります。
- 簡単に記述するため、intr.incとope.incを使っています。詳しくはそれぞれの使い方を参照してください。
- ヘッダファイルはソースファイルの一つ上の階層に置かれているので、'../common.inc'のように相対パスで記述しています。
- 32バイトのメモリを確保してbufferというラベルを付けます。
- 3回にわたってメモリクリアしてます。
- 今回は0xA0から32バイト確保されましたので実行結果は下図のようになりました。
- COMMON_functionsを最後に記述するのを忘れずに。
;------------------------------------------------------------------ ; 変数定義 UDATA buffer RES 32 ;------------------------------------------------------------------ ; スタートコード START_VECTOR ;------------------------------------------------------------------ ; メイン MAIN_ROUTINE memset_V1V1V1 buffer, 0xff, 32 _NOP_ memset_V1V1V1 buffer, 0x55, 16 _NOP_ memset_V1V1V1 buffer, 0xaa, 8 _NOP_ stop_loop: GOTO stop_loop ;------------------------------------------------------------------ ; 割り込み処理 INTERRUPT_START SAVE_CONTEXT LOAD_CONTEXT INTERRUPT_END ;------------------------------------------------------------------ ; 共用部 COMMON_functions ;------------------------------------------------------------------ END
間接参照の例
- リロケータブル形式となりますので、16f819.lkrファイルをプロジェクトに加える必要があります。
- 簡単に記述するため、intr.incとope.incを使っています。詳しくはそれぞれの使い方を参照してください。
- ヘッダファイルはソースファイルの一つ上の階層に置かれているので、'../common.inc'のように相対パスで記述しています。
本分でないトコロが多くなってますが・・・。
- buffer[0]〜[31]までに32から1までの値を入れる。(loop1)
- buffer[0]〜[31]を読み出して、それぞれ4倍(2ビットシフト)し格納しなおす。(loop2)
といった処理を行っています。C言語っぽいコメントを参考にしてみてください。
loop1が終わった時点。0x20(32)〜0x01(1)までが書き込まれています。
loop2が終わった結果。4倍になった値、0x40(80)〜0x04(4)までが書き込まれています。
;------------------------------------------------------------------ ; 変数定義 UDATA buffer RES 32 cnt RES 1 imm RES 1 ;------------------------------------------------------------------ ; スタートコード START_VECTOR ;------------------------------------------------------------------ ; メイン MAIN_ROUTINE move_U1V1 imm, 32 ; imm = 50; move_U1V1 cnt, 0 ; cnt = 0; loop1: ; buffer[cnt] = imm; write_ram_V1U1U1 buffer, cnt, imm dec_U1 imm ; imm--; inc_U1 cnt ; cnt++; ; if (cnt < 32) goto loop1; if_U1V1_goto cnt, _IsSmallerThan_, 32, loop1 move_U1V1 cnt, 0 ; cnt = 0; _NOP_ loop2: ; imm = buffer[cnt]; U1_read_ram_V1U1 imm, buffer, cnt ; imm <<= 2; lshift_U1 imm, 2; ; buffer[cnt] = imm; write_ram_V1U1U1 buffer, cnt, imm inc_U1 cnt ; cnt++; ; if (cnt < 32) goto loop1; if_U1V1_goto cnt, _IsSmallerThan_, 32, loop2 _NOP_ stop_loop: GOTO stop_loop ;------------------------------------------------------------------ ; 割り込み処理 INTERRUPT_START SAVE_CONTEXT LOAD_CONTEXT INTERRUPT_END ;------------------------------------------------------------------ END