PICとメカな日々

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

スポンサーサイト

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

とりあえずバイナリ時計作った。

 なんとなく時計でも作るかと思って、検索したらどっかのページにあった2進数時計を作ってみる。

 bin_clock


16F84のポートほぼ全部を使って、4×6のLEDマトリックスを動かしてる。PORTBの0~3が4ビットの表示、残りをシンク側の桁ドライブと時刻調整のスイッチに使用。
 最初はトランジスタで桁ドライブしてやらんとうごかんかと思ったが、よく考えたらシンク電流が25mAとれるので、4ビット同時点灯としても5mAくらいは流せるんだった。実際には0~9までの表示しかないから同時点灯は3つまで。てことは7mAくらいでもOK。よって、

 LEDの電圧降下=1.5V
 LED電流=7mA
 LED抵抗=(5.0V-1.5V)÷7mA=500Ω

となる。

 クロックは本当は水晶にしないといかんのだろうけど、あとで取り替える事にして当面10Mhzのセラロックを使う。2^nじゃないクロックだからプログラムが面倒だが。

 回路図はこう。

binary_clock


プログラムはコレ。長くてスマン。

 ちなみにまだ出来たばっかりで、致命的なバグがあるかもしれんのでこれをコピーして同じもん作るとか考えたりしないように>見てる人

/*

  時計の習作 PIC16F84使用
  10Mhzセラロック仕様
  
*/
#include<pic.h>
#include<delay.h>
__CONFIG(0x3FF2);        //CONFIG:CP=OFF,PWRT=ON,WDT=OFF,OSC=HS

void display(void);
void time_adjust(void);

unsigned long timer_count=0;  //タイマ定数設定
unsigned char hour=0;
unsigned char min=0;
unsigned char sec=0;
void main(void)
{
  PSA=0;          //プリスケーラを使用する
  PS2=1;
  PS1=0;
  PS0=0;          //プリスケーラは1:32

  T0CS=0;          //クロックソースは内部命令サイクル
  TMR0=0;          //TMR0をリセット
  T0IF=0;          //T0IFをリセット
  
  T0IE=1;          //TMR0割り込み発生を許可
  GIE=1;          //割り込みを許可
  
  PORTA=0b00000000;      //PORTAをリセット
  PORTB=0b11110000;      //PORTBをリセット
  TRISA=0b00000000;      //RAを出力に設定
  TRISB=0b11100000;      //RB5,6,7を入力に設定
  
  PORTA=0b00000000;      //PORTAをリセット
  PORTB=0b11110000;      //PORTBをリセット

  while(1)          //無限ループ
  {
    display();        //時刻表示
    time_adjust();      //時刻調整
  }
}

void display()          //時刻表示ルーチン
{
  //hourの10の桁
  PORTA=0b00011111;      
  RB4=1;            //全列OFF

  PORTB = (0xF0 & PORTB) | (0x0F & (hour/10));    //PORTBの下4bitにhourの10の桁出力
  RB4=0;            //hourの10の桁ON
  DelayMs(1);
  
  //hourの1の桁
  PORTA=0b00011111;      
  RB4=1;            //全列OFF
  
  PORTB = (0xF0 & PORTB) | (0x0F & (hour%10));    //PORTBの下4bitにhourの1の桁出力
  RA4=0;            //hourの1の桁ON
  DelayMs(1);
  
  //minの10の桁
  PORTA=0b00011111;      
  RB4=1;            //全列OFF
  
  PORTB = (0xF0 & PORTB) | (0x0F & (min/10));    //PORTBの下4bitにminの10の桁出力
  RA3=0;            //minの10の桁ON
  DelayMs(1);
  
  //minの1の桁
  PORTA=0b00011111;      
  RB4=1;            //全列OFF
  
  PORTB = (0xF0 & PORTB) | (0x0F & (min%10));    //PORTBの下4bitにminの1の桁出力
  RA2=0;            //minの1の桁ON
  DelayMs(1);
  
  //secの10の桁
  PORTA=0b00011111;      
  RB4=1;            //全列OFF
  
  PORTB = (0xF0 & PORTB) | (0x0F & (sec/10));    //PORTBの下4bitにsecの10の桁出力
  RA1=0;            //secの10の桁ON
  DelayMs(1);
    
  //secの1の桁
  PORTA=0b00011111;      
  RB4=1;            //全列OFF
  
  PORTB = (0xF0 & PORTB) | (0x0F & (sec%10));    //PORTBの下4bitにsecの1の桁出力
  RA0=0;            //secの1の桁ON
  DelayMs(1);
}

void time_adjust()
{
  //hourのカウントアップ
  if(RB5){          //hourスイッチを見る
    DelayMs(30);      //チャタリング待ち
    if(RB5){
      hour++;
      if(hour >=24){
        hour = 0;
      }
    }
    while(RB5){      //ボタンがオフになるまで待つ
      display();    //待っている間の表示
    }
    DelayMs(50);      //も一回押すには0.05秒待ち
  }
  
  //minのカウントアップ
  if(RB6){          //minスイッチを見る
    DelayMs(30);      //チャタリング待ち
    if(RB6){
      min++;
      if(min >= 60){
        min = 0;
      }
    }
    while(RB6){      //ボタンがオフになるまで待つ
      display();    //待っている間の表示
    }
    DelayMs(50);      //も一回押すには0.05秒待ち
  }
  //secのカウントアップ
  if(RB7){          //secスイッチを見る
    DelayMs(30);      //チャタリング待ち
    if(RB7){
      sec++;
      if(sec >= 60){
        sec = 0;
      }
    }
    while(RB7){      //ボタンがオフになるまで待つ
      display();    //待っている間の表示
    }
    DelayMs(50);      //も一回押すには0.05秒待ち
  }
}

interrupt clock_count()          //割り込みルーチン
{
  if(T0IF){
    T0IF = 0;            //割り込みフラグクリア
    TMR0=131;            //TMRを125カウントに指定:256-125=131
    timer_count++;
    if(timer_count == 625){
      timer_count =0;        //タイマカウント(1sec=10M=4*32*125*625)
      sec++;
      if(sec >= 60){
        sec = 0;
        min++;
        if(min >= 60){
          min = 0;
          hour++;
          if(hour >= 24){
            hour = 0;
          }
        }
      }
    }
  }
}

スポンサーサイト

コメント

架空利益で中高年の転職

架空利益とは、本来は利益とすべきではないにもかかわらず損益計算書に利益として計上されたもののこと http://mira.ellingtonrecords.com/

  • 2008/08/31(日) 08:27:41 |
  • URL |
  • #-
  • [ 編集]

絵本作家を目指して30代,40代の転職

絵本作家は、子どもの夢や希望を膨らませる絵本の絵を描いたり、ストーリーを考える http://fandango4.misterblackband.com/

  • 2008/11/14(金) 21:08:20 |
  • URL |
  • #-
  • [ 編集]

コメントの投稿


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

トラックバック

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

FC2Ad

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