PICを、アセンブリ言語のプログラムで使う。

PICで電子工作をするため、アセンブリ言語プログラムを使い始める。

当ブログをご覧いただき、ありがとうございます。
ご注意事項:
記載内容には、十分注意しておりますが、勘違い、記憶違い、理解不足、思い込み等が無いとは限りませんので、申し訳ありませんが、 記載内容の正確性は保障致しません(出来ません)。
従いまして、このブログの内容を参考にする事に起因して生じる、または 生じた、いかなる事態にも、当方は何の責任も取れませんので、 参考にされる場合は、自己責任にてお願い致します。
このブログのアセンブリ言語に関する説明には、PICで電子工作するのに必要な事柄以外(私のレベルで)は出てきません、ご了承願います。

PICをアセンブリ言語のプログラムで使う、は新記事の公開を終了します。

PICをアセンブリ言語のプログラムで使う、は新記事の公開を終了します。

 

MICROCHIPでは。最近のMPLABからアセンブリがサポートされておらず、また、マイクロチップのサイトに MPLAB XPRESS というアセンブリの開発環境が

あったのですが、こちらもC言語環境に移行したようです、従って、アセンブリでプログラムを記述し、ビルドして機械語ファイルを作成する環境を構築することが困難に

なり、残念ですが今回をもって記事の公開は終了いたします。

なお、ブログ自体の更新は終わりますが、ブログ自体は、残しておきます。

C言語プログラムで、同じようなブログをやっております。

higonohimajin.hatenablog.com

アセンブリ言語で、LCD表示器を使う、ハードウエア編。

今回は、LCD表示器に文字を表示します。

 

まずは回路ですが、下の通りです。

f:id:higonohimajin:20210505074951p:plain

使用する、LCD表示器は、秋月電子で売っている超小型LCDキャラクタディスプレイモジュール(16×2行 白抜き)型番SD1602VBWB-XA-G-G(下写真)です。

f:id:higonohimajin:20210505075135p:plain

LCDキャラクタディスプレイモジュール 表(文字表示面)

f:id:higonohimajin:20210505084555p:plain

文字表示状況(写真は、違う型番のものですが、表示は同じです)右から光っているのがバックライトです。

f:id:higonohimajin:20210505075020p:plain

LCDキャラクタディスプレイモジュール 裏

この表示器には、バックライト(裏面照明)がついており、15(+)・16(-)番ピンに電源を接続(電流制限抵抗が必要)するか、裏面のJ3パッドを短絡し、R9に100Ωの電流制限抵抗を接続すると点灯することができます。

 なお、ピンの並びが、端から順番になっていないので、注意が必要です、また、このLCD表示器には、姉妹品があるのですが、物によってピン配置が異なるので、差し替える場合は注意が必要です。

 さて、このLCD表示器は、データーラインが8ビットと4ビットのどちらかを選択して使用しなければなりません、ここでは、配線が少なくて済む4ビットモードで使います、したがって、回路図のLCD表示器のD0~D3端子(7~10番端子)は無接続になっています。

(メーカーのデータシートに、使わない端子は解放(無接続)にするよう書かれています、また、4ビットモードで使うとPICのピンが4つで済むので、空いた4つのピンを他に使えます)

ハードウエアの構成は決まったので、ブレッドボードに組んでおきます。 

f:id:higonohimajin:20210505085748j:plain

 回路を組んだブレッドボード(もう、プログラムが走ってます)

 

次回から、LCD表示器のプログラムでの制御方法を勉強します。

アセンブリ言語で、4桁7セグメントLED表示器を使う。

今回は、4桁7セグメントLED表示器をダイナミック点灯にて駆動してみた。

プログラムは、下の通りです。

f:id:higonohimajin:20210423082029p:plain

f:id:higonohimajin:20210423082045p:plain

f:id:higonohimajin:20210423082110p:plain

f:id:higonohimajin:20210423082131p:plain

f:id:higonohimajin:20210423082201p:plain

f:id:higonohimajin:20210423082218p:plain

上記プログラムには、使っていない変数が定義されています。

上のプログラムを実行する回路は下の通りです。

f:id:higonohimajin:20210423082537p:plain

