デバイスは、次のタイプのメモリから構成されています。
拡張ミッドレンジコアには、32K x14のプログラムメモリスペースをアドレス指定できる15ビットのプログラムカウンターがあります。表3-1に、実装されているメモリサイズを示します。これらの境界より上の場所にアクセスすると、実装されたメモリスペース内でラップアラウンドが発生します。
リセットベクトルは、0000hにあり、割り込みベクトルは、0004hにあります(図3-1を参照)。
デバイス | プログラムメモリサイズ(Words) | 最終プログラムメモリアドレス |
---|---|---|
PIC16F18326/18346 | 16384 | 3FFFh |
PIC16F18325/18345 | 8192 | 1FFFh |
図3-1:プログラムメモリマップとスタック
プログラムメモリ内の定数にアクセスするには、2つの方法があります。最初の方法は、RETLW命令のテーブルを使用することです。2番目の方法は、プログラムメモリを指定するように FSR を設定することです。
例 3-1:FRETLWによるプログラムメモリへのアクセス
constants BRW ;Add Index in W to ;program counter to ;select data RETLW DATA0 ;Index0 data RETLW DATA1 ;Index1 data RETLW DATA2 RETLW DATA3 my_function ;… LOTS OF CODE MOVLW DATA_INDEX call constants ;… THE CONSTANT IS IN W
RETLW命令を使用して、定数テーブルへのアクセスを提供できます。このようなテーブルを作成するための推奨される方法を例 3-1に示します。
*注意*
BRW命令により、このタイプのテーブル実装が非常に簡単になります。
しかし、前世代のマイクロコンピューターにコードを移植する必要がある場合、PIC16F6XX、PIC16F7XX、PIC16F8XX、PIC16F9XXなどの一部のデバイスは BRW命令が使用できないため、この方法は使用できません。
例 3-1a:MPASMでは DT を使用し、下のように書きます
constants BRW DT "Hallo world.",0x00 my_function ;… LOTS OF CODE MOVLW DATA_INDEX call constants ;… THE CONSTANT IS IN W
*ヒント*
MPASMでは DT を使用し、プログラムを見やすく記述することができます。
DT を機械語に変換すると 例 3-1 と同じようにRETLW命令を使用した定数テーブルへのアクセスをコードが生成されます。
例 3-2:FSRを介したプログラムメモリへのアクセス
constants RETLW DATA0 ;Index0 data RETLW DATA1 ;Index1 data RETLW DATA2 RETLW DATA3 my_function ;… LOTS OF CODE MOVLW LOW constants MOVWF FSR1L MOVLW HIGH constants MOVWF FSR1H MOVIW 0[FSR1] ;THE PROGRAM MEMORY IS IN W
FSRxH レジスタのビット7をセットし、一致するINDFxレジスタを読み取ることにより、プログラムメモリのデータにアクセスできます。
MOVIW命令は、アドレス指定されたワードの下位8ビットをWレジスタに配置します。プログラムメモリへの書き込みは、INDFレジスタを介して実行することはできません。FSRを介してプログラムメモリにアクセスする命令は、完了するために1つの追加の命令サイクルを必要とします。例3-2は、FSRを介してプログラムメモリにアクセスする方法を示しています。ラベルがプログラムメモリ内の場所を指定している場合、HIGHディレクティブはビット7を設定します。
データメモリは、各バンクに128バイトの32個のメモリバンクに分割されています。各銀行は次のもので構成されています(図3
図3-2:バンクメモリの区分け
アクティブなバンクは、バンク番号をBank Select Register(BSR)に書き込むことによって選択されます。実装されていないメモリは「0」として読み取られます。すべてのデータメモリには、直接(ファイルレジスタを使用する命令を介して)または2つのファイル選択レジスタ(FSR)を介して間接的にアクセスできます。詳細については、セクション3.5「間接アドレス指定」を参照してください。
データメモリは12ビットアドレスを使用します。アドレスの上位7ビットはバンクアドレスを定義し、下位5ビットはそのバンクのレジスタ/ RAMを選択します。
コアレジスタには、基本操作に直接影響するレジスタが含まれています。コアレジスタは、すべてのデータメモリバンクの最初の12個のアドレス(アドレスx00h
レジスタ3-1に示されているSTATUSレジスタには、次のものが含まれています。
STATUSレジスタは、他のレジスタと同様に、任意の命令の処理対象にすることができます。STATUSレジスタがZ、DC、またはCビットに影響を与える命令の処理対象である場合、これらの3ビットへの書き込みは無効になります。これらのビットは、デバイスロジックに従ってセットまたはクリアされます。さらに、TOビットとPDビットは書き込み可能ではありません。したがって、STATUSレジスタを処理対象とする命令の結果は、意図したものと異なる場合があります。 たとえば、CLRF STATUSは上位3ビットをクリアし、Zビットを設定します。これにより、STATUSレジスタは「000uu1uu」のままになります(u =変更なし)。 したがって、ステータスビットに影響を与えない BCF、BSF、SWAPF、およびMOVWF命令のみを使用して、STATUSレジスタを変更することをお勧めします。ステータスビットに影響を与えないその他の命令については、セクション3.0「メモリ構成」を参照してください。
レジスタ | bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 |
---|---|---|---|---|---|---|---|---|
STATUS | - | - | - | nTO | nPD | Z | DC | C |
レジスタ | BIT | 名 | 説明 | 1 | 0 |
---|---|---|---|---|---|
STATUS | 4 | nTO | WDT Time-Out bit | なし | 発生 |
3 | nPD | Power-Down bit | なし | 発生 | |
2 | Z | Zero bit | ゼロ | - | |
1 | DC | 4bit目からの Carry/Digit Borrow bit | 発生 | なし | |
0 | C | Carry/Borrow bit ( | 発生 | なし |
特殊機能レジスタは、デバイスの周辺機能の目的の動作を制御するためにアプリケーションによって使用されるレジスタです。特殊機能レジスタは、バンク27、28、および29(PPSおよびCLCレジスタ)を除いて、すべてのデータメモリバンク(アドレスx0Ch / x8Chからx1Fh / x9Fh)のコアレジスタの後の20バイトを占めます。周辺機器の操作に関連するレジスタは、このデータシートの該当する周辺機器の章に記載されています。
各データメモリバンクには最大80バイトのGPRがあります。特殊機能レジスタは、バンク27、28、および29(PPSおよびCLCレジスタ)を除いて、すべてのデータメモリバンク(アドレスx0Ch / x8Chからx1Fh / x9Fh)のコアレジスタの後の20バイトを占めます。
汎用RAMには、FSRを介してバンクされていない方法でアクセスできます。これにより、大容量のメモリ構造へのアクセスを簡素化できます。詳細については、セクション3.5.2「リニアデータメモリ」を参照してください。
すべてのバンクからアクセス可能な16バイトの共通RAMがあります。
デバイスのメモリマップは表3-4のとおりです。
プログラムカウンター(PC)は15ビット幅です。下位バイトは、読み取りおよび書き込み可能なレジスタであるPCLレジスタから取得されます。上位バイト(PC <14:8>)は直接読み取りまたは書き込み可能ではなく、PCLATHから取得されます。リセットすると、PCはクリアされます。図3-3は、PCをロードするための5つの状況を示しています。
図3-3:さまざまな状況でのPCのロード
PCLレジスタを処理対象として命令を同時に実行すると、プログラムカウンタPC <14:8>ビット(PCH)がPCLATHレジスタの内容に置き換えられます。これにより、必要な上位7ビットをPCLATHレジスタに書き込むことにより、プログラムカウンタの内容全体を変更できます。下位8ビットがPCLレジスタに書き込まれると、プログラムカウンタの15ビットすべてが、PCLATHレジスタに含まれている値とPCLレジスタに書き込まれている値に変更されます。
計算されたGOTOは、プログラムカウンター(ADDWF PCL)にオフセットを追加することによって実現されます。計算されたGOTOメソッドを使用してテーブルの読み取りを実行する場合、テーブルの場所がPCLメモリの境界(各256バイトブロック)を超える場合は注意が必要です。アプリケーションノートAN556、テーブル読み取りの実装(DS00556)を参照してください。
計算された関数CALLを使用すると、プログラムは関数のテーブルを維持し、ステートマシンまたはルックアップテーブルを実行する別の方法を提供できます。計算関数CALLを使用してテーブルの読み取りを実行する場合、テーブルの場所がPCLメモリ境界(各256バイトブロック)を超える場合は注意が必要です。
CALL命令を使用する場合、PCH <2:0>およびPCLレジスタには、CALL命令のオペランドがロードされます。PCH <6:3>にはPCLATH <6:3>がロードされます。
CALL命令を使用する場合、PCH <2:0>およびPCLレジスタには、CALL命令のオペランドがロードされます。PCH <6:3>にはPCLATH <6:3>がロードされます。
CALLW命令は、PCLATHとWを組み合わせて処理対象アドレスを形成することにより、計算された呼び出しを可能にします。計算されたCALLWは、Wレジスタに目的のアドレスをロードしてCALLWを実行することによって実行されます。PCLレジスタにはWの値がロードされ、PCHにはPCLATHがロードされます。
分岐命令は、PCにオフセットを追加します。これにより、再配置可能なコードとページの境界を越えるコードが可能になります。分岐には、BRWとBRAの2つの形式があります。どちらの場合も、PCは次の命令をフェッチするためにインクリメントされます。いずれかの分岐命令を使用すると、PCLメモリの境界を超える場合があります。
BRWを使用する場合は、Wレジスタに目的の符号なしアドレスをロードして、BRWを実行します。PC全体にアドレスPC + 1 + Wがロードされます。
PC + OPCODE <8:0>BRAを使用する場合、PC全体にPC + 1 + BRA命令のオペランドの符号付き値がロードされます。
すべてのデバイスには、16レベルx 15ビット幅のハードウェアスタックがあります(図3-4から図3-7を参照)。スタックスペースは、プログラムスペースまたはデータスペースの一部ではありません。
CALLまたはCALLW命令が実行されるか、割り込みによって分岐が発生すると、PCはスタックにプッシュされます。スタックは、RETURN、RETLW、またはRETFIE命令が実行された場合にPOPされます。
PCLATHは、PUSHまたはPOP操作の影響を受けません。
STVRENビットが「0」(構成ワード)にプログラムされている場合、スタックは循環バッファーとして動作します。これは、スタックが16回プッシュされた後、17番目のPUSHが最初のPUSHから保存された値を上書きすることを意味します。
18番目のPUSHは、2番目のPUSHを上書きします(以下同様)。
STKOVFおよびSTKUNFフラグビットは、リセットが有効かどうかに関係なく、オーバーフロー/アンダーフローに設定されます。
*注意*
PUSHまたはPOPと呼ばれる命令/ニーモニックはありません。これらは、CALL、CALLW、RETURN、RETLW、およびRETFIE命令の実行、または割り込みアドレスへのベクトル化から発生するアクションです。
スタックは、TOSH、TOSL、およびSTKPTRレジスタを介して利用できます。
STKPTRは、スタックポインタの現在の値です。TOSH:TOSLレジスタペアはスタックのTOPを指します。両方のレジスタは読み取り/書き込み可能です。
PCのサイズが15ビットであるため、TOSはTOSHとTOSLに分割されます。スタックにアクセスするには、STKPTRの値を調整します。これにより、TOSH:TOSLが配置され、TOSH:TOSLに対して読み取り/書き込みが行われます。
STKPTRは、オーバーフローとアンダーフローの検出を可能にする5ビットです。
*注意*
割り込みが有効になっているときにSTKPTRを変更する場合は、注意が必要です。
通常のプログラム操作中、CALL、CALLW、およびInterruptsはSTKPTRをインクリメントし、RETLW、RETURN、およびRETFIEはSTKPTRをデクリメントします。いつでもSTKPTRを検査して、スタックがどれだけ残っているかを確認できます。
STKPTRは常に、スタック上の現在使用されている場所を指します。したがって、CALLまたはCALLWはSTKPTRをインクリメントしてからPCに書き込み、リターンはPCをアンロードしてからSTKPTRをデクリメントします。
スタックへのアクセス例については、図3-4から図3-7を参照してください。
図3-4:スタックへのアクセス例1
初期スタック構成:
リセット後、スタックは空になります。空のスタックが初期化されるため、スタックポインタは0x1Fを指します。スタックオーバーフロー/アンダーフローリセットが有効になっている場合、TOSH / TOSLレジスタは「0」を返します。
スタックオーバーフロー/アンダーフローリセットが無効になっている場合、TOSH / TOSLレジスタはスタックアドレス0x0Fの内容を返します。
図3-5:スタックへのアクセス例2
この図は、最初のCALLまたは単一の割り込み後のスタック構成を示しています。RETURN命令が実行されると、戻りアドレスはプログラムカウンターに配置され、スタックポインターは空の状態(0x1F)にデクリメントされます。
図3-6:スタックへのアクセス例3
7回のCALLまたは6回のCALLと割り込みの後、スタックは左の図のようになります。一連のRETURN命令は、リターンアドレスをプログラムカウンターに繰り返し配置し、スタックをポップします。
図3-7:スタックへのアクセス例4
スタックがいっぱいになると、次のCALLまたは割り込みにより、スタックポインタが0x10に設定されます。これはアドレス0x00と同じであるため、スタックは0x00のリターンアドレスをラップして上書きします。
スタックオーバーフロー/アンダーフローリセットが有効になっている場合、リセットが発生し、場所0x00は上書きされません。
構成ワードのSTVRENビットが「1」にプログラムされている場合、スタックが第16レベルを超えてプッシュされるか、第1レベルを超えてPOPされると、デバイスはリセットされ、PCONレジスタに適切なビット(それぞれSTKOVFまたはSTKUNF)が設定されます。
ファイル選択レジスタ(FSR)は、2組の16ビットレジスタで構成されます。 FSRは、すべてのファイルレジスタ、プログラムメモリ、およびデータEEPROMにアクセスできます。これにより、すべてのメモリに対して1つのデータポインタが可能になります。 FSRがプログラムメモリを指定する場合、INDFを使用する命令には、データをフェッチできるようにするための追加の命令サイクルが1つ必要です。汎用メモリも線形にアドレス指定できるようになり、80バイトを超える連続データにアクセスできるようになりました。 FSRをサポートするための新しい手順もあります。
INDFnレジスタは物理レジスタではありません。INDFnレジスタにアクセスする命令は、実際にはファイル選択レジスタ(FSR)で指定されたアドレスのレジスタにアクセスします。FSRnアドレスが2つのINDFnレジスタの1つを指定している場合、読み取りは「0」を返し、書き込みは発生しません(ただし、ステータスビットは影響を受ける可能性があります)。FSRnレジスタ値は、FSRnHとFSRnLのペアによって作成されます。
FSRレジスタは16ビットのアドレスを使用し、65kのアドレス空間を指定可能です。これらは、次の4つのメモリ領域に分割されています。
従来のデータメモリは、FSRアドレス0x000からFSRアドレス0xFFFまでの領域です。アドレスは、すべてのSFR、GPR、および共通レジスタの絶対アドレスに対応します。
図3-8:従来のデータメモリマップ
図3-9:リニアデータメモリマップ
リニアデータメモリは、FSRアドレス0x2000からFSRアドレス0x29AFまでの領域です。この領域は、すべてのバンクのGPRメモリの80バイトブロックを指定する仮想領域です。
実装されていないメモリは0x00として読み取られます。
リニアデータメモリ領域を使用すると、1つのバンクを超えてFSRをインクリメントすると、次のバンクのGPRメモリに直接移動するため、バッファを80バイトより大きくすることができます。
16バイトの共通メモリはリニアデータメモリ領域に含まれていません。
図3-10:プログラムフラッシュメモリマップ
常時データアクセスを容易にするために、プログラムフラッシュメモリ全体がFSRアドレススペースの上半分にマップされます。
FSRnHのMSBが設定されている場合、下位15ビットは、INDFを介してアクセスされるプログラムメモリ内のアドレスです。INDFを介してアクセスできるのは、各メモリ位置の下位8ビットのみです。
プログラムフラッシュメモリへの書き込みは、FSR / INDFインターフェイスを介して実行することはできません。
FSR / INDFインターフェイスを介してプログラムフラッシュメモリにアクセスするすべての命令は、完了するために1つの追加の命令サイクルを必要とします。