/*-------------------------------------------------*/ /* In-circuit checker (C)ChaN, 2008 */ /*-------------------------------------------------*/ // // 導通チェッカー Update by inoshita.jp // // ATMEL ATTINY13 / ARDUINO // // +-\/-+ // ADC0 (D 5) PB5 1| |8 Vcc // ADC3 (D 3) PB3 2| |7 PB2 (D 2) ADC1 // ADC2 (D 4) PB4 3| |6 PB1 (D 1) PWM1 // GND 4| |5 PB0 (D 0) PWM0 // +----+ // 1: Reset // 2: BIAS // 3: ADC // 4: GND // 5: LED // 6: BUZZER(PWM) // 7: PSW // 8: Vcc(3.0V) // // SYSTEM CLOCK : 1.2MHz // #include #include #include //ピンアサイン #define PIN_LED PB0 #define PIN_BZR PB1 #define PIN_PSW PB2 #define PIN_BIAS PB3 #define PIN_ADC PB4 //ボタン押下時の割り込み関数 //スリープから復帰するためだけなので何もしない EMPTY_INTERRUPT(PCINT0_vect); #define PCLOCK 1 //9.6MHz -> 1.2MHz static const uint8_t toneCount[] = { PCLOCK * 8, //1.6kHz PCLOCK * 9, //1.4kHz PCLOCK * 10, //1.2Hz PCLOCK * 12, //1.0Hz PCLOCK * 16 //800Hz }; void beep(uint8_t t) { if(t) { DDRB |= _BV(PIN_BZR); TCCR0A = _BV(COM0B1)|_BV(WGM01)|_BV(WGM00); //PWMの動作を指定(PB1出力,8ビット高速PWM動作) TCCR0B = _BV(WGM02)|0b011; //WGM02|WGM01|WGM00で高速PWM動作 //CS2|CS1|CS0 = 0b011 clkI/O/64 (64分周) OCR0A = t; //全体カウント量 OCR0B = t / 2; //デューティ比 } else { TCCR0B = _BV(WGM02); //停止 DDRB &= ~_BV(PIN_BZR); } } void blink(uint8_t count) { do { PORTB |= _BV(PIN_LED); //ON delay(500); PORTB &= ~_BV(PIN_LED); //OFF delay(500); } while(--count); } void setup(void) { //入出力ピン指定(OUT:LED/BUZZER/BIAS) //DDRB = _BV(PIN_LED)|_BV(PIN_BZR)|_BV(PIN_BIAS); DDRB = _BV(PIN_LED)|_BV(PIN_BIAS); //プルアップピン指定 PORTB |= _BV(PIN_PSW); ACSR |= _BV(ACD); //コンパレータ無効 PCMSK = _BV(PCINT2); //Enable PCINT2 GIMSK |= _BV(PCIE); set_sleep_mode(SLEEP_MODE_PWR_DOWN); sei(); } void loop(void) { uint16_t sdt; uint8_t lvd; //初期化,LED OFF/BUZZR OFF/BIAS Disable //PORTB &= ~(_BV(PIN_LED)|_BV(PIN_BZR)|_BV(PIN_BIAS)); PORTB &= ~_BV(PIN_LED); //OFF PORTB &= ~_BV(PIN_BIAS); ADCSRA = 0; //Stop ADC blink(2); //DEBUGが正式に //PSWボタンOFF待ち while(bit_is_clear(PINB, PIN_PSW)) delay(20); //Power-Down mode sleep_mode(); delay(50); //チャタリングなど誤動作時, 再度 Power-Down modeへ //if(bit_is_set(PINB, PIN_PSW)) return; //開始 PORTB |= _BV(PIN_LED); //LED ON PORTB |= _BV(PIN_BIAS); //Enable bias circuit ADMUX |= _BV(REFS0)|0b10; //ADC Ch=2, Vref=1.1V //電源OFFまでのタイマー初期化 sdt = 0; //PSWボタンOFF待ち while(bit_is_clear(PINB, PIN_PSW)) delay(20); //起動時の電源電圧チェック delay(500); //電圧安定待ち ADCSRA = _BV(ADEN)|_BV(ADSC)|(0b100); loop_until_bit_is_set(ADCSRA, ADIF); uint16_t ad = ADC; if(ad < 432) return; //2.7V以下,もしくはプローブが接触 if(ad < 528) lvd = 1; //3.3V以下,警告(blink LED) else lvd = 0; beep(toneCount[0]); //開始音 delay(100); beep(0); //導通チェック do { ADCSRA |= _BV(ADEN)|_BV(ADSC)|(0b100); loop_until_bit_is_set(ADCSRA, ADIF); ad = ADC; delay(10); if(ad < 5) { beep(toneCount[ad]); //導通 sdt = 0; //電源OFFまでのタイマー初期化 } else { beep(0); //非導通 } if(lvd && ++lvd > 20) { //LED lvd = 1; PORTB &= ~_BV(PIN_LED); //OFF } } while(bit_is_set(PINB, PIN_PSW) && ++sdt < 18000); //5分未使用による自動電源OFF if(bit_is_set(PINB, PIN_PSW)) { beep(toneCount[0]); delay(500); } beep(0); }