8ピンPIC(12F683)を使って16進カウンタを製作しました。
タクトスイッチを押す度に、4つの青色LEDで表される4桁の2進数が1ずつ増えていく、というものです。
前記事ではGP端子を入力用として使っていなかったので、今回は入力用としても使う練習です。
使用機器・ソフト
- 8ピンPIC(12F683)
- PICkit3
- MPLAB ver.8.80
- Hi-TECH Cコンパイラ ver.9.83
実験内容
前回と同じようにPICkit3接続&MPLAB起動。
ここで、以下のプログラムを書き込みました。
#include <htc.h> __CONFIG(FOSC_INTOSCIO & WDTE_OFF & PWRTE_ON & BOREN_ON & MCLRE_OFF & CP_OFF & IESO_OFF & FCMEN_OFF); #define _XTAL_FREQ 1000000 #define PREV_CHATTR_T 300 //チャタリング防止時間(ms) #define DIGITS_NUM 4 //桁数 void main() { OSCCON = 0x40; ANSEL = 0; CMCON0 = 0x07; TRISIO = 0x08; int count=0, buff, i, max=1; int binaryDigits[DIGITS_NUM]; //2進数データ GP0=GP1=GP4=GP5=0; //リセット for (i=0; i<DIGITS_NUM; i++) //桁あふれ時のカウントを算出 max *= 2; while (1){ if (!GP3){ //ボタン押されたとき count++; if (count==max) count=0; buff=count; for (i=0; i<DIGITS_NUM; i++){ //10進数→2進数 binaryDigits[i]=buff%2; buff /= 2; } GP0=binaryDigits[0]; GP1=binaryDigits[1]; GP4=binaryDigits[2]; GP5=binaryDigits[3]; for (i=0; i<PREV_CHATTR_T; i++) //チャタリング防止 __delay_ms(1); } } }
math.hをincludeしてpow関数を使うと謎のエラーが発生するため、桁あふれ寸前の値maxの値はfor文で求めています。(pow関数の引数の型はちゃんとdoubleにして渡したのにエラー。sin関数など他のmath関数は使えたのにpowはエラー。原因不明。)
また、最初はGP3がHレベルのときにカウントさせる仕様にしてたんですが、PICの入力端子は開放状態だと常にHレベルになるとのこと。これは内部にプルアップ抵抗があるからだとかなんとか。
そこで、電源から10kΩの抵抗を挟み、さらにタクトスイッチを押した時にGNDにつながるようにしました。ここでプルアップ抵抗を10kΩ、タクトスイッチの抵抗が10Ωと仮定して入力電圧Vinを計算し、正常に動作するかを確かめます。
タクトスイッチを離してるときは、Vin={10k/(10k+10k)}5=2.5[V]
タクトスイッチを押してるときは、タクトスイッチとプルアップ抵抗の合成抵抗Ro=10k*10/(10k+10)=9.9[Ω]、Vin={9.9/(10k+9.9)}5=0.00098[V]
TTL-ICのスレッショルド電圧はだいたいVH=2.0[V], VL=0.8[V]です。
したがってタクトスイッチを離してるときはVin>VH、押してるときはVin<VLとなり、正常に動作します。
で、動作してる様子の動画↓
感想
タクトスイッチからの入力の部分に苦しみました。プルアップ抵抗内蔵のこととかもほとんど初めて知りました。
電子回路についての基本的な知識が欠けてることを実感します。