第2回 PICマイコンのソフトウェア,内蔵モジュール

■2.1 命令の概要
◆2.1.1 アセンブラ命令(Instruction)
 本実習では,マイコンが理解できる唯一の言語である機械語(machine language)の命令に一対一で対応した言語であるアセンブリ言語(assembly language)を用いてプログラムを開発する

 PIC16F84A の動作を制御するアセンブラ命令は 35 種類であり,命令機能により 8 種類に分類できる(命令アーキテクチャにより 5 種類に分類できる).
 アセンブラ命令の詳細に関しては,別ページの「アセンブラ命令」を参照すること.

 なお,説明文中の“実行サイクル”とは,命令の実行に必要とされる時間を“単位時間”の倍数で表している.単位時間は“命令クロック周波数”の逆数であり,命令クロック周波数は PIC に接続した発振器クロックの 1/4 の周波数である.
 例えば,10 MHz の発振器を接続した場合,命令クロック周波数は 2.5 MHz となり,単位時間は 0.4 us となる.

▼命令機能による分類
移動,転送命令 指定したレジスタへデータをコピーする命令.
加減算命令 最も基本的な演算である足し算と引き算をする命令.
論理演算命令 論理積,論理和,排他的論理和および補数の演算を行う命令.
カウントアップダウン命令 指定したレジスタの値を +1(カウントアップ),もしくは -1(カウントダウン)する命令.
ビット操作命令 指定したレジスタの特定のビットを 0 や 1 にする命令.
巡回シフト命令 8 bit のデータをビット単位でシフトする命令,キャリービットも含めてシフトする.
ジャンプ命令 プログラムの流れを強制的に変更する命令.
その他の命令 特殊な動作をする命令.

▼命令構造による分類
バイト処理命令 バイト単位の処理を行う命令.
ビット処理命令 ビット単位の処理を行う命令.
リテラル命令 命令の中に書かれた定数を使った処理を行う命令.
ジャンプ命令 プログラムの流れを強制的に変更する命令.
その他の命令 特殊な動作をする命令.

◆2.1.2 アセンブラ疑似命令(Directive)
 PIC 用アセンブラである MPASM には,PIC の動作を記述する命令以外に,アセンブラの処理動作を制御するために,アセンブラ自身が使用する命令がある.
 これらの命令はアセンブラ疑似命令と呼ばれ,MPASM には 61 類が用意されており,その機能により 5 種類に分類できる.

 アセンブラ疑似命令の詳細に関しては,別ページの「アセンブラ疑似命令」を参照すること.

制御命令 アセンブルに各種の条件を指定するための命令
データ命令 メモリ配置やシンボル名の定義をして参照がしやすいようにする命令
リスト命令 タイトル付けや改ページ指示等,アセンブルリストの出力内容を指示する命令
マクロ命令 マクロ命令を定義するための命令
オブジェクト
ファイル命令
リロケータブルオブジェクトを出力する際に使用する命令
 
■2.2 命令フォーマット
 PIC のアセンブラ・プログラム・ソースコード(命令もしくはコメント)は,下記の基本フォーマットに従って記述する.
 なお,各コードは 1 行で記述しなければならない.

[ラベル] (空白) [ニーモニック] (空白) [オペランド] (空白) [;コメント]
例)  LOOP ADDLW 15 ;15を加算

ラベル
Label
ソースコードの各行に自分で自由につける目印用の名前
 各行の先頭から始まっていなければならない.また,含まれる文字は,アルファベットかアンダーバー "_" で始まる英数字でなければならない.文字数は 32 文字以下で,通常,大文字と小文字の区別がある.
ニーモニック
Mnemonic
アセンブラ命令の記号
 行の先頭から1個以上のスペースが無ければならない.ラベルがある場合は,ラベルの次に 1 個以上のスペースかコロン「:」 が必要.
オペランド
Operand
命令の対象,アドレス等
 ニーモニックの次に 1 個以上のスペースかタブで分離して記入する.また,複数のオペランドが必要な場合には「,」で分離して記入する.
コメント
Comment
メモ欄
 セミコロン「;」に続く文節は全てコメントとして扱われる.コメントは行のどこから始まっても良く,日本語表記も可能.アセンブル時には無視されて何も出力されない.なお,ソースコードの各行に書ける文字数は最大で 255 文字である.

◆2.2.1 オペランドのパラメータ
 オペランドには以下の 4 種類のパラメータがある.

レジスタファイルアドレス
register file address
ファイルレジスタを指定する(記号:f )
 7 bit の幅があるため,00 から 7F までの最大 128個のレジスタが指定できる
 ただし,実際に存在するレジスタは PIC の種類によって異なる.PIC16F84 の場合は,00〜4F まで(00〜0B:SFR,0C〜4F:汎用レジスタ).
 レジスタアドレスを指定する場合,アドレスの数値を直接指定すると間違いも多くわかりにくくなるため,通常は,EQU 命令等でラベルを設定してラベルで指定する

COUNTER EQU     0DH             ;ラベル設定定義
;
        INCF    COUNTER,F       ;ラベル使用
格納先指定
destination select
dest

命令を実行した結果を格納するかどうかを 0 か 1 で指定する(記号:d )
 ただし,標準インクルードファイルWF が定義されているため,通常はそれらを使用して記述する.
W d=0 Wreg に結果を格納する
F d=1 f で指定しているレジスタに格納する

        DECF    COUNTER,W       ;COUNTER-1をWregに格納
ビットアドレス
bit address
ビット位置を指定する3bitのアドレス(記号:b )
 直接数値を使って指定する方法と,別に設定されたラベルを使って指定する方法の 2 種類がある.

        BSF     PORTA,3         ;ポートAの4ビット目
;
RA3     EQU     3       ;ラベル設定定義
        BCF     PORTA,RA3       ;ラベルの使用
リテラル
literal
直接固定の値を指定する(記号:k )
 Literal とは,"文字通りの"や"そのまま"という意味.
 1 byte(8 bit)の幅があるため,数値なら 0〜255,文字なら ASCII コードが使用できる.

        ADDLW   15      ;15を加算
;
        MOVLW   'C'     ;ASCII文字コード(3C)をWregへ

◆2.2.2 数値データおよび演算記号書式
▼数値データの書式
種 類 書 式 使用例
10進数 D'<digits>' D'100'
16進数 H'<hex_digits>',または 0x<hex_digits> H'A8,または 0xA8
8進数 O'<octal_digits> O'567'
2進数 B'<binary_digits> B'011001'
ASCII A'<characters>',または '<characters>' A'ABC' または 'ABC'

▼演算記号の書式
記 号 意 味 使用例
$ 現在のプログラムカウンタの値 GOTO $+3
現在のプログラムカウンタから 3 つ先のアドレスにジャンプする.
high アドレスの上位バイトを返す MOVLW high TABLE
TABLE番地の上位バイト(5 bit)をWレジスタに格納する.
low アドレスの下位バイトを返す MOVLW low TABLE
TABLE 番地の下位バイト(8 bit)をWレジスタに格納する.
( ) 優先演算記号 (length+1)*256
* かけ算 a*b
/ わり算 a/b
+ 足し算 a+b
- 引き算 a-b
<< 指定回数左シフト val=flags<<1
>> 指定回数右シフト val=flags>>1
& ビットのAND flags=flags&ERRROR_BIT
&& 論理AND if (len==512)&&(b==c)
| ビットのOR flags=flags|ERRROR_BIT
|| 論理OR if (len==512)||(b==c)
! 論理否定 if (a!=b)
>= 大きいか等しい if a>=b
> 大きい if a>b
<= 小さいか等しい if a<=b
< 小さい if a<b
== 等しい if (a==b)
!= 等しくない if (a!=b)

◆2.2.3 標準インクルードファイル
 PIC16F84A のレジスタファイル中の 00〜 0C 番地はシステムで使用する SFR であるが,それらのラベル定義は標準インクルードファイルとして用意されている.
 したがって,プログラム中で SFR を指定する場合は,アセンブラ疑似命令「#INCLUDE」により標準インクルードファイルをプログラムに組み込み,その中で定義されてるラベルを使用することで,プログラム毎に個別に定義する必要がなくなる.
 なお,標準インクルードファイルは Microchip Technology社から各 PIC 毎に専用のファイルが提供されている.PIC16F84A 用の標準インクルードファイルは,P16F84A.inc である.

       #INCLUDE "P16F84A.INC"

 PIC16F84A 用の標準インクルードファイル(P16F84A.inc)の内容を以下に示す.

        LIST
; P16F84A.INC  Standard Header File, Version 2.00    Microchip Technology, Inc.
        NOLIST

; This header file defines configurations, registers, and other useful bits of
; information for the PIC16F84 microcontroller.  These names are taken to match
; the data sheets as closely as possible.

; Note that the processor must be selected before this file is
; included.  The processor may be selected the following ways:

;       1. Command line switch:
;               C:\ MPASM MYFILE.ASM /PIC16F84A
;       2. LIST directive in the source file
;               LIST   P=PIC16F84A
;       3. Processor Type entry in the MPASM full-screen interface
;==========================================================================
;
;       Revision History
;
;==========================================================================

;Rev:   Date:    Reason:
;1.00   2/15/99  Initial Release

;==========================================================================
;
;       Verify Processor
;
;==========================================================================
        IFNDEF __16F84A
           MESSG "Processor-header file mismatch.  Verify selected processor."
        ENDIF

;==========================================================================
;
;       Register Definitions
;
;==========================================================================

W                            EQU     H'0000'
F                            EQU     H'0001'

;----- Register Files------------------------------------------------------

