AVRホタル

暗いところに持っていくと点滅します。
部品はtiny2313とLEDを1個ずつ。
LEDを光センサーとして使っています。





// AVR Hotaru

#include <avr/io.h>
//#include <avr/interrupt.h>
#include <util/delay.h>
#define nop() __asm__ __volatile__ ("nop")


#define SERIAL_DEBUG 0
#if SERIAL_DEBUG
  #define BAUD 2400
//#define SET_PORT(PORT, MASK, VALUE) PORT = (VALUE & MASK)|((~MASK) & PORT)
  void usart_init(void)
  {
    #define _UBRR (F_CPU/16/BAUD-1)
    UBRRH = _UBRR>>8;
    UBRRL = _UBRR;
    UCSRB = 0b00011000;
    UCSRC = 0b00000110;
  }
#endif

#define LED_DEBUG 1

int main(void)
{
  char ac0;
  int count    = 0;
  int on_count = 0;
  int on_rate  = 0;
  int i,j,k;
  int bright   = 0;
  int led_on   = 1;

#if SERIAL_DEBUG
  usart_init();
#endif

#if LED_DEBUG
  DDRD  = 0b01111100;
  PORTD = 0b00000000;
#endif

  for(;;){
    // 参考) http://elm-chan.org/junk/leddet/report.html
    // LEDポートに短時間"L"レベルを出力して接合容量Cjや浮遊容量Csを放電する。
    DDRB  = 0b00000001;
    PORTB = 0b00000000;
    _delay_ms(1);

    // LEDポートを入力に設定する→光電流により容量が充電され、入力電圧が直線的に上昇してくる。
    DDRB  = 0b00000000;
    PORTB = 0b00000000;

    // 4ms待ってから入射有りか判断
    _delay_ms(4);
    ac0 = ACSR & 0b00100000;
    if(ac0){
      on_count++;
    }
    count++;
    if(50<=count){
      on_rate  = 100*on_count/count; // 50サンプル取って平均
      count    = 0;
      on_count = 0;
    }

#if SERIAL_DEBUG
    while(!(UCSRA & 0b00100000));
    UDR = ac0 ? '*' : '.';
#endif

#if LED_DEBUG
    {
      unsigned char d = 0;
      if(on_rate<45){ d |= (1<<2); }
      if(on_rate<40){ d |= (1<<3); }
      if(on_rate<35){ d |= (1<<4); }
      if(on_rate<30){ d |= (1<<5); }
      if(on_rate<25){ d |= (1<<6); }
      PORTD = d;
    }
#endif

    DDRB  = 0b00000001;
    if(0){
      // 閾値でON/OFF
      if(on_rate<20){
        PORTB = 0b00000001;
      }else{
        PORTB = 0b00000000;
      }
      _delay_ms(30);
    }else{
      // 明るさ 0-100,100-0 のこぎり型に明滅
      int b;

      bright++;
      b = bright;
      if(100<bright){
        b = 200-bright;
        if(200<bright){
          bright = 0;
          led_on = (on_rate<20);
        }
      }

      //b = 100-on_rate;
      for(j=0; j<10; j++){
        if(led_on){
          PORTB = 0b00000001;
        }
        for(i=0; i<b; i++){
          _delay_ms(0.01);
        }

        PORTB = 0b00000000;
        for(i=0; i<100-b; i++){
          _delay_ms(0.01);
        }
      }
    }
  }
}