Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // ATtiny13
- // Battery Protection from discharge
- // © Grigoriev Alexander , 2016
- // ADC Module
- #include <avr/io.h>
- #define F_CPU 4800000UL
- #include <compat/deprecated.h>
- #include <avr/interrupt.h>
- #include <util/delay.h>
- #include <avr/wdt.h>
- #include <avr/sleep.h>
- #define SRAM __attribute__((section(".noinit")))
- #define rbi(port, bit) (port) ^= (1 << (bit))
- #define GATE PORTB0
- #define VOLT_ADC PORTB4
- #define WARN_LED PORTB3
- #define PROC_LED PORTB2
- SRAM int temp;
- SRAM int DISCHARGE;
- SRAM int swarning;
- SRAM int tgate;
- SRAM int Lcounter, Hcounter;
- static const int LCONMAX=60; // 25* sleep 1s = 15 sec
- static const int HCONMAX=20; // 10* sleep 1s = 10 sec
- //SRAM
- #define tGATEOPEN {sbi(PORTB,GATE); }
- #define tGATECLOSE {cbi(PORTB,GATE); }
- #define WARNON {swarning=1; Lcounter=0;}
- #define WARNOFF {swarning=0;}
- #define GATEOPEN {tgate=1; }
- #define GATECLOSE {tgate=0; }
- #define LEDON {sbi(PORTB,WARN_LED);}
- #define LEDOFF {cbi(PORTB,WARN_LED);}
- void calc();
- void blink();
- #define DEBUGS 0
- /*
- #define WDTO_15MS 0
- #define WDTO_30MS 1
- #define WDTO_60MS 2
- #define WDTO_120MS 3
- #define WDTO_250MS 4
- #define WDTO_500MS 5
- #define WDTO_1S 6
- #define WDTO_2S 7
- #define WDTO_2S 8
- */
- //int LCONMAX; // 25* sleep 1s = 15 sec
- //int HCONMAX; // 10* sleep 1s = 10 sec
- ISR(WDT_vect) {
- cbi(WDTCR,WDE); sbi(WDTCR,WDTIE); // разрешаем прерывания по ватчдогу. Иначе будет резет.
- PORTB ^= _BV(PROC_LED); // переключаем светодиод
- wdt_reset();
- if (tgate==1) tGATEOPEN else tGATECLOSE;
- if (swarning==1) LEDON else LEDOFF;
- if (Lcounter>=5) blink((LCONMAX-Lcounter)/5,60);
- if (Hcounter>=5) blink(Hcounter/5,20);
- }
- void initadc()
- {
- //REFS0 Voltage Reference Selection
- //0 VCC used as analog reference.
- //1 Internal Voltage Reference.
- ADMUX |= (0 << REFS0) ; // VCC as Reference
- // MUX[1:0] Single Ended Input
- // 00 ADC0 (PB5)
- // 01 ADC1 (PB2)
- // 10 ADC2 (PB4)
- // 11 ADC3 (PB3)
- ADMUX |= (1 << MUX1) |(0 << MUX0) ; // ADC2 PB.4
- //Bit 5 – ADLAR: ADC Left Adjust Result
- //The ADLAR bit affects the presentation of the ADC conversion result in the ADC Data Register.
- //Write one to ADLAR to left adjust the result. Otherwise, the result is right adjusted. Changing the
- //ADLAR bit will affect the ADC Data Register immediately, regardless of any ongoing conversions.
- // ADMUX |= (1 << ADLAR); //8bit with ADLAR - 10 bit without
- // Set the prescaler to clock/128 & enable ADC
- ADCSRA |= (1 << ADPS1) | (1 << ADPS0); // set prescaller to 128, see 93 page of DS
- // Bit 7 – ADEN: ADC Enable
- // Writing this bit to one enables the ADC. By writing it to zero, the ADC is turned off. Turning the
- // ADC off while a conversion is in progress, will terminate this conversion.
- ADCSRA |= (1 << ADEN); // Enable ADC
- }
- int ReadADC()
- {
- ADCSRA |= (1 << ADSC); // Start Converstion
- while((ADCSRA & (1<<ADSC))) ;
- // while((ADCSRA & 0x40) !=0){}; //wait for conv complete
- return ADC; // 8bit for ADCH - 10 bit for ADC // see ADLAR
- }
- void delay_ms(int count)
- {
- while(count--) {_delay_ms(1);}
- }
- void init(){
- DDRB |= (1<<GATE)|(1<<PROC_LED)|(1<<WARN_LED); // output
- cbi(DDRB,VOLT_ADC); // DDRB &= ~(1 << VOLT); // input
- cbi(PORTB,VOLT_ADC); //PORTB &= ~(1 << VOLT); // low
- // wdt_reset();
- //wdt_enable(WDTO_1S); // каждые S сек просыпаться
- //wdt_enable(WDTO_500MS); // каждые S сек просыпаться
- wdt_enable(WDTO_250MS);//
- //wdt_enable(WDTO_15MS);//
- cbi(WDTCR,WDE); sbi(WDTCR,WDTIE); // разрешение прерываний по ватчдогу (иначе будет резет)!
- sei();
- set_sleep_mode(SLEEP_MODE_PWR_DOWN); // глубокий сон
- }
- /*
- R1=100K;
- R2=22K;
- Vout=(R2/(R1+R2)); ~0.166667
- 11.1*0.16667 =
- 1024*1.85/5=378.88;
- 1024*2.03/5=415.7;
- c=34.13
- 11.1*34.13=378.8
- */
- // LTHR - минимальное напряжение аккумулятора, при котором отклчючается нагрузка по истечениии времени Lcounter * sleepmode
- //int LTHR=399 ;//10.8V
- //int LTHR=402 ;//10.9V
- //int LTHR=406 ;//11.0V
- //int LTHR=410 ;//11.1V
- //int LTHR=413 ;//11.2V
- int LTHR=417 ;//11.3V
- //int LTHR=421 ;//11.4V
- //int LTHR=424 ;//11.5V
- //int LTHR=428 ;//11.6V
- //int LTHR=432 ;//11.7V
- //int LTHR=435 ;//11.8V
- // HTHR - максимальное напряжение аккумулятора, при котором включается нагрузка, по истечениии времени Hcounter * sleepmode
- //int HTHR=454 ;//12.3V;
- //int HTHR=458 ;//12.4V;
- //int HTHR=461 ;//12.5V;
- //int HTHR=465 ;//12.6V;
- int HTHR=469 ;//12.7V;
- //int HTHR=473 ;//12.8V;
- //int HTHR=476 ;//12.9V;
- //int HTHR=480 ;//13.0V;
- int __attribute__((naked))
- main (void)
- {
- init();
- initadc();
- while(1) {
- calc();
- sleep_mode();
- }
- }
- void blink (int z,int a) {
- //int statusport=PORTB;
- while (z>0) {
- z--;
- rbi(PORTB, WARN_LED);wdt_reset();
- delay_ms(a);
- rbi(PORTB, WARN_LED);wdt_reset();
- delay_ms(a);
- }
- //PORTB=statusport;
- }
- void calc()
- {
- temp=ReadADC();
- if (temp<=LTHR) {Lcounter++; Hcounter=0; DISCHARGE=1; WARNOFF; } // меньше минимума - включить счетчик, установить флаг разрядки
- else if (temp>=HTHR) {Hcounter++; Lcounter=0; DISCHARGE=2; WARNOFF; } // переключаем светодиод} // больше максимумa - включить счетчик
- else { WARNON; Lcounter=0; Hcounter=0;
- //blink((temp-LTHR),10);
- if(DISCHARGE==1) {GATECLOSE;} else GATEOPEN;
- } // если разрядка в промежуточных значениях - выключить нагрузку.
- if (Lcounter>=LCONMAX) {GATECLOSE; Lcounter--; WARNOFF; }// переключаем светодиод} // держать уровни на выходе
- if (Hcounter>=HCONMAX) {GATEOPEN; Hcounter--; WARNOFF;}
- //blink(Hcounter);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement