Advertisement
alexanderik

BatteryProtection from discharge

Jun 10th, 2016
1,367
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // ATtiny13
  2. // Battery Protection from discharge
  3. // © Grigoriev Alexander , 2016
  4. // ADC Module
  5.  
  6. #include <avr/io.h>
  7. #define F_CPU 4800000UL
  8. #include <compat/deprecated.h>
  9. #include <avr/interrupt.h>
  10. #include <util/delay.h>
  11. #include <avr/wdt.h>
  12. #include <avr/sleep.h>
  13.  
  14. #define SRAM __attribute__((section(".noinit")))
  15. #define rbi(port, bit) (port) ^= (1 << (bit))
  16.  
  17.  
  18. #define GATE        PORTB0
  19. #define VOLT_ADC    PORTB4
  20. #define WARN_LED    PORTB3
  21. #define PROC_LED    PORTB2
  22.  
  23. SRAM int temp;
  24. SRAM int DISCHARGE;
  25. SRAM int swarning;
  26. SRAM int tgate;
  27. SRAM int Lcounter, Hcounter;
  28.  
  29.  
  30.  
  31. static const int LCONMAX=60; // 25* sleep 1s = 15 sec
  32. static const int HCONMAX=20; // 10* sleep 1s = 10 sec
  33. //SRAM
  34.  
  35.  
  36.  
  37. #define tGATEOPEN   {sbi(PORTB,GATE);  }
  38. #define tGATECLOSE  {cbi(PORTB,GATE);   }
  39.  
  40. #define WARNON     {swarning=1; Lcounter=0;}
  41. #define WARNOFF    {swarning=0;}
  42. #define GATEOPEN   {tgate=1; }
  43. #define GATECLOSE  {tgate=0; }
  44.  
  45.  
  46. #define LEDON       {sbi(PORTB,WARN_LED);}
  47. #define LEDOFF      {cbi(PORTB,WARN_LED);}
  48.  
  49. void calc();
  50. void blink();
  51.  
  52. #define DEBUGS 0
  53. /*
  54. #define WDTO_15MS   0
  55. #define WDTO_30MS   1
  56. #define WDTO_60MS   2
  57. #define WDTO_120MS  3
  58. #define WDTO_250MS  4
  59. #define WDTO_500MS  5
  60. #define WDTO_1S     6
  61. #define WDTO_2S     7
  62. #define WDTO_2S     8
  63. */
  64.  
  65.  
  66.  
  67. //int LCONMAX; // 25* sleep 1s = 15 sec
  68. //int HCONMAX; // 10* sleep 1s = 10 sec
  69.  
  70.  
  71. ISR(WDT_vect) {
  72. cbi(WDTCR,WDE); sbi(WDTCR,WDTIE); // разрешаем прерывания по ватчдогу. Иначе будет резет.
  73. PORTB ^= _BV(PROC_LED); // переключаем светодиод
  74.  
  75. wdt_reset();
  76.  
  77.   if (tgate==1) tGATEOPEN else tGATECLOSE;
  78. if (swarning==1) LEDON else LEDOFF;
  79.  
  80. if (Lcounter>=5) blink((LCONMAX-Lcounter)/5,60);
  81. if (Hcounter>=5) blink(Hcounter/5,20);
  82.  
  83.    }
  84.  
  85. void initadc()
  86. {
  87.     //REFS0 Voltage Reference Selection
  88.     //0 VCC used as analog reference.
  89.     //1 Internal Voltage Reference.
  90. ADMUX |= (0 << REFS0) ; // VCC as Reference
  91.  
  92.  
  93.    //  MUX[1:0] Single Ended Input
  94.    //  00 ADC0 (PB5)
  95.    //  01 ADC1 (PB2)
  96.    //  10 ADC2 (PB4)
  97.    //  11 ADC3 (PB3)
  98. ADMUX |= (1 << MUX1) |(0 << MUX0) ;  // ADC2 PB.4
  99.  
  100.     //Bit 5 – ADLAR: ADC Left Adjust Result
  101.     //The ADLAR bit affects the presentation of the ADC conversion result in the ADC Data Register.
  102.     //Write one to ADLAR to left adjust the result. Otherwise, the result is right adjusted. Changing the
  103.     //ADLAR bit will affect the ADC Data Register immediately, regardless of any ongoing conversions.
  104. // ADMUX |= (1 << ADLAR); //8bit with ADLAR - 10 bit without
  105.  
  106.      // Set the prescaler to clock/128 & enable ADC
  107.  
  108. ADCSRA |= (1 << ADPS1) | (1 << ADPS0);      // set prescaller to 128, see 93 page of DS
  109.  
  110.     //  Bit 7 – ADEN: ADC Enable
  111.     //  Writing this bit to one enables the ADC. By writing it to zero, the ADC is turned off. Turning the
  112.     //  ADC off while a conversion is in progress, will terminate this conversion.
  113.  
  114. ADCSRA |= (1 << ADEN);                      // Enable ADC
  115. }
  116.  
  117. int ReadADC()
  118. {
  119. ADCSRA |= (1 << ADSC); // Start Converstion
  120.      while((ADCSRA & (1<<ADSC))) ;
  121.      //  while((ADCSRA & 0x40) !=0){}; //wait for conv complete
  122.     return ADC; //  8bit for ADCH - 10 bit for ADC // see ADLAR
  123. }
  124.  
  125.  
  126. void delay_ms(int count)
  127. {
  128.     while(count--) {_delay_ms(1);}
  129. }
  130.  
  131. void init(){
  132.  
  133. DDRB |= (1<<GATE)|(1<<PROC_LED)|(1<<WARN_LED); // output
  134.  
  135. cbi(DDRB,VOLT_ADC); //  DDRB &= ~(1 << VOLT); // input
  136. cbi(PORTB,VOLT_ADC); //PORTB &= ~(1 << VOLT); // low
  137.  
  138. //   wdt_reset();
  139.  
  140.   //wdt_enable(WDTO_1S);   // каждые S сек просыпаться
  141. //wdt_enable(WDTO_500MS);   // каждые S сек просыпаться
  142. wdt_enable(WDTO_250MS);//
  143. //wdt_enable(WDTO_15MS);//
  144.    
  145. cbi(WDTCR,WDE); sbi(WDTCR,WDTIE);    // разрешение прерываний по ватчдогу (иначе будет резет)!
  146.  
  147.   sei();
  148.  
  149.   set_sleep_mode(SLEEP_MODE_PWR_DOWN); // глубокий сон
  150. }
  151.  
  152. /*
  153. R1=100K;
  154. R2=22K;
  155. Vout=(R2/(R1+R2));  ~0.166667
  156. 11.1*0.16667 =
  157. 1024*1.85/5=378.88;
  158. 1024*2.03/5=415.7;
  159. c=34.13
  160. 11.1*34.13=378.8
  161.  
  162. */
  163.  
  164. // LTHR - минимальное напряжение аккумулятора, при котором отклчючается нагрузка по истечениии времени Lcounter * sleepmode
  165. //int  LTHR=399 ;//10.8V
  166. //int  LTHR=402 ;//10.9V
  167. //int  LTHR=406 ;//11.0V
  168. //int  LTHR=410 ;//11.1V
  169. //int  LTHR=413 ;//11.2V
  170. int  LTHR=417 ;//11.3V
  171. //int  LTHR=421 ;//11.4V
  172. //int  LTHR=424 ;//11.5V
  173. //int  LTHR=428 ;//11.6V
  174. //int  LTHR=432 ;//11.7V
  175. //int  LTHR=435 ;//11.8V
  176.  
  177. // HTHR - максимальное напряжение аккумулятора, при котором включается нагрузка, по истечениии времени Hcounter * sleepmode
  178. //int  HTHR=454 ;//12.3V;  
  179. //int  HTHR=458 ;//12.4V;  
  180. //int  HTHR=461 ;//12.5V;  
  181. //int  HTHR=465 ;//12.6V;  
  182. int  HTHR=469 ;//12.7V;
  183. //int  HTHR=473 ;//12.8V;  
  184. //int  HTHR=476 ;//12.9V;  
  185. //int  HTHR=480 ;//13.0V;
  186.  
  187.  
  188.  
  189.  
  190. int __attribute__((naked))
  191. main (void)
  192. {
  193. init();
  194. initadc();
  195.  
  196.   while(1) {
  197.            calc();
  198.             sleep_mode();
  199.         }  
  200. }
  201.  
  202. void blink (int z,int a) {
  203. //int statusport=PORTB;
  204.  
  205.     while (z>0) {
  206.         z--;
  207.         rbi(PORTB, WARN_LED);wdt_reset();
  208.         delay_ms(a);
  209.         rbi(PORTB, WARN_LED);wdt_reset();
  210.         delay_ms(a);
  211.             }
  212. //PORTB=statusport;
  213. }
  214.  
  215.  
  216.          
  217. void calc()
  218. {
  219. temp=ReadADC();
  220.  
  221.         if (temp<=LTHR)  {Lcounter++; Hcounter=0;  DISCHARGE=1; WARNOFF; }  // меньше минимума - включить счетчик, установить флаг разрядки
  222. else    if (temp>=HTHR)  {Hcounter++; Lcounter=0;  DISCHARGE=2; WARNOFF; } // переключаем светодиод}   // больше максимумa - включить счетчик
  223. else    { WARNON; Lcounter=0; Hcounter=0;
  224.             //blink((temp-LTHR),10);
  225.             if(DISCHARGE==1) {GATECLOSE;} else GATEOPEN;
  226.      } // если разрядка в промежуточных значениях - выключить нагрузку.
  227.  
  228.      
  229. if (Lcounter>=LCONMAX)   {GATECLOSE; Lcounter--; WARNOFF; }// переключаем светодиод}  // держать уровни на выходе
  230. if (Hcounter>=HCONMAX)   {GATEOPEN;  Hcounter--; WARNOFF;}
  231.  
  232. //blink(Hcounter);
  233.  
  234. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement