MENU
カタログクリップ
本ページはプロモーションを含みます。

ニキシー管時計のAVR-gccソースコード

2018 11/01
広告
電子工作
2014年1月22日2018年11月1日

本体は内部RCで1 MHzで動作し、時計用タイマは外部クロック端子につながっている時計用水晶振動子の32.768 kHzで動作させています。24時間制です。

時計合わせ用にボタン2つ(←と↑)がついています。←を押すと順に1分の位、10分の位、1時間の位、10時間の位が点滅して、その位の数字が調整できます。↑を押すと、点滅している桁の数字が1つ増えます。10秒なにもボタンを押さないと元にもどります。


#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

#define TIMEOUT 10//config timeout
#define S_IDOL 0 //idol state
#define S_ONEMIN 1
#define S_TENMIN 2
#define S_ONEHOUR 3
#define S_TENHOUR 4

volatile uint8_t sec = 0;//0-60
volatile uint16_t min = 0;//0-60*(24 + 1)
volatile uint8_t confsec = 0;//0-10+alpha
volatile uint8_t state = S_IDOL;//state
volatile uint8_t red_last = 1;
volatile uint8_t white_last = 1;

int8_t display(uint16_t num);

ISR(TIMER2_OVF_vect){ //int. per 1 sec
  //count and set time
  sec++;
  if (sec >= 60){
    min++;
    sec = 0;
    if (min >= 60*24){
        min = 0;
    }
  }

  display((min / 60)*100 + min % 60);

  //config timeout
  confsec++;
  if(confsec > TIMEOUT){
    state = S_IDOL;
    confsec = 0;
  }

}


ISR(TIMER2_COMPA_vect){ //int. per 1 sec + 1/2
    //turn off -> unavailable 74141
    if(state == S_ONEMIN){
        //PB0,PD7
        PORTB |= (1 << PORTB0);
        PORTD |= (1 << PORTD7); //| (1 << PORTD6) | (1 << PORTD5));
    }else if(state == S_TENMIN){
        //PB1,2
        PORTB |= ((1 << PORTB1) | (1 << PORTB2));
    }else if(state == S_ONEHOUR){
        //PD0,1
        PORTD |= ((1 << PORTD0) | (1 << PORTD1));
    }else if(state == S_TENHOUR){
        //PC0,1
        PORTC |= ((1 << PORTC0) | (1 << PORTC1));
    }

}


ISR(PCINT1_vect){
  _delay_ms(10);
  uint8_t red_now = PINC & (1 << PINC4);
  uint8_t white_now = PINC & (1 << PINC5);

  if ((white_last != 0) & (white_now == 0)){//white pull down
    //shift state
    state++;
    if(state > S_TENHOUR){
        state = S_IDOL;
    }
    confsec = 0;
  }
  white_last = white_now;

  if ((red_last != 0) & (red_now == 0)){//red pull down
    confsec = 0;
    if(state == S_ONEMIN){
        min++;
        if(min % 10 == 0){
            min -= 10;
        }
    }else if(state == S_TENMIN){
        min += 10;
        if(min % 60 < 10){
            min -= 60;
        }
    }else if(state == S_ONEHOUR){
        min += 60;
        if((min / 60) / 10 < 2){
            if((min / 60) % 10 == 0){
                min -= 60*10;
            }
        }else{
            if((min / 60) % 10 == 4){
                min -= 60*4;
            }
        }
    }else if(state == S_TENHOUR){
        min += 60*10;
        if((min / 60) % 10 >= 4){
            if((min / 60) / 10 == 2){
                min -= 60*20;
            }
        }else{
            if((min / 60) / 10 == 3){
                min -= 60*30;
            }
        }
    }

    display((min / 60)*100 + min % 60);
  }
  red_last = red_now;
}

int8_t display(uint16_t num){
  uint8_t one = num % 10;
  uint8_t ten = (num / 10) % 10;
  uint8_t hund = (num / 100) % 10;
  uint8_t thou = (num / 1000) % 10;

  //4one DCBA -> PB0,PD7,6,5
  //3ten DCBA -> PB1,2,3,4
  //2hundDCBA -> PD0,1,2,3
  //1thouDCBA -> PC0,1,2,3
  PORTB = (((ten & 0b0001)?1:0) << 4)
    | (((ten & 0b0010)?1:0) << 3)
    | (((ten & 0b0100)?1:0) << 2)
    | (((ten & 0b1000)?1:0) << 1)
    | (((one & 0b1000)?1:0) << 0);

  PORTC = (((thou & 0b0001)?1:0) << 3)
    | (((thou & 0b0010)?1:0) << 2)
    | (((thou & 0b0100)?1:0) << 1)
    | (((thou & 0b1000)?1:0) << 0)
    | (1 << PORTC4)
    | (1 << PORTC5);

  PORTD = (((hund & 0b0001)?1:0) << 3)
    | (((hund & 0b0010)?1:0) << 2)
    | (((hund & 0b0100)?1:0) << 1)
    | (((hund & 0b1000)?1:0) << 0)
    | (((one & 0b0001)?1:0) << 5)
    | (((one & 0b0010)?1:0) << 6)
    | (((one & 0b0100)?1:0) << 7);

  return 0;
}

