C.K PRIVATE アセンブラ・プログラム基礎,

WEB・PIC

C.K PRIVATE アセンブラ・プログラム基礎

C.K PRIVATE /  アセンブラ・プログラム基礎のページです
ここではアセンブラの基礎の部分をリストアップしています

アセンブラプログラム命令系(16F系)

☆アセンブラのPG記述
LABEL TAB MOVF TABかSpace0,1;メモ下記、コメントReturn

☆PICアセンブラ命令

命令 命令内容 命令の説明 影響フラグ サイクル
ADDWF f,d 加算 W+fの結果をWかfへ格納 C,DC,Z 1
ANDWF f,d 論理積 Wandfの結果をWかfへ格納 Z 1
CLRF f ゼロクリア fを0にする Z 1
CLRW ゼロクリア Wを0にクリアする Z 1
COMF f,d 反転 fの反転結果をWかFへ格納 Z 1
DECF f,d -1 f-1の結果をWかfへ格納 1
DECFSZ f,d ゼロスキップ 結果がゼロで次の命令をスキップ 1
INCF f,d +1 f+1の結果をwかfへ格納 Z 1
INCFSZ f,d ゼロスキップ f+1の結果をwかfへ格納し
結果がゼロで次の命令をスキップ 1(2)
IORWF f,d 論理和 worfの結果をwかfへ格納 Z 1
MOVF f,d 移動 fの内容をwかfへ格納 1
MOVWF f 移動 wの内容をfへ格納 1
NOP 無動作 1サイクル使い何もしない 1
RLF f,d 左シフト 1ビット左シフトの結果をwかfへ格納 C 1
RRF f,d 右シフト 1ビット右シフトの結果をWかfへ格納 C 1
SUBWF f,d 減算 w-fの結果をWかFへ格納    c,DC,Z 1
SWAPF f,d 入れ替え f上位と下位の内容を入れ替え後
Wかfへ格納 1
XORWF f,d 排他的論理和 Wxorfの結果をWかFへ格納 Z 1
BCF f,d ビットリセット fのbビット目を0にする 1
BSF f,d ビットセット fのbビット目を1にする 1
BTFSC f,d ビット0スキップ fのbビット目が0
だったら次の命令をスキップ 1(2)
BTFSS f,d ビット1スキップ fのbビット目が1だったら
次の命令をスキップ 1(2)
ADDLW k 定数加算 W+Kの結果をWへ格納    C,DC,Z 1
ANDLW k 定数論理積 Wandkの結果をwへ格納 Z 1
IORLW k 定数論理和 WorKの結果をwへ格納 Z 1
MOVLW k 定数格納 KをWへ格納 1
SUBLW k 定数減算 W-Kの結果をWへ格納    C,DC,Z 1
XORLW k 定数排他的論理和 WxorKの結果をWへ格納 Z 1
CALL k サブルーチンへ サブルーチン「K]へジャンプ 2
GOTO k 無条件ジャンプ 「K]へ無条件ジャンプ 2
RETFIE リターン 割り込み許可で戻る 2
RETLW k リターン Wにkを格納して戻る 2
RETURN リターン 通常のサブルーチンから戻る 2
CLRWDT WDTクリア WDT(ウォッチドッグタイマ)をクリアする 1
SLEEP スリープへ スリープモードにする 1

アセンブラの擬似命令
LIST 書式 LIST P=device_name
アセンブラに対し使用するPICの種類を伝えます、プログラムの先頭に必ず1行必要です

END 書式 END
アセンブラのプログラムの終了を示します
プログラムの最後に必ず1行必要です

EQU 書式 Name EQU nn
名称(ラベル)と数値を対応させるときに使用するイコール命令です
数値はデータでもアドレス値でも定義できます
メモリの割付などに使用します

TOTORO EQU 10
と記述するとTOTOROは10であると宣言することになり、それ以降PG内でTOTOROの
文字が出てくるとそれが10の数値に置き換わります、名称はPICのアセンブラで規定
されている単語以外は自由に使用できます
ラベルはPG上の位置を示す名称で、PGの番地に対応します、主にジャンプ先の位置を示します



VARIABLE 書式 VARIABLE Nane=nn
変数名に数値を対応させます、数値はアドレスです
使用例 VARIABLE DATA=H’A3'

☆プリスケーラ
bit2-0: PS2 : PS1 : PS0プリスケーラレート選択ビット
PS2  PS1  PS0  TMR0  WDT
0 0 0 1:2 1:1
0 0 1 1:4 1:2
0 1 0 1:8 1:4
0 1 1 1:16 1:8
1 0 0 1:32 1:16
1 0 1 1:64 1:32
1 1 0 1:128 1:64
1 1 1 1:256 1:128

アセンブラプログラムその他

数値の表現方法
2進数 B'01011010'
10進数 D'90’
16進数 H'5A'
ASCII  A’Z' 左の数値は皆同じ

エラーの読み方
Error[122] A:\TEST\LED1E.ASM4:Illugal opcode(H)
エラー「122」はエラーコード

その後はドライブと名前

ASM4はそのソースの4行目の所がおかしいことを指している

Illugal opcodeはコードの書き方がおかしいことを表している

簡単な説明
movlw B'00001111' ;2進数で定義 リテラル→Wレジスタ
movwf PORTB ;Wレジスタ→ファイルレジスタ PORTBに出力