INDF                         EQU     H'0000'
TMR0                         EQU     H'0001'
PCL                          EQU     H'0002'
STATUS                       EQU     H'0003'
FSR                          EQU     H'0004'
PORTA                        EQU     H'0005'
PORTB                        EQU     H'0006'
EEDATA                       EQU     H'0008'
EEADR                        EQU     H'0009'
PCLATH                       EQU     H'000A'
INTCON                       EQU     H'000B'

OPTION_REG                   EQU     H'0081'
TRISA                        EQU     H'0085'
TRISB                        EQU     H'0086'
EECON1                       EQU     H'0088'
EECON2                       EQU     H'0089'

;----- STATUS Bits --------------------------------------------------------

IRP                          EQU     H'0007'
RP1                          EQU     H'0006'
RP0                          EQU     H'0005'
NOT_TO                       EQU     H'0004'
NOT_PD                       EQU     H'0003'
Z                            EQU     H'0002'
DC                           EQU     H'0001'
C                            EQU     H'0000'

;----- INTCON Bits --------------------------------------------------------

GIE                          EQU     H'0007'
EEIE                         EQU     H'0006'
T0IE                         EQU     H'0005'
INTE                         EQU     H'0004'
RBIE                         EQU     H'0003'
T0IF                         EQU     H'0002'
INTF                         EQU     H'0001'
RBIF                         EQU     H'0000'

;----- OPTION_REG Bits ----------------------------------------------------

NOT_RBPU                     EQU     H'0007'
INTEDG                       EQU     H'0006'
T0CS                         EQU     H'0005'
T0SE                         EQU     H'0004'
PSA                          EQU     H'0003'
PS2                          EQU     H'0002'
PS1                          EQU     H'0001'
PS0                          EQU     H'0000'

;----- EECON1 Bits --------------------------------------------------------

EEIF                         EQU     H'0004'
WRERR                        EQU     H'0003'
WREN                         EQU     H'0002'
WR                           EQU     H'0001'
RD                           EQU     H'0000'

;==========================================================================
;
;       RAM Definition
;
;==========================================================================

        __MAXRAM H'CF'
        __BADRAM H'07', H'50'-H'7F', H'87'

;==========================================================================
;
;       Configuration Bits
;
;==========================================================================

_CP_ON                       EQU     H'000F'
_CP_OFF                      EQU     H'3FFF'
_PWRTE_ON                    EQU     H'3FF7'
_PWRTE_OFF                   EQU     H'3FFF'
_WDT_ON                      EQU     H'3FFF'
_WDT_OFF                     EQU     H'3FFB'
_LP_OSC                      EQU     H'3FFC'
_XT_OSC                      EQU     H'3FFD'
_HS_OSC                      EQU     H'3FFE'
_RC_OSC                      EQU     H'3FFF'
        LIST
 
■2.3 入出力モジュール(I/O port module)
 入出力モジュールは,I/Oポートと呼ばれるハードウェア・ブロックによって構成され,PIC マイコンと外部デバイスとのデータ・インターフェイスを行うモジュールである.
 PIC16F84A  にはPORTA(5 bit) と PORTB(8 bit) の2つの双方向ポートが用意されており,それぞれ 1 bit 毎に入出力をプログラミングできる.

ポート名 ピン名 バッファタイプ 備 考
PORTA RA0-RA3 TTL
RA4/T0CKI ST オープンドレイン
PORTB RB0/INT TTL/ST 割り込みピン兼用
RB1-RB3 TTL
RB4-RB5 TTL 割り込みピン兼用
RB6-RB7 TTL/ST 割り込みおよび
プログラムピン兼用

◆2.3.1 入出力モードの設定
▼PORTAの設定
 SFRTRISA レジスタにより,PORTA の入出力モードを設定できる.
 TRISA は 1 byte = 8 bit のレジスタであり,各ビットに 1 か 0 をセットして対応するポートの入出力を設定する.ただし,実際は RA0-RA4 の下位 5 bit のみが有効であり,RA5-RA7 の上位 3 ビットは無効である.
 なお,電源 ON やリセット後は,TRISA レジスタは全ビットが 1 に初期化されるため,全ポートが入力設定となる

1: 入力ポート
0: 出力ポート



▼PORTBの設定
 PORTA 同様,SFRTRISB レジスタにより,PORTB の入出力モードを設定できる.
 TRISB は 1 byte = 8 bit のレジスタであり,各ビットに 1 か 0 をセットして対応するポートの入出力を設定する.
 なお,電源 ON やリセット後は,TRISB レジスタは全ビットが 1 に初期化されるため,全ポートが入力設定となる

1: 入力ポート
0: 出力ポート



▼入出力モードの設定例
 TRISA および TRISB は,Bank1SFR である.
 電源 ON やリセット後は Bank0 になっているため,Bank を切り替えて設定し,設定終了後には,Bank0 に戻す必要がある.

        BSF     STATUS,RP0      ;Bank0->Bank1
        CLRF    TRISA           ;PORTA all Output
        MOVLW   00FH            ;[00001111]
        MOVWF   TRISB           ;PORTB RB7:4 Output, RB3:0 Input
        BCF     STATUS,RP0      ;Bank1->Bank0

◆2.3.2 入出力の実行
▼入力
 各ポートのピンから信号を入力する場合は,MOVF 命令等の転送命令を使用する.MOVF 命令はポート全体のデータ(1 byte)を入力するが,任意の 1 bit の状態だけを知りたい場合は,BTFSC 命令やBTFSS 命令により各ピンの論理状態をテストすることができる.

        MOVF    PORTB,W         ;PORTB->Wreg
        MOVWF   DATA            ;Wreg->DATA
;
        BTFSC   PORTB,0         ;test RB0 if Low Skip

▼出力
 各ポートのピンに信号を出力する場合は,MOVWF 命令等の転送命令を使用する.MOVWF 命令ではポート全体にデータを出力する(1 byte)が,任意の 1 bit の状態だけを変更して出力したい場合は,BCF 命令やBSF 命令等により出力する.

        MOVLW   0CCH            ;[10101010]
        MOVWF   PORTB           ;PORTB 8bit Output
;
        BSF     PORTB,4         ;RB4 High
        BCF     PORTB,5         ;RB5 Low
 
■2.4 割り込み制御モジュール(Interrupt service module)
 割り込み制御モジュールは割り込み処理を制御するためのモジュールである.
 割り込み処理とは,その名の通り,通常のプログラムの実行中に割込んで別の処理をするというものである.
 通常は繰り返しで何か実行していて,ある事象が発生したら直ちにその処理をさせたいというような場合や,インターバルタイマのように一定のタイミングで実行したい処理を実行する場合に使用する.

 PIC16F84A には,以下の 4 種類の割り込み要因が実装されている.

 
・RB0/INT 割り込み(RB0/INT ピン)
・TMR0 オーバフロー割り込み
・PORTB 変化割り込み(RB7-RB4 ピン)
・EEPROM 書き込み完了割り込み

◆2.4.1 割り込みコントロールレジスタ
 割り込みの制御は,INTCON レジスタ(割り込みコントロールレジスタ)により行う.INTCON レジスタは,個別の割り込み要求フラグビットを記憶している.
 グローバル割り込みイネーブルビット GIE は,全ての割り込みの発生を一括してコントロールできる.なお,割り込み処理からの復帰命令である RETFIE 命令実行後は,割り込みを発生許可するためGIE ビットを1にする.

R 読み出し可能ビット
W 書き込み可能ビット
S セット可能ビット
U 使用しないビット.0 として読み出し
-n リセットでの値
GIE グローバル割り込みイネーブルビット
 1:禁止されていない全ての割り込み発生を許可する.
 0:全ての割り込み発生を禁止する.
EEIE EEPROM 書き込み完了割り込みイネーブルビット
 1:EEPROM 書き込み完了割り込み発生を許可する.
 0:EEPROM 書き込み完了割り込み発生を禁止する.
T0IE タイマ0 オーバーフロー割り込みイネーブルビット
 1:タイマ0 割り込み発生を許可する.
 0:タイマ0 割り込み発生を禁止する.
INTE RB0/INT 割り込みイネーブルビット
 1:RB0/INT 割り込み発生を許可する.
 0:RB0/INT 割り込み発生を禁止する.
RBIE RB ポート変化割り込みイネーブルビット
 1:RB ポート変化割り込み発生を許可する.
 0:RB ポート変化割り込み発生を禁止する.
T0IF タイマ0 オーバーフロー割り込みフラグビット
 1:タイマ0 がオーバーフローした.
  (ソフトウェアでクリアする必要がある)
 0:タイマ0 がオーバーフローしていない.
INTF RB0/INT 割り込みフラグビット
 1:RB0/INT 割り込みが発生した.
  (ソフトウェアでクリアする必要がある)
 0:RB0/INT 割り込みが発生していない.
RBIF RB ポート変更割り込みフラグビット
 1:少なくとも 1 つ以上の RB7-RB4 ピンの状態が変化した.
  (ソフトウェアでクリアが必要)
 0:RB7-RB4 ピンは状態が変化していない.

◆2.4.2 割り込みシーケンス
 割込みの設定,および割り込みが発生した時のPICの動作,および割り込み処理ルーチン内での処理は下記の様なシーケンス(順序)で実行される.

<Step 1>
個別割り込み許可
割込みを発生させたい割り込み要因に対応した各割り込みイネーブルビット(INTCON レジスタの EEIET0IEINTERBIE)に BSF 命令等で 1 を設定する.
<Step 2>
全割り込み許可
割込みを許可するよう,INTCON レジスタの GIE ビットに BSF 命令等で 1 をセットする.
<Step 3>
割り込み発生
別の割込みを要因による多重割り込みが発生しないよう,INTCON レジスタの GIE ビットがクリアされる.
実行中の命令の次の命令のアドレス(リターンアドレス)がスタックに保存される.
強制的に PC(プログラムカウンタ)に 0004H がセットされ,4 番地にジャンプする.
したがって,割り込み処置ルーチンを4番地から記述するか,もしくは割り込み処理ルーチンへのジャンプ命令を 4 番地に記述する必要がある
<Step 4>
割り込み処理ルーチン
 (実行開始部分)
必要に応じて直前のレジスタ値を保存する.
<Step 5>
割り込み処理ルーチン
 (割込み要因調査)
INTCON レジスタの割込みフラグを調べ,フラグが 1 の要因の処理を実行する.
複数の割込みフラグが《1》になっている場合は全ての関連割込み処理を実行する.
なお,1 となっていたフラグは BCF 命令等で 0 にクリアしておく(クリアしない場合,全割り込み許可をしたとたんに再び割り込み要求が発生し,割込み要求の無限ループとなる).
<Step 6>
割り込み処理ルーチン
 (実行完了部分)
レジスタを保存していた場合は,レジスタを復帰させる.
通常処理へ復帰するため,最後に RETFIE 命令を実行する.
<Step 7>
通常処理へ復帰
RETFIE 命令の実行により,スタックに保存されていたリターンアドレスにジャンプして通常処理ルーチンに復帰する.
同時に次の割込みを許可するため INTCON レジスタの GIE ビットが自動的にび 1 にセットされる.

◆2.4.3 各割り込みの設定概要
▼RB0/INT 割り込み
 INT/RB0 ポートの入力信号の論理が変化したときに(立ち上がりまたは立ち下がりのエッジ)発生する.
 パルス信号のパルス数をカウントする場合等に利用する.

<Step 1>
初期設定
OPTION レジスタの INTEDG ビットにより,割り込みが発生する条件(立ち上がり/立ち下がりエッジ)を指定する.
<Step 2>
割り込み許可
INTCON レジスタの INTE  ビットを 1 に設定し,GIE ビットを 1 にして割込み待ちする.
<Step 3>
割り込み発生
割込み処理ルーチンの先頭部分で,INTCON レジスタの INTF フラグをクリアして次の割込みに備える.

▼TMR0 オーバフロー割り込み
 クロックによりカウントアップする TMR0 レジスタが FFH から 00H になる時に発生する.
 一定間隔ごとに割込ませるインターバルタイマや正確なタイミング用のワンショットタイマとして使用する.

<Step 1>
初期設定
TMR0 レジスタにカウンタの初期値を格納する(00〜FF,大きい値ほど早く割り込みが発生する).
必要であればプリスケーラTMR0 レジスタへ供給するクロックを分周する)の設定をする.
<Step 2>
割り込み許可
INTCON レジスタの T0IE ビット を 1 に設定し,GIE ビット1 にして割込み待ちする.
<Step 3>
割り込み発生
割込み処理ルーチンの先頭部分で,INTCON レジスタの T0IF フラグのクリア,および TMR0 レジスタにカウンタ初期値を再格納して次の割込みに備える.

▼PORTB 変化割り込み
 RB4:RB7 のいずれかの入力に論理の変化があった場合に発生する.
 スイッチを接続してその状態変化を即座に読みとる場合等に利用する.

<Step 1>
初期設定
TRISB レジスタにより PORTB の対象ポート(RB4:RB7)を入力ポートに設定する
<Step 2>
割り込み許可
INTCON レジスタの RBIE ビットを 1 に設定し,GIE ビットを 1 にして割込み待ちする.
<Step 3>
割り込み発生
割込み処理ルーチンの先頭部分で,INTCON レジスタの RBIF フラグをクリアして次の割込みに備える.

▼EEPROM 書き込み完了割り込み
 EEPROM への書き込みが完了したときに発生する.
 EEPROM からのデータ読み出しは非常に高速であるため,プログラムで直接読み出しても問題無いが,書き込みは約10 msecを必要とするため,待ち時間が無駄になる(20 MHz で動作している場合,10 ms は 50000 サイクルの待ち時間となる).
 そこで書き込みをスタートさせたら書き込み完了の割込み待ちとすることで,その間に他の処理を実行することができる.

<Step 1>
初期設定
なし
<Step 2>
割り込み許可
INTCON レジスタの EEIE ビットを 1 に設定し,GIE ビットを 1 にして割込み待ちする.
<Step 3>
割り込み発生
割込み処理ルーチンの先頭部分で,INTCON レジスタの EEIF フラグをクリアして次の割込みに備える.

◆2.4.4 割り込み処理実行時の注意点
 割り込み中は,プログラムカウンタリターンアドレススタックに保存されるが,レジスタは保存されない
 割り込みは通常処理ルーチン実行中に任意の場所で発生するため,何らかの計算途中に発生した場合等,割り込み処理前後で WregSTATUS レジスタの値が変化すると予期しない動作を生じる場合がある.
 この問題は,計算に使用するレジスタ(Wreg,STATUS)を割り込み処理の初段で保存し,かつ割り込み処理の最後で復帰させることで解決できる.

 下記の例は,Wreg および STATUS レジスタの値の保存と復帰を含む割り込み処理ルーチンである.
 W_temp および STATUS_temp は,それぞれ Wreg および  STATUS レジスタの割り込み中の保存場所である.Z フラグが影響を受けないように,データの格納にはSWAPF 命令を使用している.
 なお,FSR レジスタやPCLATCH レジスタ等も保存が必要な場合がある.

INTERRUPT
PUSH    MOVWF   W_temp          ;Copy Wreg to W_TEMP
        SWAPF   STATUS,W        ;Swap STATUS to be saved into Wreg
        MOVWF   STATUS_temp     ;Save STATUS to STATUS_TEMP
;
;Interrupt Service Routine
;
POP     SWAPF   STATUS_temp,W   ;Swap nibbles in STATUS_TEMP and place result into W
        MOVWF   STATUS          ;Move Wreg into STATUS
        SWAPF   W_temp,F        ;Swap nibbles in W_TEMP and place result in W_TEMP
        SWAPF   W_temp,W        ;Swap nibbles in W_TEMP and place result into Wreg
 
■2.5 タイマ0 モジュール(TIMER0 module)
 TIMER0 モジュールは,基本的にはパルスカウンタであり,インターバルタイマ等に利用される.
 TIMER0 モジュールには次の機能が実装されている.

 
・8 bit タイマ/カウンタ
・読み出し/書き込みが可能
・ソフトウェアプログラマブル 8 ビットプリスケーラ
・内部または外部クロック選択可能
・FFH から 00H カウント時にオーバフロー割込みを発生
・外部クロック用エッジ選択可能

◆2.5.1 アーキテクチャ
 タイマ0 は,図に示す構成となっており,TOSETOCSPSxPSA という制御信号で制御される 8 bit カウンタである.
 TOSE,TOCS,PSx,PSA は OPTION レジスタで設定でき,一旦設定した内容はリセットされるまで有効である.


TMR0
タイマ0レジスタ
8 bit カウンタであり,単体でカウントできるのは最大で 256 である(プリスケーラと組み合わせると 16 bit カウンタとして動作できる).
カウンタオーバーフロー(FFH から 00H へのインクリメント時)で,割り込みコントロールレジスタである INTCON レジスタの T0IF(タイマ0 オーバーフロー割り込みフラグビット)を 1 にセットする.
ソフトウェアによる読み出し/書き込みが可能であるため,任意の値(タイマ0 カウンタ初期値)からカウントをスタートさせることができる.
ただし,TMR0 レジスタに書き込みをした場合,それに続 く 2 サイクルはインクリメントされないため,精密さを求める場合はその分の調整を初期値等で行う必要がある.
なお,タイマ0 モジュールに何らかの設定をすると 0 にクリアされる.
programmable prescaler
プリスケーラ
TMR0 レジスタの前段に位置する 8 bit カウンタ.TMR0 レジスタと組み合わせて 16 bit カウンタを構成できる.
ソフトウェアによるカウンタ値の読み出し/書き込みはできない.
TMR0 レジスタ同様,タイマ0 モジュールに何らかの設定をすると 0 にクリアされる
FOSC/4
命令クロック周波数
タイマ0 モジュール(TMR0 レジスタおよびプリスケーラ)に加えられるパルス信号.
周波数は命令クロックに同期しており,発振器クロックの 1/4 である.
T0CS
クロックソース選択
タイマ0 モジュールへの入力信号を内部命令クロックと外部信号(RA4/T0CKI ポート)から選択する.
T0SE
クロックソースエッジ選択
外部信号入力時に入力信号の有効エッジ(立ち上がり/立ち下がり)を設定する.
PSA
プリスケーラ選択
プリスケーラを有効にするかどうかを設定する.
PS0-PS2
プリスケーラレート選択
プリスケーラのレートを設定する 3 bit の信号であり,8 種類のレート(1:2,1:4,1:8,1:16,1:32,1:64,1:128,1:256)を設定できる. 

▼プリスケーラ
 プリスケーラを使用すると,TMR0 レジスタへの入力信号周波数はプリスケーラレートで割ったものとできる.
 したがって,TMR0 レジスタ単独ではカウントできない 257 以上のパルス数のカウントも可能となる.

 例えば,10000個のパルスをカウントする場合は,プリスケーラレートを 1:256 と設定することにより,TMR0 レジスタへの入力パルス数は10000/256=39.0625,約 39 個となり十分カウントできる範囲となる(0.0625 個は誤差となるので,精密さを求める場合は何らかの調節を別途行う必要がある).

 なお,このプリスケーラは,ウォッチドッグタイマ用のポストスケーラとしても使用できるが,タイマ0 モジュールとウォッチドッグタイマの両方に使用することはできない.

 以下に PSA と PS0-PS2 を使用したプリスケーラレートの設定法と,プリスケーラを使用した場合のカウント誤差を示す.
