いまさらアセンブラでPIC
Home

メモリーマップ
12F675のプログラムを格納するメモリーは図の通りで、1ワード(アドレスの1番地分)は14ピットで構成されていて、それが000番地から3FF番地まで使える。特に000番地は電源投入後に最初に実行される番地であり、004番地は割込みが発生したときに飛んでくる番地である。


スペシャルファンクションレジスタ
ファイルレジスタバンク0バンク1
00h(80h)indirect addrindirect addr
01h(81h)TMR0OPTION_REG
02h(82h)PCLPCL
03h(83h)STATUSSTATUS
04h(84h)FSR
05h(85h)GPIO
06h(86h)
07h(87h)
08h(88h)
09h(89h)
0Ah(8Ah)PCLATHPCLATH
0Bh(8Bh)INTCONINTCON
0Ch(8Ch)PIR1PIE1
0Dh(8Dh)
0Eh(8Eh)TMR1LPCON
0Fh(8Fh)TMR1H
10h(90h)T1CONOSCCAL
11h(91h)
12h(92h)
13h(93h)
14h(94h)
15h(95h)WPU
16h(96h)IOC
17h(97h)
18h(98h)
19h(99h)CMCONVRCON
1Ah(9Ah)EEDATA
1Bh(9Bh)EEADR
1Ch(9Ch)EECON1
1Dh(9Dh)EECON2(1)
1Eh(9Eh)ADRESH(2)ADRESL(2)
1Fh(8Fh)ADCON(2)ANSEL(2)
20h(8Fh)
General
Purpose
Registers
64 Bytes
accesses
20h-5Fh
5Fh(DFh)
60h(E0h)
  
7Fh(FFh)


INSTRUCTION SET
Cycles14-Bit OpcodeStatus
Affected
BYTE-ORIENTED FILE REGISTER OPERATIONS
ADDWF f, dd = W + f100 0111 dfff ffffC, DC,Z
ANDWF f, dd = W and f100 0101 dfff ffffZ
CLRF ff = 0100 0001 1fff ffffZ
CLRWW = 0100 0001 0xxx xxxxZ
COMF f, dComplement f100 1001 dxxx xxxxZ
DECF f, dd = f - 1100 0011 dxxx xxxxZ
DECFS f, dd =f - 1, Skip next if 01(2)00 1011 dfff ffff
INCF f, dd = f + 1100 1010 dfff ffffZ
INCFSZ f, dd = f + 1, Skip next if 01(2)00 1111 dfff ffff
IORWF f, dd = Wとf100 0100 dfff ffffZ
MOVF f, dd = f100 1000 dfff ffffZ
MOVWF fW = f100 0000 1fff ffff
NOPdo nothing100 0000 0xx0 0000
RLF f, dRotate f Left d bit100 1101 dfff ffff
RRF f, dRotate f Right d bit100 1100 dfff ffff
SUBWF f, dd = f-W100 0010 dfff ffffC, DC, Z
SWAPF f, d100 1110 dfff ffff
XORWF f, dd = W XOR f100 0110 dfff ffffZ
BIT-ORIENTED FILE REGISTER OPERATIONS
BCF f, bf.b = 0101 00bb bfff ffff
BSF f, bf.b = 1101 01bb bfff ffff
BTFSC f, bif bit=0, skip next1(2)01 10bb bfff ffff
BTFSS f, bif bit=1, skip next1(2)01 11bb bfff ffff
LITERAL AND CONTROL OPERATIONS
ADDLW kW = W + k111 111x kkkk kkkkC, DC, Z
ANDLW kW = W and k111 1001 kkkk kkkkZ
CALL kCall subroutine210 0kkk kkkk kkkk
CLRWDTClear Watchdog Timer100 0000 0110 0100/TO, /PD
GOTO kGo to address k210 1kkk kkkk kkkk
IORLW kW = W IOR k111 1000 kkkk kkkkZ
MOVLW kW = k111 00xx kkkk kkkk
RETFIEReturn from interrupt200 0000 0000 1001
RETLW kReturn with literal in W211 01xx kkkk kkkk
RETURNReturn from Subroutine200 0000 0000 1000
SLEEPGo into Standby mode100 0000 0110 0011/TO, /PD
SUBLW kW = W - k111 110x kkkk kkkkC, DC, Z
XORLW kW = W XOR k111 1010 kkkk kkkkZ


