4. 演算命令 ( つづき ) ( 足し算の桁上がり,Rotate, etc.) を学ぼう 本稿の Web ページ http://www.cmplx.cse.nagoya-u.ac.jp/~furuhashi/education/pic/index.html 1
本章では足し算の桁上がり情報の格納場所の確認をするプログラムを学びます. PIC16F マイコンではデータは 8 ビットで表されています. 最上位ビットは 7 ビット目, 最下位ビットは 0 ビット目と数えられます. 7 ビット目 0 ビット目 1 0 1 1 0 0 1 0 以下の足し算を実行すると,8 ビット目に桁上がりした 1 は 8 ビットのレジスタに収まらずオーバーフローします. この値は捨てられることなく,STATUS レジスタの 0 ビット目に格納されます. 11111111 +00000001 100000000 オーバーフロー 2
; ADD Carry Check このソースファイルを各自打ち込んで下さい. CONFIG _HS_OSC & _WDT_OFF & _PWRTE_OFF & _CP_OFF MEM1 EQU 0x0C ;MEM1 at 0C BCF STATUS,0 MOVLW 0xFF ; Load 0xFF to W MOVWF MEM1 ; Move W to MEM1 MOVLW 0x01 ; Load 0x01 to W ADDWF MEM1, 0 ; W + MEM1 -> W END 3
Data Sheet の REGISTER FILE MAP よりファイルレジスタの 03h 番地と 83h 番地に STATUS レジスタがあります.STATUS レジスタは 1 つだけです. どちらの番地からでも同じレジスタにアクセスできます. TMR0 01h OPTION_REG 81h PCL 02h PCL 82h STATUS 03h STATUS 83h FSR 04h FSR 84h PORTA 05h TRISA 85h PORTB 06h TRISB 86h 07h 87h EEDATA 08h EECON1 88h EEADR 09h EECON2 89h PCLATH 0Ah PCLATH 8Ah INTCON 0Bh INTCON 8Bh 0Ch 8Ch General Purpose Register 68 バイト 4Fh Mapped in Bank 0 CFh 03h と H 03 と 0x03 はいずれも 16 進数の 3 を表します. Bank 0 Bank 1 4
STATUS レジスタは Special Function Registers と File Registers のどちらのウィンドウでも見ることができます. 5
; ADD Carry Check ;================================== CONFIG _HS_OSC & _WDT_OFF ;-----Bank0------------------ & _PWRTE_OFF & _C STATUS EQU H'0003 MEM1 EQU 0x0C ;MEM1 at 0C C: Program Files (x86) Microchip MPASM Suite の中に p16f84a.inc ファイルがあります. これをテキストエディタを使って開くと ;================================== ; Register Definitions という記述が見られます.0x03 も H 0003 もどちらも 16 進数の 3 を意味します. すなわち STATUS という言葉は 16 進数の 3 と同じ意味であることを宣言しています. ここでSTATUSを使っています. 既にincファイル内にて BCF STATUS,0 STATUSが3を表すことが宣言されています. 従って, こ れはファイルレジスタの3 番地, すなわちSTATUSレジス MOVLW 0xFF タに対して操作を行うことを意味します ; Load 0xFF to W. MOVWF MEM1 ; Move W to MEM1 MOVLW 0x01 ; Load 0x01 to W ADDWF MEM1, 0 ; W + MEM1 -> W END 6
; ADD Carry Check CONFIG _HS_OSC & _WDT_OFF & _PWRTE_OFF & _C MEM1 EQU 0x0C ;MEM1 at 0C STATUS レジスタ 7 6 5 4 3 2 1 0 BCF STATUS,0 MOVLW 0xFF ; Load 0xFF to W MOVWF MEM1 ; Move W to MEM1 MOVLW 0x01 ; Load 0x01 to W ADDWF MEM1, 0 ; W + MEM1 -> W END STATUS レジスタの第 0 ビット ( キャリーフラグという名前がつけられています.) を 0 にします. BCF f, b Bit Clear f の略. f レジスタの第 b ビットをクリア (0 に ) する命令です. 7
; ADD Carry Check CONFIG _HS_OSC & _WDT_OFF & _PWRTE_OFF & _CP MEM1 EQU 0x0C ;MEM1 at 0C STATUS レジスタ 7 6 5 4 3 2 1 0 1 BCF 足し算の結果に桁上がりがあるとキャリーフラ STATUS,0 グが1になります. MOVLW 0xFF ; Load 0xFF to W MOVWF MEM1 ; Move W to MEM1 MOVLW 0x01 ; Load 0x01 to W ADDWF MEM1, 0 ; W + MEM1 -> W END 11111111 + 00000001 100000000 8
; Rotate このソースファイルを各自打ち込んで下さい. CONFIG _HS_OSC & _WDT_OFF & _PWRTE_OFF & _CP_OFF MEM1 EQU 0x0C ;MEM1 at 0C Rotate 命令を学んで下さい. MOVLW B'00110000' ; Load 0x30 to W MOVWF MEM1 ; Move W to MEM1 BCF STATUS,0 ;Clear the 0-th bit of STATUS register ; Rotate MEM1 Left ; Rotate MEM1 Left ; Rotate MEM1 Left ; Rotate MEM1 Left ; Rotate MEM1 Left ; Rotate MEM1 Right ; Rotate MEM1 Right ; Rotate MEM1 Right ; Rotate MEM1 Right ; Rotate MEM1 Right END 9
; Rotate CONFIG _HS_OSC & _WDT_OFF & _PWRTE_OFF & _C MEM1 EQU 0x0C ;MEM1 at 0C STATUS レジスタ 7 6 5 4 3 2 1 0 * * * * * * * 0 MOVLW B'00110000' ; Load 0x30 to W MOVWF MEM1 ; Move W to MEM1 BCF STATUS,0 ;Clear the 0-th bit of STATUS register ; Rotate MEM1 Left ; Rotate MEM1 Left ; Rotate MEM1 Left ; Rotate MEM1 Left ; Rotate MEM1 Left ; Rotate MEM1 Right ; Rotate MEM1 Right ; Rotate MEM1 Right ; Rotate MEM1 Right ; Rotate MEM1 Right STATUS レジスタの第 0 ビット ( キャリーフラグ ) を 0 にします. END 10
; Rotate CONFIG _HS_OSC & _WDT_OFF & _PWRTE_OFF & _CP_OFF MEM1 EQU 0x0C STATUS レジスタ 7 6 5 4 3 2 1 0 * * * * * * * 0 MOVLW MOVWF BCF B'00110000 MEM1 STATUS,0 MEM1 7 6 5 4 3 2 1 0 0 0 1 1 0 0 0 0 MEM1 の中身を 1 ビット左に移動させます. 一番左の第 7 ビット目の中身は外に出てしまうので, これをキャリーフラグに入れます. 一番右の第 0 ビット目にはキャリーフラグの中身を転送します. その結果を MEM1 に転送します. f, d Rotate Left f の略 END d = 1のとき転送先は f レジスタ,d = 0 のときはwレジスタ 11 です.
; Rotate CONFIG _HS_OSC & _WDT_OFF & _PWRTE_OFF & _CP_OFF MEM1 EQU 0x0C STATUS レジスタ 7 6 5 4 3 2 1 0 * * * * * * * 0 MOVLW MOVWF BCF B'00110000 MEM1 STATUS,0 MEM1 7 6 5 4 3 2 1 0 0 1 1 0 0 0 0 0 最初の 実行後の MEM1 の中身です. 以降の を順次 STEP 実行し,MEM1 および STATUS レジスタの中身の変化を確認してください. END 12
; Rotate CONFIG _HS_OSC & _WDT_OFF & _PWRTE_OFF & _CP_OFF MEM1 EQU 0x0C STATUS レジスタ 7 6 5 4 3 2 1 0 * * * * * * * 0 MOVLW MOVWF BCF B'00110000 MEM1 STATUS,0 MEM1 の中身を 1 ビット右に移動させます. 一番右の第 0 ビット目の中身は外に出てしまうので, これをキャリーフラグに入れます. 一番左の第 7 ビット目にはキャリーフラグの中身を転送します. f, d MEM1 7 6 5 4 3 2 1 0 0 0 1 1 0 0 0 0 Rotate Right f の略 d = 1のとき転送先は f レジスタ,d = 0 のときは wレジスタです. END 13
演習問題 7.W レジスタに 0xFF をロードし, これと 0x03 の AND 演算した結果を W レジスタに転送するプログラムを作成せよ. ANDLW B 01010011 AND Literal and W の略 B 01010011 と W レジスタの中身の AND をとって, その結果を W レジスタに転送させる命令です. 今,W レジスタに B 11011001 が入っていたとして, 上の命令を実行すると W レジスタには B 01010001 が得られます. W レジスタ プログラムメモリより 11011001 AND 01010011 01010001 W レジスタへ転送 14
演習問題 7. 解答 W レジスタに 0xFF をロードし, これと 0x03 の AND 演算 (p.60) した結果を W レジスタに転送するプログラムを作成せよ. ;Problem 7 CONFIG _HS_OSC & _WDT_OFF & _PWRTE_OFF & _CP_OFF MOVLW 0xFF ; Load 0xFF to W ANDLW 0x03 ; W AND 0x03 -> W END 15
演習問題 8.MEM1 に 0xAA,W レジスタに 0x0B をロードし, これらの AND 演算した結果を W レジスタに転送するプログラムを作成せよ. ANDWF f, d AND W and f の略 例えば, ANDWF MEM1, 0 は, W レジスタに B 11011001,MEM1 に B 01010011 が入っていたとすると, W レジスタと MEM1 レジスタの中身の AND をとって, その結果を W レジスタに転送させる命令です.W レジスタには B 01010001 が得られます. W レジスタ MEM1 レジスタ 11011001 AND 01010001 01010011 W レジスタへ転送 16
演習問題 8. 解答 MEM1 に 0xAA,W レジスタに 0x0B をロードし, これらの AND 演算した結果を W レジスタに転送するプログラムを作成せよ. ;Problem 8 CONFIG _HS_OSC & _WDT_OFF & _PWRTE_OFF & _CP_OFF MEM1 EQU 0x0C MOVLW 0xAA ; Load 0xAA to W MOVWF MEM1 ; W -> MEM1 MOVLW 0x0B ; Load 0x0B to W ANDWF MEM1,0 ; W AND MEM1 -> W END 17
演習問題 9.W レジスタに 0x30 をロードし, これと 0x03 の OR 演算した結果を W レジスタに転送するプログラムを作成せよ. IORLW B 00000011 Inclusive OR Literal and W の略 ( 通常の OR 演算です.Exclusive OR 演算との区別をはっきりさせるために, Inclusive と明記しています.) 演習問題 10.MEM1 に 0x4A,W レジスタに 0xAB をロードし, これらの OR 演算した結果を W レジスタに転送するプログラムを作成せよ. IORWF f, d Inclusive OR W and f の略 演習問題 11.MEM1 に F0 を転送し, 上位 4 ビットと下位 4 ビットを交換 (SWAPF 命令 ) した結果を W レジスタに転送するプログラムを作成せよ. SWAPF f, d Swap halves f の略 18
演習問題 9. 解答 W レジスタに 0x30 をロードし, これと 0x03 の OR 演算した結果を W レジスタに転送するプログラムを作成せよ. ;Problem 9 CONFIG _HS_OSC & _WDT_OFF & _PWRTE_OFF & _CP_OFF MOVLW 0x30 ; Load 0x30 to W IORLW 0x03 ; W OR 0x03 -> W END 19
演習問題 10. 解答 MEM1 に 0x4A,W レジスタに 0xAB をロードし, これらの OR 演算した結果を W レジスタに転送するプログラムを作成せよ. ;Problem 10 CONFIG _HS_OSC & _WDT_OFF & _PWRTE_OFF & _CP_OFF MEM1 EQU 0x0C MOVLW 0x4A ; Load 0x4A to W MOVWF MEM1 ; W -> MEM1 MOVLW 0xAB ; Load 0xAB to W IORWF MEM1,0 ; W OR MEM1 -> W END 20
演習問題 11.MEM1 に F0 を転送し, 上位 4 ビットと下位 4 ビットを交換 (SWAPF 命令 ) した結果を W レジスタに転送するプログラムを作成せよ. ;Problem 11 CONFIG _HS_OSC & _WDT_OFF & _PWRTE_OFF & _CP_OFF MEM1 EQU 0x0C MOVLW 0xF0 ; Load 0xF0 to W MOVWF MEM1 SWAPF MEM1,0 ; SWAP MEM1 -> W END 21
2004 年 8 月 22