2個のLEDの交互点滅をやってみました。ソースはこれ(lesson2.asm) 。
ポイントをメモしておきます。
;=================
TIMER1 EQU 20H
TIMER2 EQU 21H
TIMER3 EQU 22H
;=================
TIMER1~3をLEDの点滅のインターバルタイマーの変数に使います。
;========================================
MAIN
BSF PORTA,2 ;RA2のLED点灯
BCF PORTA,3 ;RA3のLED消灯
CALL TIMELOOP1 ;時間稼ぎのサブルーチンへ
BCF PORTA,2 ;RA2のLED消灯
BSF PORTA,3 ;RA3のLED点灯
CALL TIMELOOP1 ;時間稼ぎのサブルーチンへ
GOTO MAIN
;========================================
これがメインプログラム。今回は,BSF(Bit Set F)でLEDを点灯,BCF(Bit Clear F)で消灯させてみました。
インターバルを取って点滅させるために時間稼ぎのためのTIMELOOPというサブルーチンに飛びます。
;===================================================
TIMELOOP1 ;約0.4sの時間稼ぎ
MOVLW D'20'
MOVWF TIMER1 ;変数TIMER1に20を代入
LOOP1
CALL TIMELOOP2 ;時間稼ぎのサブルーチン2へ
DECFSZ TIMER1,F ;TIMER1を1ずつ減じ,0になったら次行をスキップ。
GOTO LOOP1
RETURN
TIMELOOP2 ;約20msの時間稼ぎ
MOVLW D'200'
MOVWF TIMER2
LOOP2
CALL TIMELOOP3 ;時間稼ぎのサブルーチン3へ
DECFSZ TIMER2,F
GOTO LOOP2
RETURN
TIMELOOP3 ;約0.1msの時間稼ぎ
MOVLW D'166'
MOVWF TIMER3
LOOP3
DECFSZ TIMER3,F
GOTO LOOP3
RETURN
;===================================================
まずTIMELOOP3から説明します。
変数TIMER3に166を代入し,DECFSZ TIMER3,F(Decrement F,Skip if 0)で1ずつ減じていきます。
TIMER3が0になったら次のGOTO LOOP3をスキップして,RETURNします。
このサブルーチンで約0.1msの時間稼ぎができます。
僕のテスト基板は20MHzのセラロックで動いているので,PICの命令1つ(1サイクル=4クロック)を実行するのに0.2μsかかります。GOTOとCALLとRETURNは2サイクルかかることに注意して,このサブルーチンを1回実行するのにかかる時間を計算すると,約0.1msとなります。計算が間違ってなければね(笑)
1つのサブルーチンで0.5sくらい時間を稼げるといいのですが,変数に代入できる数値は最大256なので,TIMELOOP1~TIMELOOP3の3つを用意したわけです。
2つでもできるんだけど,20msは後で必要(タクトスイッチのチャタリング対策)な気がしたので作っておきました。
で,実行結果の動画がこれ↓です。
VIDEO
【今日覚えた命令】 CALL,DECFSZ,RETURN