第2回 スイッチを使ってみよう

このページは、わたしの備忘録として作成しました。

[Home] [目次] [前頁] [次頁]


(1) スイッチを使ってみる

前回では、PICを使ってLEDを点滅させることができましたので、今回は、PICへのユーザーインターフェースのひとつ、入力装置としてスイッチを使ってみたいとおもいます。

スイッチといっても、スライドスイッチ、トグルスイッチ、プッシュボタンスイッチ、タクトスイッチ、キースイッチ、ロータリスイッチ、DIPスイッチなど、用途にあわせておおくの種類があります。今回は、6ミリ角のタクトスイッチを使います。タクトスイッチは、リードがあらかじめ曲げられている、リードフォーム加工済みのものがおおいので、リードをペンチでまっすぐにしてブレッドボードの穴にはいるようにします。

スイッチの実験ボード

GP3は、10kオームの抵抗で+5Vにプルアップされ、タクトスイッチでGNDに接続されています。GP3は、タクトスイッチのボタンを押さない状態では+5V、ボタンを押すと0Vになります。このボタンを押している間だけ、GP0に接続されたLEDを点灯させてみようとおもいます。今回は、GPIOレジスタの現在の内容をBTFSCBit Test File, Skip if Clear)命令をつかってチェックします。GP3は+5Vにプルアップされていますので、GPIOレジスタのビット3はタクトスイッチのボタンを押さなければHigh、すなわち 1 と読まれ、アドレスがBTFSCから1つ進みます。ボタンを押せば、GP3の電位は0Vになりますので、Low、すなわち 0 と読まれ、BTFSCのつぎのアドレスを1つ飛ばして(スキップして)進みます。

下記は、タクトスイッチのボタンを押している間だけLEDが点灯するプログラムです。

12F509_SW1.asm

1

LIST

P = 12F509

; プロセッサの種類を指定

2

#INCLUDE

<P12F509.INC>

; プロセッサのインクルードファイルを指定

3

__CONFIG

0x0A

; このように記述することもできます

4

; 外部リセットを使用しない

5

; コードプロテクトしない

6

; ウォッチドッグタイマを使用しない

7

; 内蔵クロックを使用する

8

ORG

0x000

; プログラム実行開始番地

9

MOVWF

OSCCAL

; OSCCALレジスタを更新

10

MOVLW

0x08

; GP3を入力ポート、他は出力ポートに設定

11

TRIS

0x06

; f=6

12

MOVLW

0xDF

; T0CSはゼロ、GP2を出力ポートに

13

OPTION

; OPTIONレジスタに書き込む

14

GP0_OFF

MOVLW

0x00

; Wにb'000000'を格納して、それを

15

MOVLW

0x06

; GPIOレジスタ(0x06番地)に書き込む

16

SW1

BTFSC

GPIO,3

; GPIOのビット3がLowのとき、アドレスを2つ進める

17

GOTO

GP0_OFF

; アドレスを2つ進める

18

GP0_ON

MOVLW

0x01

; Wにb'000001'を格納して、それを

19

MOVWF

GPIO

; GPIOレジスタ(0x06番地)に書き込む

20

GOTO

SW1

; おなじことを繰り返す

21

END

; プログラムはここで終了

ダウンロード
12F509_SW1.asm

このプログラムを実行すると、ボタンを押している間だけLEDが「点灯しているようにみえます」。しかし、実際は、ボタンを押してから数ミリ秒の間、LEDは点滅しているのです。前回の「LEDを点滅させよう」のところでためしたように、ボタンを押してからLEDが点灯、消灯を高速にくりかえしていても、網膜の残像でLEDが点灯しつづけているかのようにみえるのです。これは、スイッチのボタンを押したりはなしたときに、スイッチの接点には弾性があるので、一瞬の間、バウンド(反跳、バウンス)して開閉を繰り返す、チャタリング(Chattering)がおきるためです。

ためしに、チャタリングがおきていることをたしかめるためのプログラムをつくってみました。下記のプログラムを実行すると、タクトスイッチのボタンを押すタイミングによっては、LEDが点灯しないことがあります。

ダウンロード
12F509_SW2.hex


チャタリングの防止

チャタリングは、蛍光灯のスイッチでは使用上の不都合はなくても、1回ボタンを押すと1個ではなくて2個以上のパルスが発生するということですから、デジタル回路では不都合が生じるかもしれませんね。このチャタリングを防止するには、スイッチからの入力部分に、CR時定数をチャタリングの継続時間より多くした波形整形回路を追加するか、PICのプログラムでスイッチの入力判定にチャタリングの継続時間より多めの遅延時間をとる必要があります(注:ストップウォッチのような用途では、スイッチの入力判定の遅延時間をとってしまうと、不具合が生じる場合もあります)。

