PIC16F84Aを使用したLEDのフロー表示(順次点灯)は、Bポートが8ビット、Aポートが5ビットのためBポートのみを使用したものが多く、AポートとBポートが連動しているものはあまり見かけませんでした。そこで動作パターンとしてA4→B0→B1→B2→B3→B4→B5→B6→B7→A0→A1→A2→A3を一巡としこれをエンドレスに繰返すフロー表示を製作しました。単純な方法としてはbcf、点滅用遅延ルーチン、bsfを反復使用する方法がありますが単純すぎるので他の方法にしました。色々参考にして回転(rlf)を使用する方法にしました。今回はアセンブラを使用しましたが、MPLABのデバッグモードでレジスタを監視しながらデバッグできますので思っていたよりも楽でした。A4をスタートとしたのは、A4がオープンドレインなのでプルアップしており、電源投入時オンしてしまうためです。
回路は下図になります。セラミック発振子は12MHzを使用しています。この回路では青色LEDを使用しましたのでLEDに100Ω直列接続し電流は約17mAです。LED1個あたりの点灯時間は約80mSecになっています。A4はオープンドレインになっていますので、出力ポートとし使うときは抵抗でプルアップする必要があります。点灯の順序はA4が最初に点灯し次にB0からB7、A0からA4と順次移動していきます。
LIST P=PIC16F84A
INCLUDE <P16F84A.inc>
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC
COUNT1 EQU 0x0C ;0C番地以降は汎用レジスタ
COUNT2 EQU 0x0D
BPT EQU 0x0E ;PORTのビットパターン
AB EQU 0x0F
ORG 0x00
GOTO main
ORG 0x04
GOTO main
main
bcf STATUS,RP0 ;00でバンク0
bcf STATUS,RP1
CLRF INTCON ;割込みクリア
bsf STATUS,RP0 ;01でバンク1
CLRF TRISA ;Aポートを出力に設定
CLRF TRISB ;Bポートを出力に設定
bcf STATUS,RP0 ;00でバンク0
main_1
movlw 0x00
movwf PORTA ;PORTAをLにして全消灯
movlw 0x00
movwf PORTB ;PORTBをLにして全消灯
bcf STATUS,C ;キャリーフラグをクリア
clrf AB ;ABレジスタを0000 0000に
movlw 0x01
movwf BPT ;BPTレジスタを0000 0001に
LOOP1
movf BPT,w ;BPTのビットパターンを
movwf PORTB ;PORTBに設定
call DELAY_250 ;ビット点灯時間
btfsc BPT,7 ;B7が0なら次行をスキップ
bsf AB,0 ;ABレジスタのビット0を1に
btfsc BPT,0 ;BPTレジスタのbit0が0なら次行をスキップ
bcf AB,0 ;ABレジスタのbit0を0に
btfsc AB,0 ;ABレジスタのbit0が0なら次行をスキップ
goto main_2 ;main_2へ
rlf BPT,f ;BPTレジスタのビットパターンを左へシフト
goto LOOP1 ;LOOP1へ
main_2
movlw 0x00
movwf PORTA ;PORTAをLにして全消灯
movlw 0x00
movwf PORTB ;PORTBをLにして全消灯
bcf STATUS,C ;キャ リーフラグをクリア
clrf AB ;ABレジスタをクリア
movlw 0x01
movwf BPT ;BPTレジスタを0000 0001に
LOOP2
movf BPT,w ;BPTのビットパターンを
movwf PORTA ;PORTAに設定
call DELAY_250 ;ビット点灯時間
btfsc BPT,5 ;A4が0なら次行をスキップ
bsf AB,0 ;ABレジスタのビット0を1に
btfsc BPT,0 ;BPTレジスタのbit0が0なら次行をスキップ
bcf AB,0 ;ABレジスタのbit0を0に
btfsc AB,0 ;ABレジスタのbit0が0なら次行をスキップ
goto main_1 ;main_1へ
rlf BPT,f ;BPTレジスタのビット位置を左へシフト
goto LOOP2 ;LOOP2へ
DELAY_250
movlw 0xFA ;COUNT1に250を代入
movwf COUNT1
DELAY1
movlw 0xC8 ;COUNT2に200を代入
movwf COUNT2
DELAY2
nop ;1サイクル何もしない
nop ;1サイクル何もしない
decfsz COUNT2,f ;COUNT2をデクリメント、0になったら次行を
;スキップ
goto DELAY2
decfsz COUNT1,f ;COUNT1をデクリメント、0になったらリタ
;ーン
goto DELAY1
return
END
LEDの0.08秒点灯を順次移動させていきます。mainはポートA、Bを出力に設定しています。main1はポートA、Bの点灯パターンを初期設定しています。LOOP1はBポートの順次点灯、LOOP2はAポートの順次点灯を行っています。ABレジスタはポートのフラグ、BPTレジスタはポートのビットパターンを表します。
DELAY_250はDELAY2の最初から4行で5サイクル費やし1サイクルは4クロック、1クロックは0.083μSecですから1サイクル0.33μSecで5サイクルで1.67μSec、COUNT2が200ですから0.33mSecとなります。COUNT1が250ですから82.5mSecになります。
縦の5個のLEDはAポートに、横の8個のLEDはBポートにつながっています。