各説明
フィールド 説明
f ファイルレジスタのアドレス(0x00~0x7f)
W ワーキングレジスタ(アキュームレータ)
b 8ビットファイルレジスタ内のビットアドレス
K リテラル、定数データまたはラベル
X 無効(=0または1)
アセンブラはX=0としてコードを生成、全て
のソフトウェアツールとの互換性を確保する
ためにX=0を推奨します
d 結果格納先指名子;
d=0(結果はWに格納)
d=1(結果はファイルレジスタ’f’に格納)
デフォルトはd=1
label ラベル名
TOS スタックの最上位
PC プログラムカウンタ
PCLATH プログラムカウンタのハイラッチ
GIE グローバル割り込みイネーブルビット
WDT ウォッチドッグタイマ/カウンタ
TO タイムアウトビット
PD パワーダウンビット
dest 結果格納先(Wレジスタまたは指定されて
いるレジスタファイルのロケーション)
[] オプション
() 内容
→ 割当先
<> レジスタビットフィールド
E セットを表す
イタリック ユーザー定義

PICのサイクル
PICが命令を実行する時間は通常、1/4クロックを1サイクルとする値です、今PIC10F200を内蔵の4Mhz
のクロックで動作させていますので、1サイクルの周波数は1MHz、すなわち1×10の6乗の値の周波数です
のでこれの逆数を取ったものがサイクル時間となり、1サイクル時間は1μ秒ということになります

PICの命令のほとんどは1サイクルで完結し、一部の命令だけが2サイクルを消費します、前者を1サイクル
命令、後者を2サイクル命令といいます、2サイクル命令はGOTOのようなジャンプ命令、CALLのような
サブルーチン命令などです、これらを踏まえて先ほどのPGの処理時間を考えてみると次のようになります
main_loop
;GPIO 0をオン
bsf GPIO,0 ;1サイクル(1μS) ←全て4MHZ時の時間
;GPIO 0をオフ
bsf GPIO,0 ;1サイクル(1μS)
goto main_loop ;2サイクル(2μS)

BSF/BCF命令は1サイクル、すなわち(4Mhz時)1μ秒で実行されます、GOTOは2サイクルなので
2μ秒かかって実行されます、これがオンの時間とオフの時間の比率になっておりオンの時間
が1μ秒、オフの時間は1+2の3μ秒かかっていますから、先ほどオシロスコープで観察した結果に
なるわけです

時間遅延を作る
PICの命令を実行することで「時間」は消費されることが分かりました、ならば、これを利用して
より長い時間を作ってやればLEDは点滅して見えるようにすることが出来るはずです
PICの命令のひとつに「何もしない」というNOP命令というのがあります、これは何も処理をしないのですが
PICのサイクル数を消費しますので、これを並べると時間潰しになるはずです、ところがPICの1サイクル
が1μ秒であったとこを思い出してください、たとえこの命令を100個並べたとしても100μ秒、つまり
0.00000001秒しか時間を消費することが出来ないため、点滅には程遠いいのです、
そこでカウンタループ処理を用いることで時間をつぶすPGを書くことにします、カウンタというのは
PICの内部のタイマーといった、方法を使うこともできるのですが、ここでは汎用的に使えるように内部メモリ
すなわちファイル、レジスタのに値をいれその値によってPGをループ処理させます、ですので、この処理では
内部のファイル、レジスタ(汎用レジスタ)を使用します、まず次のようなPGを考えます、ここでCNTなどの
変数に相当する部分はファイル。レジスタのことです、後からこれは定義しますので、ここでは変数のように
値が入るものと理解しておいてください

まず表記方法の問題ですが下記PGにて説明を行います、d200というのは十進数の200.つまり我々が
普通に使う数値の200です、MOVLW命令はオペランドに指定された値をWレジスタに入れた後、
MOVWF命令でファイル、レジスタのCNT2へと値を入れます、ここまでが前準備になります、
ラベルDLP2からがループの部分でNOP命令によって
単に2サイクル消費させます、Decfsz命令だけはちょっと特殊です、Decfszとというのはファイル、レジスタ
の値を-1し、もし値がゼロになったならば次の命令を実行しないで飛ばすという命令です、このための
CNT2の値がゼロになったならば、GOTO DLP2は実行されません、ゼロでない場合は次の命令が実行されます

この際のサイクル数は1+1+1+2=5となります
ここでサイクルは1μ秒(4MHz)でしたから、この繰り返しを200回実行すると、
5×200=1000サイクルとなるので、1ミリ秒遅延することが出来ます

つまり、CNT2に設定する値×5μ秒間の遅延を作ることが出来ます、実際には前準備に2サイクル
、DECFSZがゼロになった際に余計に1サイクルを消費しますから、1ミリ秒に対して3μ秒余分に時間が
かかりますが、1ミリに対する3μは十分に小さい誤差ですからここでは、無視します
さてLEDの点滅ということで、あればもっと遅い間隔が必要です、ところがPIC10F200は8ビットしか
データの幅がないため最大でも255×5μ秒、1.275ミリ秒までしかこの方法では作ることが出来ません
そこで、ループ処理を二重にします、

DLY100 ;200ms  1
movlw d'200' ;ワーキングレジスタに200をセットする  2   
movwf CNT1 ;CNT1に200をセットする  3
DLP1 ;1ms  4
movlw d'200' ;上に同じ  5
movwf CNT2 ;上に同じ    6
DLP2 ; 7
nop ;何もしない  8
nop ;何もしない  9
decfsz CNT2,f ;カウントしていく  10
goto DLP2 ;7行目へ  内側ループ  11
decfsz CNT1,f ;カウントしていく  12
goto DLP1 ;4行目へ  外側ループ  
 
遅延タイマ書式例
PICはクロック4回で1つの命令が実行されます、これを1サイクルといいます
10Mhzのクロックで1サイクルにかかる時間はどのぐらいでしょうか??
1/10.000.000×4=0.000.0004S 1サイクル:0.4μS(μS)

0.5S=500mS=500.000μSののタイマを作るには何サイクル必要でしょうか?
500.000÷0.4=1.250.000サイクル   0.5Sタイマ:125万サイクル