avr-gcc で工作(そのA)
avr-gcc で工作(そのA)
ブザーつけました。モノは秋月電子で売られているコレです。PORTBのPB4に DTC144E でオープンコレクタで VCC0 を掛ける形で接続しています。今回は回路図は省略*1。あ、消費電流を測らなくては…
これを使って、ロータリエンコーダを回すとクリック音が出るようにしてあります。経験的に 10msec ぐらいの長さをクリック音長として採用しました。
また同時にロータリエンコーダによる変化が遅れて有効となるような仕組みを入れてあります。これは、最終的な出来上がりでは制御される先にメカニカル・リレーが付くためです。ロータリエンコーダをぐりぐり回してその都度リレーがガチガチ言っていては心臓に良くないので、値が確定してから0.5秒ぐらいのちに有効となるようにしています。ここでは有効となったら PA0 の LED と 7セグメントLEDの一の位の dot を光らせるようにしています。
べたクロックでポートに出力*2したりして汚いですが、UIの実験と割り切って目を瞑ります*3。
今後、ハードウェア的にやることは、
の付加です。ケースの設計/加工と足並みを揃えながら進める予定です。
以下ソースコード
/* 7seg. LED w/ Rotary Encoder */ #include#include #include #include #define RENC_DELAY_LEN 500; #define SOUND_CLICK 10; enum { LOW, HIGH, EDGE } ; volatile uint8_t num = 128; uint8_t DIGIT[] = { 0x03, 0x9F, 0x25, 0x0D, 0x99, 0x49, 0x41, 0x1B, 0x01, 0x09 }; volatile uint8_t renc = HIGH; volatile uint16_t renc_delay_cnt = RENC_DELAY_LEN; volatile uint8_t click = 0; /* PB5 serial data PB6 latch clock PB7 shift clock */ void send7seg (uint8_t dat) { int i; for (i = 0; i < 8; i++, dat >>= 1) { if (dat & 0x01) sbi(PORTB, PB5); else cbi(PORTB, PB5); sbi(PORTB, PB7); cbi(PORTB, PB7); } } void load7seg (void) { sbi(PORTB, PB6); cbi(PORTB, PB6); } void send (uint8_t dat, uint8_t dot) { if (dot) send7seg(DIGIT[dat % 10] & 0xFE); else send7seg(DIGIT[dat % 10]); send7seg(DIGIT[(dat/10) % 10]); send7seg(DIGIT[dat / 100]); load7seg(); } SIGNAL (SIG_OVERFLOW1) { TCNT1 = 65536 - 1000 + 1; if (renc == EDGE) { if (bit_is_clear(PIND, PD3)) { // true falling edge renc = LOW; if (bit_is_clear(PIND, PD4)) { num++; } else { num--; } send(num, 0); renc_delay_cnt = RENC_DELAY_LEN; click = SOUND_CLICK; } else { renc = HIGH; } } else { if (bit_is_clear(PIND, PD3)) { if (renc == HIGH) renc = EDGE; else renc = LOW; } else { renc = HIGH; } } if (renc_delay_cnt) --renc_delay_cnt; else send(num, 1); if (click) { sbi(PORTB, PB4); --click; } else { cbi(PORTB, PB4); } } void ioinit (void) { DDRA = _BV (PA0); DDRB = _BV (PB4) | _BV (PB5) | _BV (PB6) | _BV (PB7); TCCR1B = _BV (CS11); TCNT1 = 65536 - 1000; timer_enable_int (_BV (TOIE1)); cbi(PORTA, PA0); cbi(PORTB, PB4); sei(); } int main(void) { ioinit(); send(num, 0); for (;;) { if (!renc_delay_cnt) { sbi(PORTA, PA0); } else { cbi(PORTA, PA0); } } return 0; }