int8_t init(void){

//pc4(PCINT12) red, pc5(PCINT13) white
  DDRB = 0xFF;
  DDRC = 0b11001111;
  DDRD = 0xFF;
  PORTB = 0x00;
  PORTC = 0b00110000;
  PORTD = 0x00;


  ASSR   = 0b00100000; // use crystal.
  TCCR2B = 0b00000101; // 128 prescaler, timer on; 1 sec
  //TCCR2B = 0b00000100; // 64 prescaler, timer on; 1/2 sec
  //TCCR2B = 0b00000011; // 32 prescaler, timer on; 1/4 sec

  TIMSK2 |= (1 << TOIE2) | (1 << OCIE2A); // overflow and A interrupts on
  OCR2A = 0x80;

  //interrupt.
  PCICR |= (1 << PCIE1);
  PCMSK1 |= (1 << PCINT12) | (1 << PCINT13);//PCMSK1 = 0x30

  GTCCR  = 0b00000010; //timer reset
  sei(); // allow interrupts

  return 0;
}

int main(void){
  init();

  while(1){

  }
  return 0;
}

f:id:beiz23:20140122213837j:image:w360f:id:beiz23:20140126191537j:image:w360

電子工作
highlightjs

関連記事

  • 購入前に知っておきたいUSB接続・PC接続型デジタルオシロスコープの利点と欠点。スタンドアロン型との違いは。
    2018年8月9日
  • SWR値はどのくらいまで大丈夫?SWR値から分かる反射波電力の割合。
    2018年7月23日
  • アマチュア無線用SWR計の選び方とダイヤモンド・コメット・ダイワの製品一覧。おすすめは?
    2018年7月23日
  • OWONのデジタルオシロスコープSDS5032Eの基本的な使い方。
    2018年7月10日
  • PCXpresso NXP LPC1769の評価ボード(OM13000)にmbedのバイナリを書き込む方法
    2017年5月13日
  • L, Cを測ることを考える
    2014年8月10日
  • Raspberry piで大気圧と温度を記録してグラフにして他のPCからグラフを見る
    2014年7月26日
  • raspberry pi を使って何かするメモ。
    2014年7月26日
カテゴリー
  • コンピューター
    • gnuplot & eps
    • mac
    • matplotlib
    • wordpress
  • ホーム・家電
    • アイロン
    • オーディオ
    • オーラルケア
      • ジェットウォッシャー
      • 音波振動歯ブラシ
    • カメラ
    • カー用品
    • クリーナー
    • テレビ、レコーダー
    • ドアホン
    • メンズ美容家電
      • ラムダッシュ
    • ルンバ
    • 一覧比較
    • 工具
    • 浄水器
    • 温水洗浄便座
    • 炊飯器
    • 空気清浄機・加除湿機
    • 空調・季節家電
    • 美容家電
      • フェイスケア
      • ヘアケア
      • ボディーケア
    • 血圧計
    • 調理器具
    • 電子レンジ
  • 健康
  • 家事
    • パン
    • 料理
    • 育児
    • 食品
      • おせち
      • コーヒー
  • 書籍
  • 知識
  • 趣味
    • ペン字
    • ロードバイク・クロスバイク
    • 車
    • 鉄道模型
    • 電子工作
サイト内検索
最近の投稿
  • モナークHGとモナークM7の4つの違い。[ニコン双眼鏡]
  • ニコン モナーク M7とM5の4つの違い。[双眼鏡]
  • Speed Wi-Fi DOCK 5G 01の実機使用レビュー。
  • RZ-760、GT-760、ST-760の違い。[ガス缶・CB缶]
  • RZ-730、RZ-730S、RZ-730SBK、RZ-730SWH、ST-Y450の違い。
  • TC-EA35WとTC-E123SBKの違いを比較。[スティッククリーナー]
  1. ホーム
  2. 趣味
  3. 電子工作
  4. ニキシー管時計のAVR-gccソースコード
  • ホーム
  • プライバシーポリシー

© カタログクリップ
contact@beiznotes.org

目次