2014/12/03

16F88 XC8開発例 - ロータリスイッチの状態をA/D変換で取得する

概要
はじめに

前回の記事「Arduino - ロータリスイッチの状態をA/D変換で取得する」と同様の回路を,PIC16F88とMPLAB XC8 C Compilerを使用して実装する方法を紹介します. この開発例では,PIC16F88のA/D変換モジュールによるA/D変換と,AUSARTモジュールによる調歩同期式シリアル通信を行っています. 開発環境は下記のとおりです.

PIC PIC16F88-I/P
MPLAB X IDE MPLAB X IDE v2.26
MPLAB XC8 MPLAB XC8 C Compiler v1.32
PICkit 2 MPLAB X IDEを使用して書込み
通信仕様

通信仕様は下表のとおりです. 本記事では詳細は説明しませんが,今回はUSBシリアル変換モジュールを経由してPICとPCとの間で調歩同期式シリアル通信を行いました. 調歩同期式シリアル通信について調べる場合は,「RS-232C」や「UART」をキーワードに検索してみてください.

ボーレート 9,600 bps
データビット 8 bit
パリティビット なし
ストップビット 1 bit
フロー制御 なし
回路
回路図

PDFファイルにて公開します.

PICkit 2を使用してICSP (In Circuit Serial Programming)と電源供給を行うことを前提とした回路です. 今回は,これをブレッドボード上に組んで動作を確認しました.

ロータリスイッチ SW1の共通接点Aは,グランドに接続されています. 一方,PIC16F88のAN0ピンは,常にSW1の選択接点1に接続されています. スイッチを回転させると,合成抵抗の分圧比が変化し,アナログ入力ピンに印加される電圧が変化します. この変化を読み取ることで,SW1の状態を取得できます.

仮に共通接点Aがいずれの選択端子にも接続されていない状態になっても,AN0ピンは抵抗 R1でプルアップされている状態となり,ハイインピーダンスにはなりません.

回路部品

下表は使用部品表です. 参考単価をクリックすると,秋月電子通商のページに飛びます. 「互換品」と記載されているリンクについては,互換性があると考えられる部品のページに飛びます. ただし,私が互換性および動作を確認したわけではありませんので,ご注意ください.

番号 部品名 型番 数量 参考単価
U1 PICマイコン Microchip PIC16F88-I/P 1 250円
U2 USBシリアル変換
モジュールキット
秋月電子通商 AE-UM232R 1 800円
X1 セラロック 村田製作所 20MHz 1 35円
SW1 ロータリスイッチ 1回路12接点
ノンショーティングタイプ
1 150円
(互換品)
R1 炭素皮膜抵抗 各社 1/4W 10kΩ 1 1円
(互換品)
R2, R11 炭素皮膜抵抗 各社 1/4W 4.7kΩ 2 1円
(互換品)
R3 炭素皮膜抵抗 各社 1/4W 470Ω 1 1円
(互換品)
R4 炭素皮膜抵抗 各社 1/4W 680Ω 1 1円
(互換品)
R5 炭素皮膜抵抗 各社 1/4W 820Ω 1 1円
(互換品)
R6 炭素皮膜抵抗 各社 1/4W 1kΩ 1 1円
(互換品)
R7 炭素皮膜抵抗 各社 1/4W 1.2kΩ 1 1円
(互換品)
R8 炭素皮膜抵抗 各社 1/4W 1.5kΩ 1 1円
(互換品)
R9 炭素皮膜抵抗 各社 1/4W 2.2kΩ 1 1円
(互換品)
R10 炭素皮膜抵抗 各社 1/4W 3kΩ 1 1円
(互換品)
R12 炭素皮膜抵抗 各社 1/4W 8.2kΩ 1 1円
(互換品)
R13 炭素皮膜抵抗 各社 1/4W 15kΩ 1 1円
(互換品)
その他 リード線など 適量
回路製作例

ロータリスイッチ周辺の配線については,前回の記事の「回路製作例」で紹介しています.

プログラム
A/D変換値からロータリスイッチの状態を取得する方法

まず,ロータリスイッチの各状態における,AN0ピンへの印加電圧を計算してみましょう. 計算結果を下表に示します. 下表から,例えば選択接点2の場合は,AN0ピンへの印加電圧が0.455Vになることがわかります. PIC16F88のA/D変換の分解能は10bit(0~1023)ですから,A/D変換値は93になると考えられます. ただし,電源電圧や抵抗値の公差により,各値は多少変動します.

これらの計算結果を基に,A/D変換値と閾値を比較することで,ロータリスイッチの状態を割り出します. 例えば,選択接点が3以下か4以上かを調べるためには,各状態におけるA/D変換値(201と302)の中間値(252)を閾値にします. このような比較処理を繰り返すことで.選択接点が特定できます.

ロータリスイッチの選択接点とアナログ入力ピンへの印加電圧の関係
選択接点 印加電圧 [V] A/D変換値(10bit)
1 0.000 0
2 0.455 93
3 0.983 201
4 1.477 302
5 1.936 396
6 2.351 481
7 2.734 560
8 3.130 641
9 3.491 715
10 3.841 787
11 4.175 855
12 4.459 910
main.c

下記は,ソースファイル main.cです. このほかに,「16F88 XC8開発例 - 調歩同期式シリアル通信(AUSARTモジュール)」に掲載している,uart.cuart.hが必要です.

A/D変換値からロータリスイッチの状態を取得する,getRotarySwStatus()関数を作成しました. これは,前回の記事で紹介した,Arduinoのスケッチから移植した関数です. 復帰値1~12でロータリスイッチの状態を,復帰値0で取得エラーを示します.

getRotarySwStatus()関数内の条件分岐処理がif文の入れ子構造になっているのは,ロータリスイッチの状態によって関数内の処理時間が変動しないようにしたかったためです. この関数では,ロータリスイッチがいずれの状態であっても条件分岐処理が3回以内になっています. よりスマートなやり方があるのだとは思いますが….

製品紹介
超小型ブレッドボード(青)
SparkFun
売り上げランキング: 369,705

0 件のコメント:

コメントを投稿