nobodyの日記

2005-01-04

[] ためし

以下にサンプルソースを書いて「続きを…」記法で格納しておきます。*1

/*
  7seg. LED w/ Rotary Encoder
 */
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

#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
     (多分、次の行で表示が切れると思う。 nobody)
*/
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;
}

*1:ついでに、注釈も書いておいてみよう。

トラックバック - http://gamma.g.hatena.ne.jp/nobody/20050104