Skip to content

Instantly share code, notes, and snippets.

@akirayou
Created August 31, 2019 08:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save akirayou/da732615919adef786a867d17e69bc4b to your computer and use it in GitHub Desktop.
Save akirayou/da732615919adef786a867d17e69bc4b to your computer and use it in GitHub Desktop.
Hanahotaru for ATTiny10
/*
* Digital HanaHotaru
*
* Author: akira noda
*/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#define false 0
#define true -1
#include <avr/wdt.h>
#define max(x,y) ((x)<(y)?(y):(x))
#define min(x,y) ((x)<(y)?(x):(y))
volatile char sleepFlag;
ISR(WDT_vect){}//センサークランプ待ち用WDT割り込み
ISR(TIM0_CAPT_vect){//センサー用タイマ割り込み(積分時間計測
sleepFlag=false;
}
ISR(INT0_vect){} //充電完了割り込み(起動)
static int16_t thresh;
int32_t old;
static int16_t getCount();
static void ledOn(){
PORTB |= _BV(PORTB0);//HIGH
}
static void ledOff(){
PORTB &= ~_BV(PORTB0);//LOW
}
int main(void)
{
CCP=0xD8; // 128kHz wdt オシレータ
CLKMSR=1;
CCP=0xD8;
CLKPSR=0;
DIDR0=0x09;// 1001 PB1,PB2以外は入力ピンなし(省電力)
DDRB=_BV(PORTB0); //LED
PUEB=0x00;// no pull up
PRR=0x02;//ADC stop
ACSR=0x80;//comparetor off
//Timmer 125kHz
sleep_enable();
#define RA 16
#define THRESH_RATE 1
old= getCount();
thresh=0;
char ledState=0;
int16_t diff=0;
char skipCount=0;
while(1)
{
int16_t now=getCount();
if(skipCount){
skipCount--;
old=now;
}else{
diff=(now-old)+((RA-1)*diff+RA/2)/RA;
old=now;
if(ledState){
thresh=max(diff-THRESH_RATE*RA,thresh);
if(diff<thresh){
thresh+=2*THRESH_RATE*RA;
ledState=0;
diff=0;
skipCount=3;
ledOn();
}
}else{
thresh=min(diff+THRESH_RATE*RA,thresh);
if(diff>thresh){
thresh-=2*THRESH_RATE*RA;
ledState=1;
ledOff();
diff=0;
skipCount=3;
}
}
}
//充電器に繋がれたので Power off
if(PINB & _BV(PORTB2)){
ledOff();
cli();//割り込み関係なしに起きてくれるのでseiしない
//7ISC0=0x00;
EICRA=0;EIMSK=0x01;//enable INT0
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
sei();
sleep_cpu();
EIMSK=0x00;//seep解除されても割り込みが走らない場合がある(マニュアルより)
sleep_disable();
//充電器から外された(6.8Mプルダウン)か充電完了(0V直結)かをプルアップ抵抗で判定
PUEB = _BV(PORTB2);
while((PINB & _BV(PORTB2)) == 0 ){//pull up しても0と言う事は引き込みがある。
ledOn();
}
//引き込みがないので、充電装置から外された
PUEB = 0;
}
}
}
static void clampP(){
DDRB|=_BV(PORTB1);//output
PORTB &= ~_BV(PORTB1);//Low
}
static void freeP(void){
DDRB &= ~ _BV(PORTB1);//input
}
static void countStart(){
cli();
GTCCR=0x81;//stop
TCCR0B=0;
TCNT0=0;
TIFR0|=0x27;
TIMSK0=_BV(ICIE0);//enable input caputre interrupt
sleepFlag=true;
sei();
//ノイズキャンセルON 立ち上がりエッジ プリスケーラ:1 タイマーON
TCCR0A=0;
TCCR0C=0;
TCCR0B=0xC1; // 0b1100 0001
GTCCR=0x00;//start
}
static void countStop(){
cli();
TIMSK0=0;
GTCCR=0x81;//stop
TCCR0B=0x00; //timer stop
}
static void waitStart(){
wdt_reset();
sei();
CCP=0xD8;
WDTCSR=0xC1; //32ms
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
sleep_cpu();
cli();
// wdt_disable();
CCP=0xD8;
WDTCSR=0x00;
sleep_disable();
}
static int16_t getCount(){
clampP();
waitStart();
freeP();
countStart();
set_sleep_mode(SLEEP_MODE_IDLE);
while(sleepFlag)sleep_mode();
countStop();
return ICR0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment