コンピュータ系実験Ⅲ 「ワンチップマイコンの応用」 第2週目
実験内容 LED点灯回路の制御プログラムの作成 PICのアセンブリ言語でのプログラミング MPLABを用いたノートPC上でのシミュレーション 実験書16ページ、図10の回路を用いて実機動作(課題3のみ) PICのアセンブリ言語でのプログラミング
ここで少し先週の復習
アセンブリ言語とは? こういう感じのものです。 ORG 0 BSF STATUS,RP0 CLRF TRISB BCF STATUS,RP0 CLRF PORTB MOVLW 55H MOVWF PORTB ・・・・
アセンブリ言語とは? プロセッサが解釈可能な言語(機械語)を人間が理解可能な形にした低水準言語 ⇔高水準言語,高級言語 ex)C言語, Java ニーモニックともいう プロセッサごとに定義された命令を用いる プロセッサによって言語仕様が異なる Ex) PICとPentiumでは全く異なる命令 PICでは35種類の命令を使用する(実験書45~49ページ)
機械語とは? プロセッサが解釈可能な言語 ディジタル回路では0と1で表現される 下記の0と1の羅列がプロセッサでのなんらかの動作を示す 11000000000100 00000010001100 11000000010001 00011100001100 ・・・
機械語とアセンブリ言語 機械語を人間が理解可能な形にしたもの 命令を見れば大体の動作の予想がつく 機械語 11000000000100 00000010001100 11000000010001 00011100001100 ・・・ アセンブリ言語 MOVLW 04H MOVWF 0CH MOVLW 11H ADDWF 0CH,W ・・・
用語① アセンブル:アセンブリ言語で書かれたプログラムを機械語に変換すること アセンブラ:アセンブリ言語を機械語に変換するプログラム MOVLW 04H MOVWF 0CH MOVLW 11H ADDWF 0CH,W 機械語 11000000000100 00000010001100 11000000010001 00011100001100 アセンブル
用語② アセンブリ言語の動作を示す部分をオペコード、引数を示す部分をオペランドという ADDWF 0CH,W オペコード オペランド
アセンブリ言語の特徴 メモリやレジスタなど、計算資源を直接扱う プロセッサの構造(レジスタの数や用途など)を知らないとプログラミングできない C言語のような変数は存在しない C言語などのように変数に対してコンパイラがメモリを割り当てたり、計算に使用するレジスタを決めてくれたりはしない プロセッサの構造(レジスタの数や用途など)を知らないとプログラミングできない 一般に高級言語で書いたプログラムよりも高速に動作する
PIC(PIC16F84)上の資源 PIC上でプログラミングする際に使用する資源は以下の通りである(実験書7~8ページ) プログラムメモリ:プログラムを格納するメモリ レジスタファイル:動作設定やデータ格納用メモリ STATUSレジスタ ポートの入出力設定、入出力 汎用レジスタ など Wレジスタ(Working Register): 演算する際に一時保存用に使用するレジスタ
PICの構造 プログラムメモリ (EEPROM) 入出力ポート 演算処理部 メモリ (レジスタ ファイル)
PICの構造 プログラム メモリ プログラム カウンタ 命令 レジスタ レジスタ ファイル MUX 入出力ポート W レジスタ ALU RA0~RA7 W レジスタ ALU RB0~RB7
PICの構造 データバス プログラム メモリ プログラム カウンタ 命令 レジスタ レジスタ ファイル MUX 入出力ポート W レジスタ RA0~RA7 W レジスタ ALU RB0~RB7
PICの構造 プログラムバス プログラム メモリ プログラム カウンタ 命令 レジスタ レジスタ ファイル MUX 入出力ポート RA0~RA7 W レジスタ ALU RB0~RB7
プログラムメモリのアドレスを生成するカウンタ PICの構造 プログラム メモリ プログラム カウンタ 命令 レジスタ レジスタ ファイル MUX 入出力ポート RA0~RA7 Wレジスタ ALU RB0~RB7
PICの構造 プログラムアドレス プログラム メモリ プログラム カウンタ 命令 レジスタ レジスタ ファイル MUX 入出力ポート RA0~RA7 Wレジスタ ALU RB0~RB7
PICの構造 プログラムバスを通って、 命令が読み出される プログラム メモリ プログラム カウンタ 命令 レジスタ レジスタ ファイル MUX 入出力ポート RA0~RA7 Wレジスタ ALU RB0~RB7
PICの構造 命令に従って、 ALUで処理が行われたり、 レジスタファイルの内容が 読み出されたりする プログラム メモリ プログラム カウンタ 命令 レジスタ レジスタ ファイル MUX 入出力ポート RA0~RA7 Wレジスタ ALU RB0~RB7
PICの構造 命令に従って、 ALUで処理が行われたり、 レジスタファイルの内容が 読み出されたりする プログラム メモリ プログラム カウンタ 命令 レジスタ レジスタ ファイル MUX 入出力ポート RA0~RA7 Wレジスタ ALU RB0~RB7
プログラムメモリ プログラム プログラム メモリ カウンタ 0番地 PIC16F84Aではプログラムメモリを1024ワード分搭載 1番地 1000命令程度までのプログラムを書き込み可能 プログラムカウンタで指定された番地の命令が読み出される 0番地 BSF 1番地 CLRF 2番地 BCF 3番地 CLRF 4番地 MOVLW ・・・ ・・・・・・・・・・・・ 1023番地
プログラムメモリ 0 プログラム プログラム メモリ カウンタ 0番地 PIC16F84Aではプログラムメモリを1024ワード分搭載 1番地 1000命令程度までのプログラムを書き込み可能 プログラムカウンタで指定された番地の命令が読み出される 0番地 BSF 0 1番地 CLRF 2番地 BCF 3番地 CLRF 4番地 MOVLW ・・・ ・・・・・・・・・・・・ 1023番地
プログラムメモリ 1 プログラムカウンタの値は自動的に+1され、次の番地を指す プログラム プログラム メモリ カウンタ 0番地 1番地 BSF 1 1番地 CLRF 2番地 BCF 3番地 CLRF 4番地 MOVLW ・・・ ・・・・・・・・・・・・ 1023番地
プログラムメモリ 2 プログラムカウンタの値は自動的に+1され、次の番地を指す プログラム プログラム メモリ カウンタ 0番地 1番地 BSF 2 1番地 CLRF 2番地 BCF 3番地 CLRF 4番地 MOVLW ・・・ ・・・・・・・・・・・・ 1023番地
プログラムメモリ 3 プログラムカウンタの値は自動的に+1され、次の番地を指す プログラム プログラム メモリ カウンタ 0番地 1番地 BSF 3 1番地 CLRF 2番地 BCF 3番地 CLRF 4番地 MOVLW ・・・ ・・・・・・・・・・・・ 1023番地
プログラムメモリ 4 プログラムカウンタの値は自動的に+1され、次の番地を指す ジャンプ命令はプログラムカウンタの値を書き換えることで実現される 0番地 BSF 4 1番地 CLRF 2番地 BCF 3番地 CLRF 4番地 MOVLW ・・・ ・・・・・・・・・・・・ 1023番地
レジスタファイル 0番地 レジスタファイルもプログラムメモリと同様に、アドレスを指定することで、データの読み書きができる 1番地 2番地 読み出し、書き込みのいずれであるかは命令によって決定される 実験書13ページ参照 1番地 2番地 ・・・ ・・・ 0B番地 0C番地 0D番地 ・・・ 4E番地 4F番地
レジスタファイル 0番地から0B番地まではSpecial Function Register(SFR)と呼ばれ、用途が決まっている 0番地 PICの動作設定 ステータス 外部との入出力 1番地 2番地 ・・・ ・・・ 0B番地 0C番地 0D番地 ・・・ 4E番地 4F番地
レジスタファイル 0C番地から4F番地までは汎用レジスタであり、プログラム実行中の一時データなどの保存に使用する 0番地 1番地 2番地 ・・・ ・・・ 0B番地 0C番地 0D番地 ・・・ 4E番地 4F番地
PICでのプログラミング Wレジスタにレジスタファイルの値を読み出す(または直値をロード) その値とレジスタファイルの値(または直値)で演算 ALU:Arithmetic Logic Unit 各種演算をするブロック レジスタ ファイル Wレジスタ ALU
例) 04H 11H 04Hを0CH番地にロードし、その値と11Hを加算する MOVLW 04H MOVWF 0CH MOVLW 11H レジスタ ファイル プログラム MOVLW 04H MOVWF 0CH MOVLW 11H ADDWF 0CH,W 04H Wレジスタ 15H 04H 11H ALU 11H 04H 15H
実験手順 サンプルプログラム1(19ページ)を21ページの操作に従って動かしてみる 先週、追加課題で動かしている人はやらなくてOK サンプルプログラム2(23ページ)を動かし、23ページの表を埋める→ TAのチェック サンプルプログラム2を参考に、課題1を解く→ TAのチェック サンプルプログラム3(26ページ)を動かしてみる サンプルプログラム3を参考に、課題2を解く→ TAのチェック サンプルプログラム4(29ページ)を動かしてみる サンプルプログラム4を参考に、課題3を解く → TAのチェック 課題3を先週作成したボード(16ページ図10)で動かす → TAのチェック
サンプルプログラムについて① サンプルプログラムの最初の辺りの行はPICの動作設定や初期化のコード (最初の3行はファイルの読み込み等) ORG 0 MAIN BSF STATUS,RP0 CLRF TRISB BCF STATUS,RP0 CLRF PORTB ここがプログラムの 0番地であることを示す この3行で PORTBの 入出力を設定 PORTBの初期化
サンプルプログラムについて② プログラム中のTRISBはレジスタファイル中のSFRのTRISBレジスタのこと PORTBの入出力の設定を行う これに関しては翌週解説
サンプルプログラムについて③ プログラム中のPORTBはレジスタファイル中のSFRのPORTBのこと PICのRB0~RB7(実験書5ページ図2参照)に対応する 例)PORTBを出力に設定した状態でPORTBの値を11110000とすると、RB0~RB3には0が出力され、RB4~RB7には1が出力される 今回の回路だと、1が出力されたRB4~RB7に接続されたLEDが点灯する
初期化部分で初出の命令 BSF (Bit Set File register) BCF (Bit Clear File register) CLRF (CLeaR File register)
PICの命令③ ビット操作命令 -BSF BSF (Bit Set File register) ファイルレジスタの指定したビット(0オリジン)を1にする 例) BSF 0CH, 4 0CH番地の値の4ビット目を1にする 0CHに00000000が格納されていたとすると00010000となる 指定可能なビットは0~7
PICの命令③ ビット操作命令 -BCF BCF (Bit Clear File register) ファイルレジスタの指定したビットを0にする 例) BCF 0CH, 4 0CH番地の値の4ビット目を0にする 0CHに11111111が格納されていたとすると11101111となる 指定可能なビットは0~7 BSF, BCF以外にもビット判定(指定したビットが0か1か)をして、分岐する命令も存在する
PICの命令④ 初期化命令 -CLRF CLRF (CLeaR File register) 指定したファイルレジスタの値を0にする 例)CLRF 0CH → 0CH番地の値が00H(00000000)になる CLRF以外にもWレジスタを初期化する命令などが存在する
サンプルプログラムについて④ サンプルプログラム3ではループ(繰り返し)を伴うコードが書かれている LOOP RLF 0CH, F DECFSZ 0DH GOTO LOOP MOVF 0CH, W
サンプルプログラム3で初出の命令 RLF (Rotate Left File register through carry) DECFSZ (DECrement File register, Skip of Zero) GOTO
PICの命令⑥ シフト命令 RLF (Rotate Left File register through carry) ファイルレジスタの内容を1bit左シフトする 7bit目はCarry(桁上がり)にシフトされる Carryの実体はSTATUSレジスタのCarryビット 当然、逆方向のシフト命令も存在する 7 6 5 4 3 2 1 0 C 0 1 1 0
PICの命令⑤ 条件分岐命令 DECFSZ (DECrement File register, Skip of Zero) 指定したファイルレジスタの値から1を引いて(デクリメント)、その結果が0ならば次の命令をスキップする(1つ後の命令を実行する) 0でないならば、次の命令を実行する DECFSZ以外にもビット判定命令などで同様の動作をする命令も存在する
PICの命令⑦ ジャンプ命令 GOTO 指定した番地(プログラムアドレス)に無条件分岐する 例) GOTO LOOP 分岐できる範囲は000H~7FFHの間
DECFSZの例 0 1 2 3 0DH番地に3が格納されているとする 下図では矢印で示した命令を実行しているものとする 0DH番地の値 LOOP RLF 0CH, F DECFSZ 0DH GOTO LOOP MOVF 0CH, W 0 1 2 3
サンプルプログラムについて⑤ サンプルプログラム4の最初 GPR_1 EQU 0CH GPR_2 EQU 0DH GPR_3 EQU 0EH は、“0CHという値にGPR_1という別名を付けますよ”という意味(GPR_2, GPR_3も同様) 上記の場合、以下のコードは同じ意味を持つ MOVWF GPR_1 MOVWF 0CH
サンプルプログラム4で初出の命令 CALL (CALL subroutine) COMF (COMplement File register) NOP (No OPeration) RETURN (RETURN from subroutine)
PICの命令⑧ サブルーチンコール CALL (CALL subroutine) 指定したサブルーチンにジャンプする GOTO命令と異なる点はRETURN命令と組み合わせることで、サブルーチンの呼び元に戻ることができる点 例) CALL TIMER → TIMERというサブルーチンに飛ぶ このTIMERはラベルであるが、直接サブルーチンのプログラムアドレスを数値で指定することも可能 例) CALL 0FFH → 0FFH番地から始まるサブルーチンに飛ぶ
PICの命令⑧ サブルーチンコール RETURN (RETURN from subroutine) CALLで呼び出されたサブルーチンから、CALLの呼び出し元に戻る(CALL命令の次の命令に飛ぶ)
PICの命令⑨ ビット反転命令 COMF (COMplement File register) 正確にはFile registerの値の(1の)補数(Complement)をとる命令 実行すると、指定したFile registerの値のビットが全て反転する 例) 0CH番地に11110000が格納されているとする COMF 0CH とすると、0CH番地の値は00001111になる
PICの命令⑩ 何もしない命令 NOP (No OPeration) その名の通り、何もしない命令 今回のように時間を計る場合など、用途は様々
サンプルプログラムについて⑥ サンプルプログラム4の流れを以下に示す メインルーチン タイマサブルーチン MAIN ・・・ ;===================== MOVLW 55H LOOP MOVWF PORTB CALL TIMER COMF PORTB, W ・・・・ タイマサブルーチン ・・・ TIMER RETURN
: ADD W and F(Wレジスタとファイルレジスタの加算) 実験書45~49ページの見方 命令とその意味 ADDWF : ADD W and F(Wレジスタとファイルレジスタの加算) アセンブリ言語で 記述する際の書式 書式 : ADDWF f, d PIC内部の動作 動作 : W ← W + f (d = 0(W)) f ← W + f (d = 1(F)) W : Wレジスタ f : ファイルレジスタ(7bit:00h~7Fh) d : 結果の格納先(0(W) or 1(F)) この命令を実行したことによって 影響を受けるステータスレジスタのビット 影響するフラグ : C, DC, Z マシン語 : 00 0111 dfff ffff 例 : MOVLW 44H ; Wレジスタに44hを書き込む ・・・・ マシン語に変換した際のビット列 プログラム例
プログラミング時の注意事項 Wレジスタの値に入っている値を把握する アルファベットで始まるアドレス、値には0を付ける AH → 0AH CH → 0CH 扱っている値がアドレスなのか数値なのか認識すること アセンブル時にエラーが出た場合は、TAを呼ぶ前にエラーコードを読み、自分で原因追求をしてみること(実験書25ページ) プログラム中にコメント以外で全角文字(全角スペースも含む)を入れないこと
作業中の注意 実験中は立ち歩かないこと 立ち歩く用件がある場合はTAに伝えてから
PICライタに関して PICライタを取り外すときは必ずPICライタの電源を落としてからにすること Windowsがブルースクリーンになって、落ちることがあります MPLABも落としておくと、より安全です