PICマイコンは、PIC16F627Aの持ち合わせがなくなったので、PIC16F628Aを使いました、メモリの容量が多いだけで、ほぼ同じです。

実際の動作状況を撮影してみました。

youtu.be

表示している数字は、各セグメントの表示時間(ms)です、表示時間を短くすると各桁が同時に点灯しているように見えてきます、ダイナミック点灯駆動方式の原理です。

アセンブリ言語で、LEDチカチカをやってみた。

アセンブリ言語でプログラムを書いて、LEDチカチカをやってみた。

 

下が、そのプログラム、40行まで、初期設定である。

29、30行で変数のラベルを設定。

34行からがメインプログラム、35行でメモリのバンクを1に変更。

(TRISレジスタがバンク1にあるから)

36,37行でPORTAおよびBを全部出力に設定。

38でメモリのバンクを0に戻す。

39、40行で、コンパレータをOFFにし、1、2、17、18ピンをデジタル入出力に設定。

 

f:id:higonohimajin:20210407091508p:plain

 

上の続き。

f:id:higonohimajin:20210407094250p:plain

42行はLIGHTというラベルを設定。

43行でLED点灯用データをWレジスタに入れる。

44行でWレジスタのデータをPORTBにいれて、LEDを点灯させる。

45行は、DELAYサブルーチン(待ち時間作成サブルーチン)に飛ぶ。

46行でPORTBをクリア(0にする)して、LEDを消す。

47行は、DELAYサブルーチンに飛ぶ。

48行で、LIGHT(ラベル)に飛ぶ。

以上で、42行から、48行までを永久に繰り返すことにより、LEDが点滅し続ける。

以下、サブルーチンの説明。

50行がDELAYサブルーチンの始まり、DELAYというラベルにした。

51行で、繰り返し回数データ(0FFh、10進数で255)をWレジスタに入れる。

52行で、Wレジスタのデータを変数COUNT1に入れる。

54行が繰り返しの始まり、LOOP1というラベルにした。

55行は、DELAYSサブルーチン(待ち時間作成サブルーチン)に飛ぶ。

56行は、COUNT1から1を引き、COUNT1が0でない時次の行に行き、0の時は、次の行をNOP命令にして実行後、その次(58行)の行に行く。

57行は、LOOP1に飛ぶ。

(54行から、57行までが255回繰り返されるとCOUNT1が0になり、58行が実行され、CALL命令の次の行に戻る。)

58行は、CALL命令の次の行に飛ぶ。

60行から、68行までは、54行から、57行までとほぼ同じ内容で、65行のみNOP命令になっているだけである。

CALL命令で、DELAYサブルーチンが呼び出されると、LOOP1を255回実行する内にLOOP2が255回呼び出され実行される、この実行時間をLEDの点灯および消灯時間にしている。

その時間は、アセンブリ言語ではほぼ正確に算出できる。

まず1命令の実行時間は、クロックが4MHzだから、1μSとなる。

では、命令の数を計算してみよう、命令の数が算出できれば、命令数✖1μSで、計算できる。

まず、50行から、DELAYはラベルであり命令ではないので、数えない。

51行と52行で、2命令。

55行はCALL命令で、2サイクル命令なので、2命令。

 

ここで60行に飛んで、61行と62行で2命令。

65,66,67行は、3命令で、254回繰り返すので、3✖254=762命令。

65,66,67行の最後の1回は、65.66,67(NOP命令になる)の3命令とリターン命令(2サイクル命令)で5命令。

つまり、DELAYSサブルーチンの命令数は、769命令。

 

56行にサブルーチンから戻ってくると、56、57行で2命令。

 

55行から、57行までは254回繰り返されるので、(2+769+2)✖254=196,342命令。

55行から、57行までの最後は、55行の762命令と56、57行の2命令とリターン命令の2命令で、766命令。

 

従って、全体の命令数は、51行と52行で、2命令と55~57行の196,342命令と55行から、57行までの最後の766命令で、合計197,110命令です。

 

時間は、197,110命令✖1μS=197.110mS=0.19711Sと言う事で、約0.2秒と言う事になります、したがって、LEDは0.2秒点灯し0.2秒消灯するを繰り返すことになります。

 

