PICとメカな日々

Webにも萌えにも限界を感じたオタクがPICマイコンをいじる日々。

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

チャタリング対策

 PORTBの出力からLEDを点灯させるのはうまくいったので、こんどは入力のほうを試してみる。

 そろそろ回路図を書かないとヤマカンではユニバーサル基盤の配線がわけわからん様になってきたので、回路図CADのBSshをダウンロード。

水魚堂の回路図エディタhttp://www.suigyodo.com/online/schsoft.htm

 これのライブラリにPIC16F84などのPICチップも入ってるので、かなり楽に回路図を書くことが出来る。これを出力しておけば配線するときもおおむね悩まないで済む。

 しかしユニバーサル基盤の使い方ほとんど忘れてるし、ずいぶんハンダ付けの腕も落ちたなあ。10年以上ブランクがあるとやっぱ大変だわ。

今回の回路図

 配線はほどなく完成したが、ソフトウェアでスイッチの入力を処理する際には単純に

if(RA0){
  hogehoge
}

 みたいな訳にはいかない。スイッチにはチャタリングというもんがあって、入力された瞬間に何度かon/offを繰り返す性質がある。
 いくつか参考書読んだりして、とりあえずもっとも処理が簡単そうな「スイッチがonになった→30ミリ秒待つ→やっぱりスイッチがonなら処理」という方式をとる事にした。

 例によってコンパイルのあとICPROGでPICに転送して実験。RA0につながったスイッチを押す→PORTBにつないである8ビット分のLEDがカウントアップ。RA1のスイッチを押す→カウントダウンということでおおむね成功。

 今回のソースコードはこんな感じ。

/*
  スイッチのテスト
  RA0のスイッチを押すたびにPORTBの出力をインクリメント
  RA1のスイッチを押すとPORTBの出力をデクリメント
*/
#include<pic.h>
#include<delay.h>
__CONFIG(0x3FF2);        //CONFIG:CP=OFF,PWRT=ON,WDT=OFF,OSC=HS
unsigned char led_outdata=0;  //出力データを初期化
void main(void)
{
  OPTION=0b00000000;     //オプションレジスタ
  INTCON=0b00000000;     //割り込みレジスタ
  PORTA=0b00000000;      //PORTAをリセット
  PORTB=0b00000000;      //PORTBをリセット
  TRISA=0b00000011;      //RA0,RA1を出力に設定
  TRISB=0b00000000;      //PORTBを出力に設定
  while(1)               //無限ループ
  {
    if(RA0){         //RA0が押されたときの処理
      DelayMs(30);     //チャタリング待ち
      if(RA0){
        led_outdata++;            //インクリメント
        led_outdata=led_outdata % 256 ; //8ビット以内の表示
        PORTB=led_outdata;       //PORTBに出力
      }
      while(RA0)
        {}                 //swがoffになるまで待つ
      DelayMs(100);            //も一回押すには0.1秒待ち
    }

    if(RA1){                  //RA1が押されたときの処理
      DelayMs(30);            //チャタリング待ち
      if(RA1){
        led_outdata--;         //デクリメント
        led_outdata=led_outdata % 256 ; //8ビット以内の表示
        PORTB=led_outdata;       //PORTBに出力
      }
      while(RA1)
        {}                 //swがoffになるまで待つ
      DelayMs(100);            //も一回押すには0.1秒待ち
    }
  }
}



 実際には完成したあとで某氏から指摘を受けたが、PORTA,PORTBの初期化はTRISA,TRISBレジスタの初期化よりも先にやらないといかんらしい。電源を入れた瞬間のPORTA,PORTBの値は不定なので、入出力の向きをTRISレジスタで指定する前に初期化しておかないと、TRISレジスタで入出力を指定したときに妙な値が出力されて妙なことになる恐れがあるらしい。今回みたいにつながってるのがLEDだけなら良いが、もっと重要なもんがつながってる場合を考えると先にデータの方を初期化しないといかんと。またひとつ勉強になった。
スポンサーサイト

コメント

中国酒

中国酒を探すなら http://www.takeonemusik.com/510915/201344/

  • 2008/09/15(月) 12:48:17 |
  • URL |
  • #-
  • [ 編集]

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバックURLはこちら
http://dmidorikawa.blog39.fc2.com/tb.php/9-9c13c786
この記事にトラックバックする(FC2ブログユーザー)

FC2Ad

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。