CONFIG bit
bit
13バンドギャップ・キャリブレーション・ビット
12バンドギャップ・キャリブレーション・ビット
11未使用
10未使用
9未使用
8データメモリの保護 1:不許可 0:許可
7コードプロテクト プログラムの保護 1:不許可 0:許可
6ブラウンアウト検出 1:許可 0:不許可
5GP3/MCLRピンの設定 1:GP3はMCLR, 0:GP3はI/O, MCLRはVDD
4パワーアップタイマ 1:不許可 0:許可
3ウォッチドッグタイマ 1:許可 0:不許可
2オシレータの設定
1オシレータの設定
0オシレータの設定

ということで、13,12bit(キャリブレーションビット)をH, 11,10,9bitは意味はないがH,8,7bit(プロテクト)はOFFにするから両方1, 6bitブラウンアウトは無効なので0, 5bitGP3はI/Oにつなぐので0, 4bitはパワーアップタイマは1,3bitウォッチドッグはOFFなので0, オシレータ(2,1,0bit)は内部発振なので100。そうすると11 1111 1101 0100先頭に2ビットをたしてコードは3FD4になる。


HEXファイル
最終的にこのファイルをライタに渡す。HEXファイルはIntel hex formatという規格に則っているが、中身は普通のテキストデータなのでメモ帳で中身を見ることもできるし、なんなら書き換えることもできる。

HEXファイルのフォーマット
HEXファイル内は1行ごと独立しており、それぞれの行は次のフォーマットで記録されている。()内はバイト数

スタートコード(1) データ長(2) アドレスオフセット値(4) レコード種別(2) データ(任意) チェックサム(2)

1, スタートコード(1文字)
スタートコードとして:(コロン)を書き込む

2, データ長
その行に収めてあるデータの数を16進数で記録する。例えばデータの長さ10なら16byteの意味。

3. アドレスオフセット(4文字)
書き込み時の開始アドレス ビッグエンディアンで表記

4. レコード種別(2文字)
種別意味
00データフィールド
01ファイルの最後 データ長は00でデータフィールドはブランクになる
02拡張セグメントアドレス アドレスが16ビットを超えるときここが使われる。
この値の指定値x16 + 00レコードで指定されたアドレスオフセット値
03PICマイコンには関係ない
04拡張リニアアドレス このレコードでは、アドレス指定のうち上位16ビット分を指定します。
これ以降のデータは、”ここで指定されたアドレスを16ビット左シフトした値”+”00レコードで指定されたアドレスオフセット値”をオフセット値とみなします。
PICマイコンには関係ない種別になる。仮に指定されていてもデータ部は00 00となりオフセット指定になっていないはず
05PICマイコンには関係ない

5. データ部(データ長分の文字数)
PICのデータは2バイトで1ワードを表現する。1ワードを意味する2バイトの上位下位を入れ替えて記録していく。

6.チェックサム(1バイト分の2文字)
”データ長、アドレスオフセット値、レコード種別、データ”部の各バイトを合計した後の数の2の補数。
例えばチェックサムを除いて:020000002108となった場合、合計は02h+00h+00h+00h+21h+08h = 2Bhとなる。2Bhの2の補数はD5hとなる。最終的にチェックサムを含めた:020000002108D5が完全なデータとなる。

合計値が0xFFを超える場合は、下位2桁のみを使って2の補数を考える。
例えばチェックサムを除いて:02000000FF08となった場合、各バイトの合計は02h+00h+00h+00h+FFh+08hより109hと3桁になる。この場合下位2桁である09hを使って2の補数を考えるからチェックサムはF7hとなる。

6.まとめとデータ例
例えばPICのメモリの0番地に281Fh、1番地に193Bhと書き込むことを考える。まずデータ長は28h, 1Fh, 19h, 3Bhの4バイトなので04となる。スタート位置は0000hとなる。この時データのスタート位置はバイト単位、PICのメモリはワード単位(2バイト)なのでスタート位置÷2=PICのメモリの番地となることに注意する。データ種別はデータなので00, データ部は上位下位を入れ替えることに注意すると1F28 3B19となる。ここまでを前夫並べると:04 0000 00 1F28 3B19となる。チェックサムを求めるためにまずデータをバイトごとに区切って総和を取ると04h+00h+00h+00h+1Fh+28h+3Bh+19h=9Fhとなる。9Fhの2の補数は61となる。 最終的に:04 0000 00 1F28 3B19 61となる。これをファイルに記録するときには不要なスペースを抜いて:040000001F28 3B1961とする。

7.おまけ的メモ
コンフィグの設定例
本来はPICの2007番地に書き込まなければいけないのに書き込み位置が400EなのはPICが1番地あたり2バイトを使うから。しかもデータはデータ部の説明にも書いたように上位下位を入れ替えている。
:02400E00C43FAD
終了コードの例。データ部がない。
:00000001FF