youtu.be

上のプログラムを実行させてみました。

 

 

 

 

 

PICの動作はいかにして開始されるか。

PICの動作開始は、どの様になっているのか。

 

1.PICが適正な回路で使用され、電源が投入される。

2.電源電圧が決まった値を超えると、リセット信号が出て、PICは動作停止状態になる。

3.その後、決まった時間待機してから、クロック信号をカウント開始。

4.クロックが正常に1024カウント出来たら、0x00から、プログラムを開始。

のようになります。

 

PICのプログラムメモリーは下のようになっています。

f:id:higonohimajin:20210401091458p:plain

PICは0x00から動作を始めますが、上のように、割込み発生時には0x04から処理が開始されるようになっています。

何もしないと、命令は0x00から0x01へ、そして。0x02と順番に実行されるので、0x04から始まる割込み処理も次々と実行してしまいます。

そこで、それを回避するために、0x00にGOTO 0x08(0x04を回避すればよいので0x08でなくとも良い)を書き、ジャンプして避けています。

また、割込み発生時には、0x04から処理が開始されるので、そのままだと、メインルーチンの処理に入ってしまうので、ここでも、GOTO INTERRUPTとしてジャンプし、割込みルーチンに処理が行くようにプログラムします。

 

例; 下のプログラムは、時計用プログラムの一部です。

;********************************      ;以降はコメント文
; Jumping Vector
;********************************

ORG 0                 ;ORG 0 は、次の命令は0x00に置くという命令です、したがって、0x00に、GOTO INIT が置かれます。
GOTO INIT

ORG 4                 ;ORG 4 は、次の命令を0x04に置くという命令です、したがって、0x04に、GOTO INTRPT が置かれます。
GOTO INTRPT


ORG 08H                ;ORG 08Hは、次の命令を0x08に置くという命令です、したがって、0x08に、INIT が置かれますので、0x08のラベルはINITです。

                    (すぐ下からコメント文が始まりますが、コメント文は無視されるので、INITになる。)

                     ここで、ORG 08H 命令が必要なのは、メインルーチンがどのアドレスから始まるか指定するためです、

                     これが決まると、これを基準に他のラベルや命令のアドレスは計算できるのです。
;************************************
; Initialize routine
; PORT A & B Initialize
; PORTA
; RA3,4 :AC SWITCH control output
; RA0,1,2:LCD control output
; PORTB
; lower:SWITCH input
; upper:LCD data output
;
; Timer initilize
;
;************************************

INIT                   ;ここから、メインルーチン
;**** CMCON mode set *****
MOVLW 07H ;degital mode
MOVWF CMCON ;CMCON set

;**** PORT mode set *****
BCF INTCON,GIE ;Interrupt Disable
BSF STATUS,RP0 ;Set page 1


中略

 

;*************************************************
; Timer interrupt routine
; This interrupt occur every 3.125KHz
; So count this interrupt until 3125 times,
; then second count +1.
;*************************************************
INTRPT                  ;ここから、割込みルーチン
;**** save each register *******
MOVWF WR_SV ;save wreg
SWAPF STATUS,W ;save status
MOVWF STA_SV
;**** last pulse check ****
BCF INTCON,T0IF ;int flag reset

 以下省略。

 

のように、プログラムを作ります。

 

 

 

アセンブリ言語の命令、RETLW命令。

ETFLW命令の解説。

 

書式;RETLW  k

    kは、定数データ 0~255(0x00~0xFF)、または、ラベル。

    

動作;CALL命令の次の命令に制御を移すと共に、ワーキングレジスタにkを書き込む。

 

ステータスレジスタへの影響

   C;影響しない

   DC;影響しない

   Z;影響しない

 

f:id:higonohimajin:20210330130415p:plain

 

アセンブリ言語の命令、RETFIE命令。

ETFIE命令の解説。

 

書式;RETFIE

    

動作;ハードウェア割込み発生命令の次の命令に制御を移すと共に、INTCONレジスタのGIEに1を書き込む。

 

ステータスレジスタへの影響

   C;影響しない

   DC;影響しない

   Z;影響しない

 

f:id:higonohimajin:20210330131127p:plain