レート OPTION_REG 最大カウント値 分解能
PSA PS2 PS1 PS0
1:1 1 - - - 256 1/1
1:2 0 0 0 0 512 1/2
1:4 0 0 0 1 1024 1/4
1:8 0 0 1 0 2048 1/8
1:16 0 0 1 1 4096 1/16
1:32 0 1 0 0 8192 1/36
1:64 0 1 0 1 16384 1/64
1:128 0 1 1 0 32768 1/128
1:256 0 1 1 1 65536 1/256

▼外部クロックの使用法
 RA4/T0CKI ポートの外部クロックをタイマ0 モジュールの入力信号として使用する場合,その外部クロック信号には内部位相クロック(TOSC:発振器クロック)との同期等の問題から以下の特性が求められる.

プリスケーラを
使用しない場合
RA4/T0CKI ポートに入力される外部クロック信号の High および Low の各ロジックは,最低 2 TOSC の間は同じ状態を維持する必要がある.
プリスケーラを
使用する場合
RA4/T0CKI ポートに入力される外部クロック信号の High および Low の各ロジックは,最低 4TOSC をプリスケーラ値で割った周期かつ 10 ns 以上の間は同じ状態を維持する必要がある.

◆2.5.2 インターバルタイマ
 データのサンプリング等,一定時間間隔で行う必要がある処理は比較的多い.
 そのような場合には,タイマ0 モジュールを利用してインターバルタイマを構成して利用できる.
 以下に構成方法を示す.

▼TMR0 レジスタの初期値の設計
 任意のインターバル時間を発生するタイマを設定するためには,インターバルでカウントする命令クロック数(=インターバル時間/命令クロック周期)を計算して,TMR0 レジスタの初期値やプリスケーラレートを適切に決定する必要がある.

 例として,発振器の周波数が 10 MHz である場合に,内部命令クロックを用いて 20 ms のインターバルで動作するタイマにおける TMR0 レジスタの初期値およびプリスケーラの設計法を以下に示す.

<Step 1>
クロック周期計算
タイマ0 モジュールに入力するクロックの周期を求める.
 クロック周期=1/(発振器クロック周波数/4)=1/(10 MHz/4)=0.4 us
<Step 2>
パルス数計算
インターバル中にカウントするパルス数を求める.
 パルス数=インターバル時間/クロック周期=20 ms/0.4 us=50000 パルス 
<Step 3>
プリスケーラレート決定
パルス数からプリスケーラレートを決定する.
 レート=パルス数/TMR0 レジスタの最大値=50000/256≒195
 195 以上で一番近いレートである 1:256 のプリスケーラを設定する.
<Step 4>
TMR0レジスタ決定
TMR0 レジスタの初期値を決定する.
 TMR0 レジスタがカウントするパルス数が 195(C3H)の場合,TMR0 レジスタがアップカウンタであり FFH から 00H へのインクリメント時に割り込みを発生することから,その初期値は 00H(100H)−C3H=3DH となる.

▼初期値の設定
 求めた初期値は以下のように設定する.

        BSF     STATUS,RP0      ;set Bank1
        MOVLW   087H            ;prescale 256
        MOVWF   OPTION_REG
        BCF     STATUS,RP0      ;set Bank0
;
        MOVLW   03DH            ;TIMER0 counter preset
        MOVWF   TMR0

▼インターバルタイマの再設定
 インターバルタイマとして動作させるためには,タイマ割り込みが発生したときに,割り込み処理ルーチン内で初期値をTMR0 レジスタに再設定する必要がある.

;- TIMER0 interrupt operation -----------------
ISR_TIM0
        BCF     INTCON,T0IF     ;interrupu flag clear
        MOVLW   03DH            ;TIMER0 counter preset
        MOVWF   TMR0

◆2.5.3 カウンタ
 T0CS ビットを 1 に設定することで,タイマ0 モジュールを用いて,RA4/T0CKI  ポートに入力される外部パルスのパルス数カウンタを構成することができる.
 TMR0 レジスタは,外部パルスの立ち上がり,または立ち下がりエッ ジごとにインクリメントされるため,任意のタイミングで TMR0 レジスタを読み出すことで外部パルスの入力パルス数を(一定タイミング毎に読み出すことで周波数を)知ることができる.
 プリスケーラの利用も可能である.
 
■2.6 EEPROM(Electrically Erasable Programmable Read Only Memory)
 EEPROM はプログラムメモリやデータメモリとは独立に搭載されたフラッシュメモリである.
 データメモリのようにプログラムから頻繁に参照されるデータではなく,あまり変更される頻度が高くないながらもずっと保持していたいパラメータ等を格納するために使用する.
 PIC16F84A には 64 byte(00H〜3FH)の EEPROM が搭載されている.

◆2.6.1 アーキテクチャ
 EEPROM はレジスタファイル空間に直接マッピングされていない.そのため,4 個の SFREEADREEDATAEECON1EECON2)を通して間接的にアドレス指定してアクセスする.
 まず,EEADR レジスタで,EEPROM のアドレスを指定し,EEDATA レジスタを経由してデータを読み書きする.
 読み出し,書き込みのタイミングEECON1 およびEECON2 レジスタでコントロールする.
