• 検索結果がありません。

レッスン 7: 方向切り換え付き可変速ローテート

ドキュメント内 PICkit 3 Starter Kit User’s Guide (ページ 65-68)

Chapter 3. レッスン

3.8 レッスン 7: 方向切り換え付き可変速ローテート

3.8.1 レッスンの紹介

このレッスンは、これまでに学んだ全てのレッスンの内容を組み合わせ、スイッチを 押してローテートの方向を反転させます。ローテーションの速度はポテンショメータ で制御します。

3.8.2 ハードウェアの動作

A/D変換結果の値に応じた速度でLEDがローテートします。スイッチを押すとLED のローテート方向が反転します。

3.8.3 概要

このプログラムではローテート方向を追跡する必要があります。また、反対方向に ローテートするためのコードを追加する必要があります。レッスン5は右方向へシフ

トし、carryビットが「1」かどうかを検査して「1」なら最初に戻って同じ点灯パター

ンを繰り返していました。レッスン7では、両方向へのローテートが必要で、左方向 へローテートする場合はbit 4が「1」かどうかを検査する必要があります。LATCの

bit 4に「1」が表れたら、これをbit 0に反映します。

3-6: レッスン7のプログラムのフロー

Get ADC Measurement

Delay Using ADC Result

Delay 5ms

Is Switch Still Down?

Check if ADC Result is ‘0’

Is Switch Down?

Change Direction YES

YES

NO Main Init

Was It Held Down Previously?

Rotate LEDs to Left Rotate LEDs to Right

Left Direction

YES NO

YES NO

NO

PICkit™ 3 スタータキット ユーザガイド

DS41628B_JP - p.66  2015 Microchip Technology Inc.

このレッスンでは、スイッチを長押しした場合でも正しく動作するように、デバウン ス ルーチンでより複雑な処理を実行しています。何も対処をせずSW1を長押しする と、LEDのローテート方向が次々と変化し、制御が不安定になったかのような印象を 与えます。上記のフローチャートでは、スイッチを長押しした場合は最初に押し込ん だ時だけ方向を変え、いったんスイッチを離して再び押し込まれるまではスイッチの 状態を無視しています。スイッチは、プログラムがスイッチの状態を検査するループ 処理を完了するまでは押し続けておく必要があります。ここではPIC MCUの動作速

度が500 kHzであるため、その時間はごくわずかです。

3.8.4 新しく学ぶレジスタ

なし

3.8.5 新しく学ぶ命令

3.8.5.1 PIC18

3.8.5.1.1 RLNCF

carryビットを使わずにビットを左へローテートします。直前のMSbがそのままLSb

に入ります。一般に、これを循環シフトと呼びます。

3-7: RLNCF

3.8.6 アセンブリ

3.8.6.1 エンハンストミッドレンジ

3-30:

以前のレッスンでは、点灯したLEDが左端から押し出されたかどうかをcarryビット を検査して調べていましたが、ここではラッチを左方向へシフトしているため、

LATC4 を検査します。LATC4 には何も接続されておらず、このビットがセットされ

ていれば直前までDS4が点灯していた事を意味します。このためDS1を点灯し、最 初から同じ点灯パターンを繰り返す必要があります。PIC18 のコードも同様ですが、

lslfの代わりにrlncfを使っています。

3.8.6.2 PIC18

PIC18の場合はcarryビットがセットされていると複数のLEDが同時に点灯してしま

うため、常にcarryビットがクリアされている事を確認する必要があります。

3-27:

命令 英語名 目的

RLNCF Rotate Left f (no carry) ビットを左方向へシフトする

7 6 5 4 3 2 1 0

0 0 0 1 0 1 1 1

0 0 1 0 1 1 1 0

MSb LSb

RotateRight:

lslf LATC, f ;logical shift left

btfsc LATC, 4 ;did it rotate out of the LED display?

bsf LATC, 0 ;yes, put in bit 0 bra MainLoop

3-31:

3.8.7 C言語

3.8.7.1 両デバイス共通

このコードでは、グローバル変数を使っています。ローカル変数とは異なり、グロー バル変数には関数のスコープがなく、この変数を宣言したソースファイル内の全ての 関数から呼び出す事ができます。グローバル変数である事が分かるように、変数名の 先頭にアンダースコア(_)を付ける等のコーディング作法を推奨します。

このバイト値はcheck_switch関数で変更され、その結果がメインループに返され ます。

3-32:

変数delayとdirectionがmainの内側で宣言されている事に注意してください。これ

らは main の外側では変更できません。また、check_switchからメインループへ はchar型符号なしバイトが1つ返されます。Cでは1つの変数しか返す事ができません。

RotateLeft:

bcf STATUS, C ;clear the carry

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?)

bra MainLoop

bsf LATC, 3 ;yes, it did and now start the sequence over again by turning on DS4 bcf STATUS, C ;clear the carry

bra MainLoop ;repeat this program forever

unsigned char _previous_state = SWITCH_UP; //global variable

void main(void) {

unsigned char delay;

unsigned char direction;

...

}

unsigned char check_switch(void){

...

..

}

PICkit™ 3 スタータキット ユーザガイド

DS41628B_JP - p.68  2015 Microchip Technology Inc.

ドキュメント内 PICkit 3 Starter Kit User’s Guide (ページ 65-68)