Chapter 3. レッスン
3.4 レッスン 3: ローテート
PICkit™ 3 スタータキット ユーザガイド
DS41628B_JP - p.52 2015 Microchip Technology Inc.
3.4.5.2 エンハンスト ミッドレンジ
3.4.5.3 PIC18
3.4.5.3.1 LSRF/RRCF
LSRFとRRCFの違いは、前者の場合はMSbに「0」が入るという事です。後者の場
合はcarryビットの内容をMSbにシフトします。どちらの命令もLSbをcarryビット
にシフトします。以下に例を示します。
図3-1: LSRF
図3-2: RRCF
シフトの結果carryビットに「1」が入った場合、次のローテートを実行するとレジス タのMSbに「1」が入るため、それを避けたい場合はcarryビットをクリアしておく 必要があります。
3.4.6 アセンブリ
3.4.6.1 エンハンスト ミッドレンジ
例3-14:
表3-9: 新しく学ぶエンハンスト ミッドレンジの命令
命令 英語名 目的
lsrf Logical Right Shift ビットを右方向へシフトする
表3-10: 新しく学ぶPIC18の命令
命令 英語名 目的
rrcf Rotate Right f through Carry ビットを右方向へシフトする
7 6 5 4 3 2 1 0
0 0 0 1 0 1 1 1 X
0 0 0 1 0 1 1 1 0
0
MSb LSb
C
7 6 5 4 3 2 1 0
0 0 0 1 0 1 1 1
C
0 0 0 1 0 1 1 1
1
MSb LSb
1
Rotate:
lsrf LATC,F ;shift the LEDs and turn on the next LED to the right btfsc STATUS,C ;did the bit rotate into the carry (i.e. was DS1 just lit?)
bsf LATC, 3 ;yes, it did and now start the sequence over again by turning on DS4 goto MainLoop ;repeat this program forever
DS1はRC0に接続され、DS2はRC1に接続されています(以下同様)。ビットを右 方向へシフトすると、LEDは右から左へ順番に点灯していきます。これを分かりやす くまとめた表を以下に示します。
プログラムを開始するとDS4が点灯します。
遅延の後、右方向への論理シフトを実行します。
これでDS3が点灯します。carryビットには、LATCbits.LATC0にあった値が格納 されます。この場合は「0」です。次にこのプログラムは carry ビットがセットされ ているかを検査します。これは DS1 が点灯した状態でlsrfが実行された場合のみ 結果が真となります。この場合carryビットがセットされているため、次の行が実行 されます。
例3-15:
これでDS4が再点灯し、プログラムは最初に戻って同じ点灯パターンを繰り返します。
なお、MSb (bit 7)は常にクリアされる事に注意してください。これはlsrf命令の性 質によるものです。
3.4.6.2 PIC18
PIC18の論理シフト命令はエンハンストミッドレンジとは異なります。
例3-16:
表3-11: ピンとLEDの対応関係
LATC
Bit # MSb (7) 6 5 4 3 2 1 LSb (0)
LED — — — — DS4 DS3 DS2 DS1
表3-12: LED点灯のローテート
LATC
Bit # MSb (7) 6 5 4 3 2 1 LSb (0)
LED — — — — DS4 DS3 DS2 DS1
値 0 0 0 0 1 0 0 0
表3-13: LED点灯のローテート
LATC
Bit # MSb (7) 6 5 4 3 2 1 LSb (0)
LED — — — — DS4 DS3 DS2 DS1
値 0 0 0 0 0 1 0 0
bsf LATC, 3 ;yes, it did and now start the sequence over again by turning on DS4
Rotate:
rrcf LATC,f ;rotate the LEDs (through carry) and turn on the next LED to the right btfss STATUS,C ;did the bit rotate into the carry (i.e. was DS1 just lit?)
goto MainLoop ;nope, repeat this program forever
bsf LATC, 3 ;yes, it did and now start the sequence over again by turning on DS4 bcf STATUS, C ;clear the carry
goto MainLoop ;repeat this program forever
PICkit™ 3 スタータキット ユーザガイド
DS41628B_JP - p.54 2015 Microchip Technology Inc.
PIC18には、carryビットを使うローテート命令と使わないローテート命令があります。
carryビットを使わないローテート命令の場合、LSbの値がそのままMSbに入ります。
PIC16 の場合と同様、このプログラムも直前まで左端のLED (DS1)が点灯していた
かどうかをcarryビットを使って調べる必要があります。唯一の違いは、セットされ
たcarryビットをクリアする必要があるという点です。このビットをクリアしなくて
もDS3は正しく点灯しますが、LATCbits.LATC7もセットされるため、ローテート 命令を繰り返すうちにこのビットがLEDの接続された<RC3:RC0>のレンジに入り、
やがて全てのLEDが点灯してしまいます。
3.4.7 C言語
3.4.7.1 両デバイス共通
Cコードの方がはるかにシンプルで、容易に理解できます。このプログラムは500 ms の遅延の後、LATCレジスタを右方向へシフトし、LATCのcarryビットがセットされ ているかを検査しています。セットされている場合は RC3 をセットしてローテート を続けます。
例3-17:
上記のシフトは、符号なしレジスタであるため論理シフトである事に注意してください。
この場合もシフト後にSTATUSレジスタが更新されます。Cにはいくつかの省略記法 があり、例3-17に示したシフトもその1つです。例3-18に例を示します。
例3-18:
__delay_ms(500); //delay 500ms
LATC >> = 1; //shift to the right by 1
if(STATUSbits.C) //when the last LED is lit, restart the pattern LATCbits.LATC3 = 1;
LATC >> = 1;
等価な代入文:
LATC = LATC >> 1;
等価なアセンブリ命令:
lsrf LATC,F ;shift the LEDs and turn on the next LED to the right