EEADR レジスタ EEPROM の書き込みおよび読み出しアドレスを指定するレジスタ.
 PIC16F84A では最初の 64 byte の EEPROM だけが物理的に存在するが,EEADR レジスタは最大 256 byte の EEPROM をアドレス指定できるため,上位 2 bit もアドレスとしてデコードされる.
 したがって,ア ドレスが必ず 64 byte のメモリ空間にあるように,EEADR レジスタの上位 2 bit は常に 0 にしておく必要がある
EEDATA レジスタ システムのデータバスと EEPROM とのデータのやりとりを中継するレジスタ.
 EEPROM へデータを書き込む場合には,EEDATA レジスタにデータを移動した後に書き込みシーケンスを行う.
 EEPROM からデータを読み出す場合には,読み出しシーケンスを実行後に EEDATA レジスタを参照する.
EECON1 レジスタ EEPROM へのアクセスを制御や監視を行うレジスタ.
 EECON1 は,下位 5 bit のみ物理的に存在するコンロールレジスタであり,上位 3 ビットは存在せず 0 としてリードされる.

R 読み出し可能ビット
W 書き込み可能ビット
S セット可能ビット
U 使用しないビット.0 として読み出し
-n リセットでの値
EEIF 書き込み完了割り込みフラグビット
 1:書き込み完了,割り込み発生.
  (ソフトウェアでクリアする必要がある)
 0:書き込みが完了していない,もしくは開始していない.
WRERR 書き込みエラーフラグビット
 1:電源変動やウォッチドッグタイマ等で書き込みが異常終了した.
 0:書き込み正常完了.
WREN 書き込みイネーブルビット
 1:書き込みサイクルを許可.
 0:書き込みを禁止.
WR 書き込み開始制御ビット
 1:書き込みサイクルを開始する.
  (終了すると自動的にクリアされ,ソフトウェアではクリアできない)
 0:書き込みサイクル完了.
RD 読み出し開始制御ビット
 1:読み出しを開始する.
  (終了すると自動的にクリアされ,ソフトウェアではクリアできない)
 0:読み出しを開始しない.
EECON2 レジスタ 誤動作等による EEPROM への書き込みを保護するため,書き込みシーケ ンスで使用されるレジスタ.
 EECON2 レジスタは物理的に存在するレジスタではない.そのため,EECON2 を読み出すと全て 0 となる.

◆2.6.2 アクセス方法
読み出しシーケンス  EEADR レジスタにアドレスを格納してRD ビットをセットすると,次のサイクルでEEDATA レジスタにデータが入力される.したがって,MOVF 命令等でそのデータを読み込むことができる.
 この値は,その後に読み出しや書き込みが行われるまでEEDATA レジスタで保持される.

READ_EEPROM
        MOVLW   CONFIG_ADDR     ;
        MOVWF   EEADR           ;Address to read
        BSF     STATUS,RP0      ;Bank 1
        BSF     EECON1,RD       ;Start read
        BCF     STATUS,RP0      ;Bank 0
        MOVF    EEDATA,W        ;EEDATA->Wreg
書き込みシーケンス  まず,EEADR レジスタにアドレスを書き込み,EEDATA レジスタにデータを書き込む.
 次に,EECON2 レジスタを用いた特別なシーケンス(下記のプログラムで REQUIRED_SEQUENCE_START〜REQUIRED_SEQUENCE_END 部分)を実行する.このシーケンスは書き込みを 1 byte 実行するごとに必要である.
 なお,このシーケンスを実行するルーチン部分では,確実な動作をさせるため割込みを禁止することが望ましい

WRITE_EEPROM
        MOVLW   CONFIG_ADDR     ;
        MOVWF   EEADR           ;Address to write
        MOVF    CONFIG_DATA     ;
        MOVWF   EEDATA          ;Data to write
        BSF     STATUS,RP0      ;Bank 1
        BCF     INTCON,GIE      ;Disable INTs.
        BSF     EECON1,WREN     ;Enable Write

REQUIRED_SEQUENCE_START
        MOVLW   55H             ;
        MOVWF   EECON2          ;Write 55H
        MOVLW   AAH             ;
        MOVWF   EECON2          ;Write AAH
        BSF     EECON1,WR       ;begin write
REQUIRED_SEQUENCE_END

        BSF     INTCON,GIE      ;Enable INTs.
WR_LOOP
        BTFSC   EECON1,WR       ;Check write end
        GOTO    WR_LOOP
        BCF     STATUS,RP0      ;Bank 0
  
■課題
 PIC16F84A を含めて,現在のほとんどのマイコンには,ウォッチドッグタイマと呼ばれるモジュールが実装されている.
 ウォッチドッグタイマとはどのようなものであるか,その機能や使用時の注意点等を述べなさい.

 レポートは,下記のWordファイルを使用して作成すること.なるべく簡潔にまとめることが望ましい.
 Form02.docx

 WebClassより期限内に提出すること.