チャタリング防止回路の一例

上記以外にもさまざまなチャタリング防止回路があるようです。

ここでは、外つけ部品を増やすのはめんどうですので、プログラムで処理することにしました。実験ボードで使用しているタクトスイッチの場合、データシートではチャタリングの時間は5ミリ秒以下と記載されていました。他のメーカーでもだいたいおなじようです。それで、スイッチ入力判定用の遅延時間を5ミリ秒にしたプログラムを考えてみました。しかし、いざ実行してみると、「チョイ押し」のような、ボタンの押し方によってはしばしば誤作動しました。ボタンを押したときとボタンをはなしたときの両方で接点がバウンスしているようです。それで、入力判定の遅延時間をボタンをはなしたときもふくめて倍以上長くして、タクトスイッチのような押しボタンスイッチ以外でも対応できるように、20ミリ秒に変更してみたところ、誤作動はなくなりました。

ボタンを押すと、GP0につないだLEDが点灯し、もういちどボタンを押すとLEDが消灯するプログラムです。ボタンの押し下げによるトグルの判定時間を長くするとLEDの点灯・消灯まで間延びする感じがしましたので、200ミリ秒でトグルの判定をするようにしました。したがって、ボタンをそれ以上の時間押しつづけると、LEDは点滅することになります。期待どおりにPICが動くと、うれしいものですね。もっとスマートなコードが書ければいいのですが、あせらずに一歩一歩勉強していくことにしましょう(FENG3曰、「吾五十而志於学」…がんばろう!)。今回はここまで。

12F509_SW3.asm

1

LIST

P = 12F509

; プロセッサの種類を指定

2

#INCLUDE

<P12F509.INC>

; プロセッサのインクルードファイルを指定

3

__CONFIG

0x0A

; このように記述することもできます

4

; 外部リセットを使用しない

5

; コードプロテクトしない

6

; ウォッチドッグタイマを使用しない

7

; 内蔵クロックを使用する

8

i

EQU

0x07

; ループカウンタの変数の定義

9

j

EQU

0x08

; ループカウンタの変数の定義

10

k

EQU

0x09

; ループカウンタの変数の定義

11

ORG

0x000

; プログラム実行開始番地

12

MOVWF

OSCCAL

; OSCCALレジスタを更新

13

MOVLW

0x08

; GP3を入力ポート、他は出力ポートに設定

14

TRIS

0x06

; f=6

15

MOVLW

0xDF

; T0CSはゼロ、GP2を出力ポートに

16

OPTION

; OPTIONレジスタに書き込む

17

START

MOVLW

0x00

; Wにb'000000'を格納して、それを

18

MOVWF

GPIO

; GPIOレジスタ(0x06番地)に書き込む(LED消灯)

19

BTFSC

GPIO,3

; ボタンが押されるまで待つ

20

GOTO

$-1

; 上記のループ

21

MOVLW

.20

; ボタンが押されたら

22

MOVWF

i

; バウンシングが収束するまで

23

CALL

DELAYms

; 20ミリ秒待つ

24

BTFSC

GPIO,3

; ボタンが押されているか

25

GOTO

$-6

; 押されていなければもういちど繰り返す

26

MOVLW

.200

; ボタンのトグル判定時間

27

MOVWF

i

; 200ミリ秒

28

CALL

DELAYms

; 待つ

29

LED_ON

MOVLW

0x01

; LEDを

30

MOVWF

GPIO

; 点灯させる

31

BTFSC

GPIO,3

; ボタンが押されるまで待つ

32

GOTO

$-1

; 上記のループ

33

MOVLW

.20

; ボタンが押されたら

34

MOVWF

i

; バウンシングが収束するまで

35

CALL

DELAYms

; 20ミリ秒待つ

36

BTFSC

GPIO,3

; ボタンが押されているか

37

GOTO

$-6

; 押されていなければもういちど繰り返す

38

MOVLW

.200

; ボタンのトグル判定時間

39

MOVWF

i

; 200ミリ秒

40

CALL

DELAYms

; 待つ

41

GOTO

START

; はじめにもどってLEDを消灯、以後繰り返し

42

INCLUDE

delayms.inc

; 遅延ルーチンのインクルードファイルを指定

43

END

; プログラムはここで終了

ダウンロード
12F509_SW3.asm
delayms.inc

注: ソースファイルのコメントが上記とことなる場合があります

ダウンロード
12F509_SW3.hex

[Home] [目次] [前頁] [次頁]


2005年3月15日作成