1352 |
miho |
1 |
//********************************************************************** |
|
|
2 |
// INFO BATTERY PACK |
|
|
3 |
//********************************************************************** |
|
|
4 |
// (c) OK1XGL 2008 |
|
|
5 |
// verze 1.0 - uvodni verze |
|
|
6 |
// 1.1 - referencni teplota pro samovybijeni se uklada pri zadani doby mereni samovybijeni |
|
|
7 |
// |
|
|
8 |
// |
|
|
9 |
|
|
|
10 |
#include "ibp2.h" |
|
|
11 |
|
|
|
12 |
|
|
|
13 |
// nastavi orientaci a klidovy stav portu |
|
|
14 |
// |
|
|
15 |
void init_ports (void) { |
|
|
16 |
set_tris_a (0b00101011); |
|
|
17 |
output_a (0b000000000); |
|
|
18 |
|
|
|
19 |
set_tris_b (0b11010000); |
|
|
20 |
output_b (0b00100000); |
|
|
21 |
port_b_pullups (FALSE); |
|
|
22 |
} |
|
|
23 |
|
|
|
24 |
|
|
|
25 |
////////////////////////////////////////////////// |
|
|
26 |
// |
|
|
27 |
// iterrupty |
|
|
28 |
// cele preruseni zabere 33+xx+30 cyklu |
|
|
29 |
// |
|
|
30 |
////////////////////////////////////////////////// |
|
|
31 |
|
|
|
32 |
// periodicky casovac |
|
|
33 |
// |
|
|
34 |
#INT_TIMER1 |
|
|
35 |
void tmr1_int (void) { |
|
|
36 |
// natahovani casovace |
|
|
37 |
set_timer1 (S_TICK_TIME); |
|
|
38 |
s_tick = 1; |
|
|
39 |
|
|
|
40 |
if (l_timer == 0) { |
|
|
41 |
l_timer = L_TICK_TIME; |
|
|
42 |
l_tick = 1; |
|
|
43 |
blink = ~blink; |
|
|
44 |
if (blink) |
|
|
45 |
slow_blink = ~slow_blink; |
|
|
46 |
} |
|
|
47 |
else |
|
|
48 |
l_timer--; |
|
|
49 |
} |
|
|
50 |
|
|
|
51 |
|
|
|
52 |
|
|
|
53 |
/////////////////////////////////////////////////// |
|
|
54 |
// |
|
|
55 |
// FUNKCE PRO PRACI S TEPLOMEREM |
|
|
56 |
// |
|
|
57 |
////////////////////////////////////////////////// |
|
|
58 |
|
|
|
59 |
// testuje pritomnost teplomeru, pri pritomnosti vraci 1 |
|
|
60 |
// zabere 1060 taktu |
|
|
61 |
// |
|
|
62 |
int8 TM_present() { |
|
|
63 |
int1 present; |
|
|
64 |
|
|
|
65 |
output_low (TM_PIN); |
|
|
66 |
output_fixed (TM_PIN); |
|
|
67 |
delay_us (500); |
|
|
68 |
disable_interrupts (GLOBAL); |
|
|
69 |
output_float (TM_PIN); |
|
|
70 |
if(!input (TM_PIN)) { |
|
|
71 |
enable_interrupts (GLOBAL); |
|
|
72 |
return (0); |
|
|
73 |
} |
|
|
74 |
delay_us (65); |
|
|
75 |
present = input(TM_PIN); |
|
|
76 |
enable_interrupts (GLOBAL); |
|
|
77 |
delay_us (440); |
|
|
78 |
if (present) |
|
|
79 |
return (0); |
|
|
80 |
else |
|
|
81 |
return (1); |
|
|
82 |
} |
|
|
83 |
|
|
|
84 |
|
|
|
85 |
// precte bajt z teplomeru |
|
|
86 |
// |
|
|
87 |
int8 TM_read_byte() { |
|
|
88 |
int8 i,data; |
|
|
89 |
|
|
|
90 |
for(i = 0; i < 8; ++i) { |
|
|
91 |
disable_interrupts (GLOBAL); |
|
|
92 |
output_low (TM_PIN); |
|
|
93 |
output_fixed (TM_PIN); |
|
|
94 |
delay_us (2); |
|
|
95 |
output_float (TM_PIN); |
|
|
96 |
delay_us (8); |
|
|
97 |
shift_right (&data,1,input(TM_PIN)); |
|
|
98 |
enable_interrupts (GLOBAL); |
|
|
99 |
delay_us (55); |
|
|
100 |
} |
|
|
101 |
return (data); |
|
|
102 |
} |
|
|
103 |
|
|
|
104 |
|
|
|
105 |
// zapise bajt do teplomeru |
|
|
106 |
// |
|
|
107 |
void TM_write_byte(int8 data) { |
|
|
108 |
int8 i; |
|
|
109 |
|
|
|
110 |
for (i = 0 ; i < 8; ++i) { |
|
|
111 |
disable_interrupts (GLOBAL); |
|
|
112 |
output_low (TM_PIN); |
|
|
113 |
output_fixed (TM_PIN); |
|
|
114 |
delay_us (5); |
|
|
115 |
if (shift_right (&data,1,0)) |
|
|
116 |
output_float (TM_PIN); |
|
|
117 |
delay_us (60); |
|
|
118 |
output_float (TM_PIN); |
|
|
119 |
delay_us (2); |
|
|
120 |
enable_interrupts (GLOBAL); |
|
|
121 |
} |
|
|
122 |
} |
|
|
123 |
|
|
|
124 |
|
|
|
125 |
// vraci 0 pri ukonceni mereni |
|
|
126 |
// vraci 1 pri rozpracovanem mereni |
|
|
127 |
// zabere max 1100 taktu na 1 cyklus |
|
|
128 |
// potrebuje 10 volani pro zmereni teploty |
|
|
129 |
// |
|
|
130 |
int8 measure_temp () { |
|
|
131 |
static int8 phase; |
|
|
132 |
static int8 tmp; |
|
|
133 |
int8 tmp2; |
|
|
134 |
|
|
|
135 |
switch (phase) { |
|
|
136 |
case 0: |
|
|
137 |
if (! TM_present ()) { // over pritomnost teplomeru |
|
|
138 |
phase = 0; |
|
|
139 |
TB_val = TB_DEFAULT; |
|
|
140 |
return (0); // teplomer neni pritomen, dal nelze pokracovat |
|
|
141 |
} |
|
|
142 |
break; |
|
|
143 |
|
|
|
144 |
case 1: |
|
|
145 |
TM_write_byte (0xcc); // preskoc na dalsi sadu prikazu |
|
|
146 |
break; |
|
|
147 |
|
|
|
148 |
case 2: |
|
|
149 |
TM_write_byte (0x44); // prikaz spust mereni teploty |
|
|
150 |
output_high (TM_PIN); // zapni tvrdy pullup |
|
|
151 |
output_fixed (TM_PIN); // |
|
|
152 |
break; |
|
|
153 |
|
|
|
154 |
case 3: |
|
|
155 |
case 4: |
|
|
156 |
case 5: // cekej nejmene 750 ms |
|
|
157 |
break; |
|
|
158 |
|
|
|
159 |
case 6: |
|
|
160 |
output_float (TM_PIN); // vyppni tvrdy pullup |
|
|
161 |
output_low (TM_PIN); // |
|
|
162 |
if (! TM_present ()) { // over pritomnost teplomeru |
|
|
163 |
phase = 0; |
|
|
164 |
TB_val = TB_DEFAULT; |
|
|
165 |
return (0); // teplomer neni pritomen, dal nelze pokracovat |
|
|
166 |
} |
|
|
167 |
break; |
|
|
168 |
|
|
|
169 |
case 7: |
|
|
170 |
TM_write_byte (0xcc); // preskoc na dalsi sadu prikazu |
|
|
171 |
break; |
|
|
172 |
|
|
|
173 |
case 8: |
|
|
174 |
TM_write_byte (0xbe); // prikaz precti zmerenou teplotu |
|
|
175 |
break; |
|
|
176 |
|
|
|
177 |
case 9: |
|
|
178 |
tmp = TM_read_byte () >> 4; // precti LSB bajt s teplotou a zahod destiny stupne |
|
|
179 |
break; |
|
|
180 |
|
|
|
181 |
case 10: |
|
|
182 |
tmp |= TM_read_byte () << 4; // precti MSB bajt s teplotou a sloz s LSB |
|
|
183 |
tmp2 = tmp & 0x7F; // |
|
|
184 |
if (tmp2 < 80) { // teplota je v moznem rozsahu (nahrada kontroly CRC - bylo by casove prilis dlouhe) |
|
|
185 |
if (tmp & 0x80) |
|
|
186 |
TB_val = 0; // zapornou teplotu povazujeme za nulovou |
|
|
187 |
else |
|
|
188 |
TB_val = tmp2; |
|
|
189 |
} |
|
|
190 |
phase = 0; |
|
|
191 |
return (0); |
|
|
192 |
break; |
|
|
193 |
|
|
|
194 |
default: |
|
|
195 |
phase = 0; |
|
|
196 |
TB_val = TB_DEFAULT; |
|
|
197 |
return (0); |
|
|
198 |
} |
|
|
199 |
phase++; |
|
|
200 |
return (1); |
|
|
201 |
} |
|
|
202 |
|
|
|
203 |
|
|
|
204 |
|
|
|
205 |
////////////////////////////////////////////////////// |
|
|
206 |
// |
|
|
207 |
// FUNNKCE PRO MERENI NAPETI A PROUDU |
|
|
208 |
// |
|
|
209 |
////////////////////////////////////////////////////// |
|
|
210 |
|
|
|
211 |
// meri velikost proudu z/do baterie a prumeruje z 8 mereni |
|
|
212 |
// zabere max 1760 taktu (1760 us) |
|
|
213 |
// |
|
|
214 |
int16 measure_IB (void) { |
|
|
215 |
int16 out; |
|
|
216 |
|
|
|
217 |
set_adc_channel (IB_CAN); |
|
|
218 |
delay_us (100); |
|
|
219 |
out = read_adc (ADC_START_AND_READ); |
|
|
220 |
delay_us (100); |
|
|
221 |
out += read_adc (ADC_START_AND_READ); |
|
|
222 |
delay_us (100); |
|
|
223 |
out += read_adc (ADC_START_AND_READ); |
|
|
224 |
delay_us (100); |
|
|
225 |
out += read_adc (ADC_START_AND_READ); |
|
|
226 |
delay_us (100); |
|
|
227 |
out += read_adc (ADC_START_AND_READ); |
|
|
228 |
delay_us (100); |
|
|
229 |
out += read_adc (ADC_START_AND_READ); |
|
|
230 |
delay_us (100); |
|
|
231 |
out += read_adc (ADC_START_AND_READ); |
|
|
232 |
delay_us (100); |
|
|
233 |
out += read_adc (ADC_START_AND_READ); |
|
|
234 |
out = out >> 3; |
|
|
235 |
return (out); |
|
|
236 |
} |
|
|
237 |
|
|
|
238 |
|
|
|
239 |
// meri velikost napeti baterie a provadi klouzavy prumer z 8 mereni |
|
|
240 |
// zabere max 320 taktu (320 us) |
|
|
241 |
// |
|
|
242 |
int16 measure_VB (void) { |
|
|
243 |
static int16 smpl [8]; |
|
|
244 |
static int8 i; |
|
|
245 |
int16 out; |
|
|
246 |
|
|
|
247 |
if (i >= 8-1) |
|
|
248 |
i = 0; |
|
|
249 |
else |
|
|
250 |
i++; |
|
|
251 |
|
|
|
252 |
set_adc_channel (VB_CAN); |
|
|
253 |
delay_us (100); |
|
|
254 |
smpl [i] = read_adc (ADC_START_AND_READ); |
|
|
255 |
|
|
|
256 |
out = smpl [0] + smpl [1] + smpl [2] + smpl [3] + |
|
|
257 |
smpl [4] + smpl [5] + smpl [6] + smpl [7]; |
|
|
258 |
out = out >> 3; |
|
|
259 |
return (out); |
|
|
260 |
} |
|
|
261 |
|
|
|
262 |
|
|
|
263 |
// meri velikost vstupniho napeti zdroje pro nabijeni |
|
|
264 |
// zabere max 200 taktu (200 us) |
|
|
265 |
// |
|
|
266 |
int16 measure_VS (void) { |
|
|
267 |
int16 out; |
|
|
268 |
|
|
|
269 |
set_adc_channel (VS_CAN); |
|
|
270 |
delay_us (100); |
|
|
271 |
out = read_adc (ADC_START_AND_READ); |
|
|
272 |
return (out); |
|
|
273 |
} |
|
|
274 |
|
|
|
275 |
|
|
|
276 |
// meri vystupni napeti OZ pro mereni proudu pri nulovem odberu - pro kompenzaci ofsetu OZ |
|
|
277 |
// |
|
|
278 |
int16 measure_offset (void) { |
|
|
279 |
int16 out; |
|
|
280 |
int8 i; |
|
|
281 |
|
|
|
282 |
// vypni vsechny spotrebice |
|
|
283 |
init_ports (); |
|
|
284 |
disable_interrupts (GLOBAL); |
|
|
285 |
ADIE = 1; |
|
|
286 |
PEIE = 1; |
|
|
287 |
delay_ms (500); |
|
|
288 |
|
|
|
289 |
// mer napeti OZ a vypocti prumer z 8 mereni |
|
|
290 |
set_adc_channel (IB_CAN); |
|
|
291 |
delay_us (100); |
|
|
292 |
out = 0; |
|
|
293 |
for (i = 0; i < 8; i++) { |
|
|
294 |
read_adc (ADC_START_ONLY); |
|
|
295 |
sleep (); |
|
|
296 |
out += read_adc (ADC_READ_ONLY); |
|
|
297 |
delay_us (100); |
|
|
298 |
restart_wdt (); |
|
|
299 |
} |
|
|
300 |
out = out >> 3; |
|
|
301 |
|
|
|
302 |
ADIE = 0; |
|
|
303 |
PEIE = 0; |
|
|
304 |
enable_interrupts (GLOBAL); |
|
|
305 |
return (out); |
|
|
306 |
} |
|
|
307 |
|
|
|
308 |
|
|
|
309 |
///////////////////////////////////////////////// |
|
|
310 |
// |
|
|
311 |
// FUNKCE PRO PRACI S LED |
|
|
312 |
// |
|
|
313 |
///////////////////////////////////////////////// |
|
|
314 |
|
|
|
315 |
// rozsviti vsechny led |
|
|
316 |
// |
|
|
317 |
void leds_all_on () { |
|
|
318 |
output_high (LED4_R); |
|
|
319 |
output_high (LED3_Y); |
|
|
320 |
output_high (LED2_Y); |
|
|
321 |
output_high (LED1_G); |
|
|
322 |
} |
|
|
323 |
|
|
|
324 |
|
|
|
325 |
// zhasne vsechny led |
|
|
326 |
// |
|
|
327 |
void leds_all_off () { |
|
|
328 |
output_low (LED4_R); |
|
|
329 |
output_low (LED3_Y); |
|
|
330 |
output_low (LED2_Y); |
|
|
331 |
output_low (LED1_G); |
|
|
332 |
} |
|
|
333 |
|
|
|
334 |
|
|
|
335 |
// signalizuje kapacitu baterie pri nabijeni |
|
|
336 |
// vraci cislo odpovidajici stavu nabiti |
|
|
337 |
// zabere max 40 cyklu |
|
|
338 |
// |
|
|
339 |
int8 leds_chrg (void) { |
|
|
340 |
if (B_cap >= B_cap_4_4) { |
|
|
341 |
leds_all_on (); |
|
|
342 |
return (4); // baterie plne nabita |
|
|
343 |
} |
|
|
344 |
|
|
|
345 |
if (B_cap > B_cap_3_4) { |
|
|
346 |
output_high (LED4_R); |
|
|
347 |
output_high (LED3_Y); |
|
|
348 |
output_high (LED2_Y); |
|
|
349 |
if (slow_blink) |
|
|
350 |
output_high (LED1_G); |
|
|
351 |
else |
|
|
352 |
output_low (LED1_G); |
|
|
353 |
return (3); |
|
|
354 |
} |
|
|
355 |
|
|
|
356 |
if (B_cap > B_cap_2_4) { |
|
|
357 |
output_high (LED4_R); |
|
|
358 |
output_high (LED3_Y); |
|
|
359 |
if (slow_blink) |
|
|
360 |
output_high (LED2_Y); |
|
|
361 |
else |
|
|
362 |
output_low (LED2_Y); |
|
|
363 |
output_low (LED1_G); |
|
|
364 |
return (2); |
|
|
365 |
} |
|
|
366 |
|
|
|
367 |
if (B_cap > B_cap_1_4) { |
|
|
368 |
output_high (LED4_R); |
|
|
369 |
if (slow_blink) |
|
|
370 |
output_high (LED3_Y); |
|
|
371 |
else |
|
|
372 |
output_low (LED3_Y); |
|
|
373 |
output_low (LED2_Y); |
|
|
374 |
output_low (LED1_G); |
|
|
375 |
return (1); |
|
|
376 |
} |
|
|
377 |
|
|
|
378 |
if (slow_blink) |
|
|
379 |
output_high (LED4_R); |
|
|
380 |
else |
|
|
381 |
output_low (LED4_R); |
|
|
382 |
output_low (LED3_Y); |
|
|
383 |
output_low (LED2_Y); |
|
|
384 |
output_low (LED1_G); |
|
|
385 |
return (0); |
|
|
386 |
} |
|
|
387 |
|
|
|
388 |
|
|
|
389 |
// signalizuje chybu |
|
|
390 |
// |
|
|
391 |
void leds_err () { |
|
|
392 |
output_low (LED1_G); |
|
|
393 |
output_low (LED4_R); |
|
|
394 |
if (blink) { |
|
|
395 |
output_high (LED2_Y); |
|
|
396 |
output_high (LED3_Y); |
|
|
397 |
} |
|
|
398 |
else { |
|
|
399 |
output_low (LED2_Y); |
|
|
400 |
output_low (LED3_Y); |
|
|
401 |
} |
|
|
402 |
} |
|
|
403 |
|
|
|
404 |
|
|
|
405 |
// signalizuje neznamou aktualni kapacitu baterie |
|
|
406 |
// |
|
|
407 |
void leds_invalid_cap () { |
|
|
408 |
output_low (LED2_Y); |
|
|
409 |
output_low (LED3_Y); |
|
|
410 |
if (blink) { |
|
|
411 |
output_high (LED1_G); |
|
|
412 |
output_high (LED4_R); |
|
|
413 |
} |
|
|
414 |
else { |
|
|
415 |
output_low (LED1_G); |
|
|
416 |
output_low (LED4_R); |
|
|
417 |
} |
|
|
418 |
} |
|
|
419 |
|
|
|
420 |
|
|
|
421 |
// signalizuje zbyvajici kapacitu baterie pri vybijeni |
|
|
422 |
// |
|
|
423 |
void leds_dis () { |
|
|
424 |
if (B_cap < B_cap_1_4) { |
|
|
425 |
output_low (LED1_G); |
|
|
426 |
output_low (LED2_Y); |
|
|
427 |
output_low (LED3_Y); |
|
|
428 |
output_high (LED4_R); |
|
|
429 |
return; |
|
|
430 |
} |
|
|
431 |
|
|
|
432 |
if (B_cap < B_cap_2_4) { |
|
|
433 |
output_low (LED1_G); |
|
|
434 |
output_low (LED2_Y); |
|
|
435 |
output_high (LED3_Y); |
|
|
436 |
output_low (LED4_R); |
|
|
437 |
return; |
|
|
438 |
} |
|
|
439 |
|
|
|
440 |
if (B_cap < B_cap_3_4) { |
|
|
441 |
output_low (LED1_G); |
|
|
442 |
output_high (LED2_Y); |
|
|
443 |
output_low (LED3_Y); |
|
|
444 |
output_low (LED4_R); |
|
|
445 |
return; |
|
|
446 |
} |
|
|
447 |
|
|
|
448 |
output_high (LED1_G); |
|
|
449 |
output_low (LED2_Y); |
|
|
450 |
output_low (LED3_Y); |
|
|
451 |
output_low (LED4_R); |
|
|
452 |
} |
|
|
453 |
|
|
|
454 |
|
|
|
455 |
// signalizuje temer vybitou baterii |
|
|
456 |
// |
|
|
457 |
void leds_VB_low () { |
|
|
458 |
output_low (LED1_G); |
|
|
459 |
output_low (LED2_Y); |
|
|
460 |
output_low (LED3_Y); |
|
|
461 |
if (slow_blink) |
|
|
462 |
output_high (LED4_R); |
|
|
463 |
else |
|
|
464 |
output_low (LED4_R); |
|
|
465 |
} |
|
|
466 |
|
|
|
467 |
|
|
|
468 |
// zobrazi cislo v rozsahu 0 - 9 v binarnim kodu na ledkach |
|
|
469 |
// |
|
|
470 |
void num_to_leds (int8 num) { |
|
|
471 |
|
|
|
472 |
switch (num) { |
|
|
473 |
case 0: |
|
|
474 |
output_low (LED4_R); // nejnizsi bit |
|
|
475 |
output_low (LED3_Y); |
|
|
476 |
output_low (LED2_Y); |
|
|
477 |
output_low (LED1_G); // nejvyssi bit |
|
|
478 |
break; |
|
|
479 |
case 1: |
|
|
480 |
output_high (LED4_R); // nejnizsi bit |
|
|
481 |
output_low (LED3_Y); |
|
|
482 |
output_low (LED2_Y); |
|
|
483 |
output_low (LED1_G); // nejvyssi bit |
|
|
484 |
break; |
|
|
485 |
case 2: |
|
|
486 |
output_low (LED4_R); // nejnizsi bit |
|
|
487 |
output_high (LED3_Y); |
|
|
488 |
output_low (LED2_Y); |
|
|
489 |
output_low (LED1_G); // nejvyssi bit |
|
|
490 |
break; |
|
|
491 |
case 3: |
|
|
492 |
output_high (LED4_R); // nejnizsi bit |
|
|
493 |
output_high (LED3_Y); |
|
|
494 |
output_low (LED2_Y); |
|
|
495 |
output_low (LED1_G); // nejvyssi bit |
|
|
496 |
break; |
|
|
497 |
case 4: |
|
|
498 |
output_low (LED4_R); // nejnizsi bit |
|
|
499 |
output_low (LED3_Y); |
|
|
500 |
output_high (LED2_Y); |
|
|
501 |
output_low (LED1_G); // nejvyssi bit |
|
|
502 |
break; |
|
|
503 |
case 5: |
|
|
504 |
output_high (LED4_R); // nejnizsi bit |
|
|
505 |
output_low (LED3_Y); |
|
|
506 |
output_high (LED2_Y); |
|
|
507 |
output_low (LED1_G); // nejvyssi bit |
|
|
508 |
break; |
|
|
509 |
case 6: |
|
|
510 |
output_low (LED4_R); // nejnizsi bit |
|
|
511 |
output_high (LED3_Y); |
|
|
512 |
output_high (LED2_Y); |
|
|
513 |
output_low (LED1_G); // nejvyssi bit |
|
|
514 |
break; |
|
|
515 |
case 7: |
|
|
516 |
output_high (LED4_R); // nejnizsi bit |
|
|
517 |
output_high (LED3_Y); |
|
|
518 |
output_high (LED2_Y); |
|
|
519 |
output_low (LED1_G); // nejvyssi bit |
|
|
520 |
break; |
|
|
521 |
case 8: |
|
|
522 |
output_low (LED4_R); // nejnizsi bit |
|
|
523 |
output_low (LED3_Y); |
|
|
524 |
output_low (LED2_Y); |
|
|
525 |
output_high (LED1_G); // nejvyssi bit |
|
|
526 |
break; |
|
|
527 |
case 9: |
|
|
528 |
output_high (LED4_R); // nejnizsi bit |
|
|
529 |
output_low (LED3_Y); |
|
|
530 |
output_low (LED2_Y); |
|
|
531 |
output_high (LED1_G); // nejvyssi bit |
|
|
532 |
break; |
|
|
533 |
default: |
|
|
534 |
output_low (LED4_R); // nejnizsi bit |
|
|
535 |
output_low (LED3_Y); |
|
|
536 |
output_low (LED2_Y); |
|
|
537 |
output_low (LED1_G); // nejvyssi bit |
|
|
538 |
} |
|
|
539 |
} |
|
|
540 |
|
|
|
541 |
|
|
|
542 |
/////////////////////////////////////////////////////// |
|
|
543 |
// |
|
|
544 |
// FUNKCE PRO CTENI TLACITEK A KONTAKTU |
|
|
545 |
// |
|
|
546 |
/////////////////////////////////////////////////////// |
|
|
547 |
|
|
|
548 |
// je pripojena zatez? |
|
|
549 |
// vraci 1 pri pripojene zatezi |
|
|
550 |
// |
|
|
551 |
int1 is_load () { |
|
|
552 |
int1 load; |
|
|
553 |
port_b_pullups (TRUE); |
|
|
554 |
delay_us (100); |
|
|
555 |
load = input (LOAD_ON); // precti stav kontaktu pripojeni zateze |
|
|
556 |
port_b_pullups (FALSE); |
|
|
557 |
return (load); |
|
|
558 |
} |
|
|
559 |
|
|
|
560 |
|
|
|
561 |
// cte stav nastavovacich tlacitek |
|
|
562 |
// vraci masky stisknutych tlacitek, 0 = klidovy stav |
|
|
563 |
// |
|
|
564 |
int8 read_keys () { |
|
|
565 |
static int1 up_key_old; |
|
|
566 |
static int1 set_key_old; |
|
|
567 |
static int8 keys; |
|
|
568 |
int1 key_state; |
|
|
569 |
|
|
|
570 |
key_state = input (UP); |
|
|
571 |
if (key_state != up_key_old) |
|
|
572 |
up_key_old = key_state; |
|
|
573 |
else |
|
|
574 |
if (! key_state) |
|
|
575 |
keys |= UP_MASK; |
|
|
576 |
else |
|
|
577 |
keys &= ~UP_MASK; |
|
|
578 |
|
|
|
579 |
key_state = input (SET); |
|
|
580 |
if (key_state != set_key_old) |
|
|
581 |
set_key_old = key_state; |
|
|
582 |
else |
|
|
583 |
if (! key_state) |
|
|
584 |
keys |= SET_MASK; |
|
|
585 |
else |
|
|
586 |
keys &= ~SET_MASK; |
|
|
587 |
return (keys); |
|
|
588 |
} |
|
|
589 |
|
|
|
590 |
|
|
|
591 |
/////////////////////////////////////////////////// |
|
|
592 |
// |
|
|
593 |
// VYKONNE FUNKCE |
|
|
594 |
// |
|
|
595 |
/////////////////////////////////////////////////// |
|
|
596 |
|
|
|
597 |
// vybijeni baterie |
|
|
598 |
// |
|
|
599 |
void do_discharge () { |
|
|
600 |
int16 IB_val; |
|
|
601 |
int16 I_zero; |
|
|
602 |
int16 VB_val; |
|
|
603 |
int16 dec_cap; |
|
|
604 |
int1 load, load_old; |
|
|
605 |
int1 err; |
|
|
606 |
|
|
|
607 |
#ifdef DEBUG |
|
|
608 |
int16 max,min; |
|
|
609 |
int16 cnt; |
|
|
610 |
#endif |
|
|
611 |
|
|
|
612 |
// signalizuj neduveryhodnost zbyvajici kapacity baterie |
|
|
613 |
if (invalid_cap) { |
|
|
614 |
blink = 1; |
|
|
615 |
leds_invalid_cap (); |
|
|
616 |
delay_ms (500); |
|
|
617 |
leds_all_off (); |
|
|
618 |
} |
|
|
619 |
|
|
|
620 |
// nastaveni AD prevodniku: reference je 2.5V posun mereni proudu o 2,51V => cim vetsi prout, tim nizzsi cislo z prevodniku |
|
|
621 |
setup_adc_ports (sAN0 | sAN1 | sAN2 | sAN3 | sAN5 | VSS_VREF); |
|
|
622 |
setup_vref (VREF_HIGH | VREF_A2 | 8); // na A2 vystup reference 2.51V |
|
|
623 |
delay_ms (1); |
|
|
624 |
|
|
|
625 |
I_zero = measure_offset (); // precti klidovou hodnotu, tedy offset OZ - nulovy odebirany proud |
|
|
626 |
|
|
|
627 |
output_high (BATT_ON); |
|
|
628 |
leds_dis (); // signalizuj zbyvajici kapacitu bateie |
|
|
629 |
|
|
|
630 |
err = 0; |
|
|
631 |
blink = 1; |
|
|
632 |
l_tick = 0; |
|
|
633 |
s_tick = 0; |
|
|
634 |
|
|
|
635 |
// jeden pruchod smycku zabere max 2000 taktu |
|
|
636 |
for(;;) { |
|
|
637 |
restart_wdt (); |
|
|
638 |
if (s_tick) { |
|
|
639 |
s_tick = 0; |
|
|
640 |
IB_val = measure_IB (); // mer proud odebirany z baterie |
|
|
641 |
if (IB_val == 0 ) { |
|
|
642 |
// proudove pretizeni |
|
|
643 |
output_low (BATT_ON); // odpoj baterii |
|
|
644 |
err = 1; // signalizuj chybu |
|
|
645 |
} |
|
|
646 |
dec_cap = I_zero - IB_val; // zbav se ofsetu OZ |
|
|
647 |
if (B_cap > dec_cap) |
|
|
648 |
B_cap = B_cap - dec_cap; // uprav zbyvajici kapacitu baterie |
|
|
649 |
|
|
|
650 |
if (! err) |
|
|
651 |
VB_val = measure_VB (); // napeti baterie je mozne merit jen pokud neni odpojena |
|
|
652 |
|
|
|
653 |
#ifdef DEBUG |
|
|
654 |
if (IB_val > max) |
|
|
655 |
max = IB_val; |
|
|
656 |
if (IB_val < min) |
|
|
657 |
min = IB_val; |
|
|
658 |
cnt++; |
|
|
659 |
#endif |
|
|
660 |
} |
|
|
661 |
|
|
|
662 |
if (l_tick) { |
|
|
663 |
l_tick = 0; |
|
|
664 |
if (! is_load ()) { |
|
|
665 |
return; // koncime, zatez odpojena |
|
|
666 |
} |
|
|
667 |
|
|
|
668 |
if (VB_val < VB_MIN) { |
|
|
669 |
// baterie zcela vybita |
|
|
670 |
B_cap = 0; // nastav prazdnou kapacitu |
|
|
671 |
invalid_cap = 0; // aktualni kapacita baterie je nyni znama |
|
|
672 |
return; |
|
|
673 |
} |
|
|
674 |
|
|
|
675 |
if (err) { |
|
|
676 |
leds_err (); // signalizuj chybu |
|
|
677 |
} |
|
|
678 |
else { |
|
|
679 |
if (VB_val < VB_LOW) { |
|
|
680 |
leds_VB_low (); // signalizuj temer vybitou baterii |
|
|
681 |
} |
|
|
682 |
else { |
|
|
683 |
leds_dis (); // signalizuj zbyvajici kapacitu bateie |
|
|
684 |
} |
|
|
685 |
} |
|
|
686 |
|
|
|
687 |
#ifdef DEBUG |
|
|
688 |
printf ("cnt:%lu z:%lu max:%ld delta:%u dec:%lu\n\r",cnt,I_zero,max,(int8)(max-min),dec_cap); |
|
|
689 |
max = 0; |
|
|
690 |
min = 1024; |
|
|
691 |
cnt = 0; |
|
|
692 |
#endif |
|
|
693 |
} |
|
|
694 |
} |
|
|
695 |
} |
|
|
696 |
|
|
|
697 |
|
|
|
698 |
// proces nabijeni baterie |
|
|
699 |
// |
|
|
700 |
void do_charge () { |
|
|
701 |
int1 chrg; |
|
|
702 |
int1 err; |
|
|
703 |
int16 I_zero; |
|
|
704 |
int16 IB_val; |
|
|
705 |
int16 inc_cap; |
|
|
706 |
int32 fast_chrg; |
|
|
707 |
int8 pwm; |
|
|
708 |
int16 duty; |
|
|
709 |
|
|
|
710 |
#ifdef DEBUG |
|
|
711 |
int16 max,min; |
|
|
712 |
int16 vs_val; |
|
|
713 |
#endif |
|
|
714 |
|
|
|
715 |
// vypocti mez do ktere budeme nabijet vyssim proudem |
|
|
716 |
// fast_chrg = (B_cap_4_4 - B_cap) / 64; |
|
|
717 |
fast_chrg = (B_cap_4_4 - B_cap) / 72; |
|
|
718 |
fast_chrg *= chrg_eff; |
|
|
719 |
fast_chrg += B_cap; |
|
|
720 |
#ifdef DEBUG |
|
|
721 |
// printf ("%lu %u %lu %lu\n\r\n\r",B_cap_4_4, chrg_eff,B_cap, fast_chrg); |
|
|
722 |
#endif |
|
|
723 |
|
|
|
724 |
err = 0; |
|
|
725 |
s_tick = 0; |
|
|
726 |
l_tick = 0; |
|
|
727 |
pwm = 0; |
|
|
728 |
chrg = 0; |
|
|
729 |
|
|
|
730 |
// nastaveni AD prevodniku, reference je VDD = 5V , zadny posun napeti pri mereni proudu => cim vyssi proud, tim vyssi cislo z prevodniku |
|
|
731 |
setup_adc_ports (sAN0 | sAN1 | sAN2 | sAN3 | sAN5 | VSS_VDD); |
|
|
732 |
setup_vref (VREF_LOW | VREF_A2 | 2); // na A2 vystup reference 0.416V |
|
|
733 |
delay_ms (1); |
|
|
734 |
I_zero = measure_offset (); // precti klidovou hodnotu, tedy ofset OZ - nulovy nabijeci proud |
|
|
735 |
|
|
|
736 |
if (invalid_cap == 0 && |
|
|
737 |
TB_val < TB_MAX && |
|
|
738 |
TB_VAL > TB_MIN) { |
|
|
739 |
// kapacita baterie je znama a teplota baterie je v mezich |
|
|
740 |
output_high (BATT_ON); // pripoj baterii |
|
|
741 |
output_high (CHRG_ON); // pripoj zdroj nabijeni |
|
|
742 |
delay_ms (500); // cekej na ustaleni menice |
|
|
743 |
chrg = 1; |
|
|
744 |
} |
|
|
745 |
|
|
|
746 |
if (measure_VS () < VS_MIN) { // kontrola napeti zatizeneho menice |
|
|
747 |
// napajeci zdroj je prilis mekky |
|
|
748 |
err = 1; // signalizuj chybu |
|
|
749 |
chrg = 0; // ukonci nabijeni |
|
|
750 |
output_low (CHRG_ON); // odpoj zdroj nabijeni |
|
|
751 |
output_low (BATT_ON); // odpoj baterii |
|
|
752 |
delay_ms (300); // cekej na ustaleni menice |
|
|
753 |
} |
|
|
754 |
|
|
|
755 |
// jeden pruchod smyckou zabere max 3000 taktu |
|
|
756 |
for (;;) { |
|
|
757 |
restart_wdt (); |
|
|
758 |
if (s_tick) { |
|
|
759 |
s_tick = 0; |
|
|
760 |
IB_val = measure_IB (); // mer proud dodavany do baterie 1760 taktu |
|
|
761 |
if (IB_val > I_zero) // zbav se ofsetu OZ |
|
|
762 |
IB_val -= I_zero; |
|
|
763 |
else |
|
|
764 |
IB_val = 0; |
|
|
765 |
// nasledujici sekvence zabere max 300 taktu |
|
|
766 |
if (chrg) { |
|
|
767 |
if (IB_val == 0) { // tece vubec nejaky nabijeci proud ? |
|
|
768 |
// NE netece |
|
|
769 |
err = 1; // signalizuj chybu |
|
|
770 |
chrg = 0; // ukonci nabijeni |
|
|
771 |
output_low (CHRG_ON); |
|
|
772 |
output_low (BATT_ON); |
|
|
773 |
} |
|
|
774 |
else { |
|
|
775 |
// ANO tece |
|
|
776 |
inc_cap = IB_val * chrg_eff; // uprav koeficientem ucinnosti nabijeni |
|
|
777 |
inc_cap = inc_cap >> (6-1); // zbav se vynasobeni 64x a vynasob dvema, protoze krok proudu pri nabijeni je dvojnasobny proti vybijeni |
|
|
778 |
B_cap = B_cap + inc_cap; // uprav kapacitu baterie |
|
|
779 |
} |
|
|
780 |
} |
|
|
781 |
#ifdef DEBUG |
|
|
782 |
if (IB_val > max) |
|
|
783 |
max = IB_val; |
|
|
784 |
if (IB_val < min) |
|
|
785 |
min = IB_val; |
|
|
786 |
#endif |
|
|
787 |
} |
|
|
788 |
|
|
|
789 |
if (l_tick) { |
|
|
790 |
l_tick = 0; |
|
|
791 |
|
|
|
792 |
measure_temp (); // mer teplotu baterie - 1100 taktu |
|
|
793 |
|
|
|
794 |
if (measure_VS () < VS_MIN) |
|
|
795 |
return; // koncime, napajeci zdroj byl odpojen |
|
|
796 |
|
|
|
797 |
if (is_load ()) |
|
|
798 |
return; // koncime, je pripojena zatez |
|
|
799 |
|
|
|
800 |
if (invalid_cap) |
|
|
801 |
leds_invalid_cap (); // signalizace nezname aktualni kapacity baterie - nutno nejdive baterii vybit |
|
|
802 |
else |
|
|
803 |
if (err) |
|
|
804 |
leds_err (); // signalizace chyby |
|
|
805 |
else { |
|
|
806 |
// signalizace nabiti baterie |
|
|
807 |
if ( leds_chrg () == 4 || TB_val > TB_MAX) { |
|
|
808 |
// baterie je plne nabita |
|
|
809 |
output_low (CHRG_ON); |
|
|
810 |
output_low (BATT_ON); |
|
|
811 |
chrg = 0; |
|
|
812 |
B_cap = B_cap_4_4; |
|
|
813 |
} |
|
|
814 |
else { |
|
|
815 |
if (B_cap > fast_chrg) |
|
|
816 |
duty = chrg_01C; // temer nabito dale nabijime 0.1C |
|
|
817 |
else |
|
|
818 |
duty = chrg_02C; // nabijeni proudem max. 0.2C |
|
|
819 |
|
|
|
820 |
if (pwm == 0) { |
|
|
821 |
output_high (CHRG_ON); |
|
|
822 |
chrg = 1; |
|
|
823 |
} |
|
|
824 |
else { |
|
|
825 |
if (pwm >= duty / IB_val) { // 400 taktu |
|
|
826 |
output_low (CHRG_ON); |
|
|
827 |
chrg = 0; |
|
|
828 |
} |
|
|
829 |
} |
|
|
830 |
pwm++; |
|
|
831 |
} |
|
|
832 |
} |
|
|
833 |
|
|
|
834 |
#ifdef DEBUG |
|
|
835 |
restart_wdt (); |
|
|
836 |
// printf ("z:%lu h:%ld add:%lu cap:%lu T:%u\n\r",I_zero,max,inc_cap,B_cap,TB_val); |
|
|
837 |
// printf ("pwm:%u z:%lu max:%lu d:%lu\n\r",pwm,I_zero,max,max-min); |
|
|
838 |
// printf ("%lu %lu\n\r",B_cap, fast_chrg); |
|
|
839 |
printf ("z:%lu max:%lu delta:%u inc:%lu\n\r",I_zero,max,(int8)(max-min),inc_cap); |
|
|
840 |
|
|
|
841 |
max = 0; |
|
|
842 |
min = 1024; |
|
|
843 |
#endif |
|
|
844 |
} |
|
|
845 |
} |
|
|
846 |
} |
|
|
847 |
|
|
|
848 |
|
|
|
849 |
// upravi kapacitu baterie dle samovybijeni |
|
|
850 |
// zabere max. 2000 cyklu |
|
|
851 |
// |
|
|
852 |
void selfdischarge (int8 day_cnt) { |
|
|
853 |
int8 k2; |
|
|
854 |
int16 temp; |
|
|
855 |
int32 dec_cap; |
|
|
856 |
|
|
|
857 |
// realizuje upravu koeficientu samovybijeni podle teploty k2 = k * Z * delta_TB |
|
|
858 |
// zmena Z je 1.05 na stupen |
|
|
859 |
if (TB_avr24 > TB_ref) |
|
|
860 |
temp = (3 * (TB_avr24 - TB_ref)) + 64; |
|
|
861 |
else { |
|
|
862 |
temp = 3 * (TB_ref - TB_avr24); |
|
|
863 |
if (temp > 64) |
|
|
864 |
temp = 0; |
|
|
865 |
else |
|
|
866 |
temp = 64 - temp; |
|
|
867 |
} |
|
|
868 |
temp = (temp * k) / 64; |
|
|
869 |
k2 = (int8)temp; |
|
|
870 |
|
|
|
871 |
// v prvnich 5 dnech je samovybijeni strmejsi |
|
|
872 |
if (day_cnt < 5) |
|
|
873 |
k2 = k2 * 2; |
|
|
874 |
dec_cap = k2 * CAP_BATT; |
|
|
875 |
if (B_cap > dec_cap) |
|
|
876 |
B_cap -=dec_cap; |
|
|
877 |
#ifdef DEBUG |
|
|
878 |
// printf ("k:%u k2:%u dec_cap:%lu cap:%lu ",k,k2,dec_cap,B_cap); |
|
|
879 |
#endif |
|
|
880 |
} |
|
|
881 |
|
|
|
882 |
|
|
|
883 |
////////////////////////////////////////////////////// |
|
|
884 |
// |
|
|
885 |
// PRIPRAVNE A NASTAVOVACI FUNKCE |
|
|
886 |
// |
|
|
887 |
////////////////////////////////////////////////////// |
|
|
888 |
|
|
|
889 |
// pripravi promenne pro beh programu |
|
|
890 |
// |
|
|
891 |
void prepare_var () { |
|
|
892 |
int16 B_cap; |
|
|
893 |
int8 tmp8; |
|
|
894 |
int16 tmp16; |
|
|
895 |
int32 tmp32; |
|
|
896 |
float tmpf; |
|
|
897 |
|
|
|
898 |
// priprav meze pro signalizaci stavu vybiti baterie |
|
|
899 |
B_cap = read_eeprom (B_CAP_L_ADDR); |
|
|
900 |
B_cap *= 100; |
|
|
901 |
tmp16 = read_eeprom (B_CAP_H_ADDR); |
|
|
902 |
tmp16 *= 1000; |
|
|
903 |
B_cap += tmp16; // kapacita baterie v mAh |
|
|
904 |
|
|
|
905 |
B_cap_4_4 = B_cap * CAP_BATT; |
|
|
906 |
// B_cap_4_4 = 100 * CAP_BATT; |
|
|
907 |
B_cap_2_4 = B_cap_4_4 / 2; |
|
|
908 |
B_cap_1_4 = B_cap_2_4 / 2; |
|
|
909 |
B_cap_3_4 = B_cap_2_4 + B_cap_1_4; |
|
|
910 |
|
|
|
911 |
// priprav omezeni nabijecich proudu |
|
|
912 |
tmpf = B_cap / 10; |
|
|
913 |
tmpf *= 256; |
|
|
914 |
tmpf /= 4.88; |
|
|
915 |
chrg_01C = (int16)tmpf; |
|
|
916 |
chrg_02C = chrg_01C * 2; |
|
|
917 |
|
|
|
918 |
// priprav koeficient ucinnosti nabijeni |
|
|
919 |
// eff = 1+(( read_eeprom (EFF_ADDR) * 5) / 100.0); // koeficient s jednickou |
|
|
920 |
// eff -= 0.1; |
|
|
921 |
// eff = 64 / eff; // ucinnost nabijeni (0-1) nasovena 64 |
|
|
922 |
// chrg_eff = (int8)(eff); // ucinnost nabijeni vhodna pro celociselnou aritmetiku |
|
|
923 |
|
|
|
924 |
chrg_eff = CHRG_EFF_TAB [read_eeprom (EFF_ADDR)]; // toto je vyhodnejsi varianta |
|
|
925 |
|
|
|
926 |
// priprav koeficient samovybijeni |
|
|
927 |
tmp8 = read_eeprom (LOSS_CAP_H_ADDR) * 10 + read_eeprom (LOSS_CAP_L_ADDR); // ztracena kapacita v procentech |
|
|
928 |
tmp32 = B_cap; |
|
|
929 |
tmp32 *= tmp8; |
|
|
930 |
tmp16 = tmp32 / 100; // ztracena kapacita v mAh |
|
|
931 |
tmp8 = read_eeprom (LOSS_DAY_H_ADDR) * 10 + read_eeprom (LOSS_DAY_L_ADDR); // pocet dni, za kterou se kapacita ztratila |
|
|
932 |
k = tmp16 / tmp8; // strmost poklesu samovybijeni v mAh / den |
|
|
933 |
|
|
|
934 |
TB_ref = read_eeprom (TB_REF_ADDR); // teplota, pri ktere k samovybijeni dochazelo |
|
|
935 |
|
|
|
936 |
#ifdef DEBUG |
|
|
937 |
// printf ("chrg_eff:%lu ",B_cap); |
|
|
938 |
// printf ("chrg_eff:%u ",chrg_eff); |
|
|
939 |
// printf ("k:%u ",k); |
|
|
940 |
#endif |
|
|
941 |
} |
|
|
942 |
|
|
|
943 |
|
|
|
944 |
// pripravi konstantu pro odmereni 1 hod pomoci wdt |
|
|
945 |
// |
|
|
946 |
prepare_hour_time () { |
|
|
947 |
int32 hour_time_cor; |
|
|
948 |
|
|
|
949 |
// vypocti potrebny pocet tiku wdt pro odmereni jedne hodiny |
|
|
950 |
hour_time_cor = 400 - hour_time; |
|
|
951 |
hour_time_cor *= HOUR_TIME_WDT; |
|
|
952 |
hour_time_cor /= hour_time; |
|
|
953 |
hour_time = HOUR_TIME_WDT + (int16)hour_time_cor; |
|
|
954 |
} |
|
|
955 |
|
|
|
956 |
|
|
|
957 |
// priprav vse pro minimalizaci spotreby ve spanku |
|
|
958 |
// |
|
|
959 |
void prepare_sleep () { |
|
|
960 |
leds_all_off (); |
|
|
961 |
output_low (BATT_ON); |
|
|
962 |
output_low (CHRG_ON); |
|
|
963 |
setup_vref (FALSE); |
|
|
964 |
} |
|
|
965 |
|
|
|
966 |
|
|
|
967 |
// nastavi parametry programu |
|
|
968 |
// |
|
|
969 |
void do_set_par () { |
|
|
970 |
int8 par_num; // cislo parametru |
|
|
971 |
int8 par_val; // hodnota parametru |
|
|
972 |
int8 key_timer; // pro osetreni zakmitu nastavovacich tlacitek |
|
|
973 |
int8 keys; // stav nastavovacich tlacitek |
|
|
974 |
int1 set_par; // jsme v rezimu nastavovani hodnoty parametru |
|
|
975 |
int1 wait_release; // cekame na uvolneni tlacitka |
|
|
976 |
|
|
|
977 |
leds_all_on (); // oznam, ze jsme v nastavovacim rezimu |
|
|
978 |
delay_ms (1000); |
|
|
979 |
|
|
|
980 |
par_num = 0; |
|
|
981 |
s_tick = 0; |
|
|
982 |
l_tick = 0; |
|
|
983 |
key_timer = 0; |
|
|
984 |
wait_release = 0; |
|
|
985 |
set_par = 0; |
|
|
986 |
num_to_leds (par_num); // zobraz zvoleny parametr |
|
|
987 |
|
|
|
988 |
for (;;) { |
|
|
989 |
restart_wdt (); |
|
|
990 |
if (s_tick) { |
|
|
991 |
s_tick = 0; |
|
|
992 |
if (key_timer != 0) |
|
|
993 |
key_timer--; |
|
|
994 |
else { |
|
|
995 |
key_timer = 5; |
|
|
996 |
keys = read_keys (); // precti stav tlacitek |
|
|
997 |
if (keys & SET_MASK) { |
|
|
998 |
// tlacitko SET je stisknuto - rezim vyberu parametru |
|
|
999 |
if (set_par) { |
|
|
1000 |
if (par_val != read_eeprom (par_num)) { // prechazime z rezimu nastaveni parametru, uloz zvoleny parametr |
|
|
1001 |
write_eeprom (par_num, par_val); // uloz jen pokud byl zmenen |
|
|
1002 |
if (par_num == LOSS_DAY_H_ADDR || |
|
|
1003 |
par_num == LOSS_DAY_L_ADDR) |
|
|
1004 |
write_eeprom (TB_REF_ADDR,TB_avr24); // pokud byla zmenena hodnota ztracene kapacity samovybijenim, uloz TB_avr24 jako refrerencni |
|
|
1005 |
} |
|
|
1006 |
num_to_leds (par_num); // zobraz zpatky zvoleny parametr |
|
|
1007 |
set_par = 0; |
|
|
1008 |
} |
|
|
1009 |
else { |
|
|
1010 |
// vybirame parametr |
|
|
1011 |
if (keys & UP_MASK) { |
|
|
1012 |
if (! wait_release) { |
|
|
1013 |
if (par_num < 6) |
|
|
1014 |
par_num++; |
|
|
1015 |
else |
|
|
1016 |
par_num = 0; |
|
|
1017 |
num_to_leds (par_num); // zobrazeni vybraneho parametru |
|
|
1018 |
wait_release = 1; // cekame na uvolneni tlacitka UP |
|
|
1019 |
} |
|
|
1020 |
} |
|
|
1021 |
else |
|
|
1022 |
wait_release = 0; // tlacitko UP bylo uvolneno |
|
|
1023 |
} |
|
|
1024 |
} |
|
|
1025 |
else { |
|
|
1026 |
// tlacitko SET je uvolneno - rezim nastaveni parametru |
|
|
1027 |
if (! set_par) { |
|
|
1028 |
par_val = read_eeprom (par_num); // prechazime z rezimu vyberu parametru, vyzvedni zvoleny parametr |
|
|
1029 |
num_to_leds (par_val); // zobraz hodotu parametru |
|
|
1030 |
set_par = 1; |
|
|
1031 |
} |
|
|
1032 |
else { |
|
|
1033 |
// nastavujeme parametr |
|
|
1034 |
if (keys & UP_MASK) { |
|
|
1035 |
if (! wait_release) { |
|
|
1036 |
if (par_val < PAR_MAX_TAB [par_num]) |
|
|
1037 |
par_val++; |
|
|
1038 |
else |
|
|
1039 |
par_val = 0; |
|
|
1040 |
num_to_leds (par_val); // zobraz hodnotu parametru |
|
|
1041 |
wait_release = 1; // cekame na uvolneni tlacitka UP |
|
|
1042 |
} |
|
|
1043 |
} |
|
|
1044 |
else |
|
|
1045 |
wait_release = 0; |
|
|
1046 |
} |
|
|
1047 |
} |
|
|
1048 |
} |
|
|
1049 |
} |
|
|
1050 |
|
|
|
1051 |
if (l_tick) { |
|
|
1052 |
l_tick = 0; |
|
|
1053 |
if (measure_VS () < VS_MIN) |
|
|
1054 |
break; // koncime, napajeci zdroj odpojen |
|
|
1055 |
} |
|
|
1056 |
} |
|
|
1057 |
prepare_var (); // konec nastavovani, aktualizuj promenne programu |
|
|
1058 |
} |
|
|
1059 |
|
|
|
1060 |
|
|
|
1061 |
|
|
|
1062 |
/////////////////////////////////////////////////// |
|
|
1063 |
// HLAVNI FUNKCE |
|
|
1064 |
/////////////////////////////////////////////////// |
|
|
1065 |
|
|
|
1066 |
main () { |
|
|
1067 |
int1 load_old; |
|
|
1068 |
int1 load; |
|
|
1069 |
int1 no_load; |
|
|
1070 |
int1 start_TB; // spust mrereni teploty baterie |
|
|
1071 |
int16 wdt_timer; // pro odmereni hodiny pomoci wdt |
|
|
1072 |
int8 hour_timer; // pro odmerovani hodin |
|
|
1073 |
int8 day_timer; // pro odmerovani dni od nabiti |
|
|
1074 |
int16 TB_avr_tmp; // pro vypocet prumerne teploty |
|
|
1075 |
|
|
|
1076 |
|
|
|
1077 |
#ifdef DEBUG |
|
|
1078 |
int16 c; |
|
|
1079 |
int16 inc_cap,IB_val,I_zero; |
|
|
1080 |
int8 val; |
|
|
1081 |
#endif |
|
|
1082 |
|
|
|
1083 |
init_ports (); |
|
|
1084 |
|
|
|
1085 |
if (restart_cause () != WDT_TIMEOUT) { |
|
|
1086 |
// mereni skutecne doby behu wdt proved pro vseshny resety krome wdt |
|
|
1087 |
setup_oscillator (OSC_4MHZ | OSC_NORMAL); |
|
|
1088 |
delay_ms (100); |
|
|
1089 |
setup_timer_1 (T1_INTERNAL | T1_DIV_BY_1); |
|
|
1090 |
setup_wdt (WDT_288MS); |
|
|
1091 |
hour_time = 0; |
|
|
1092 |
set_timer1 (~1000); |
|
|
1093 |
restart_wdt (); |
|
|
1094 |
for (;;) { |
|
|
1095 |
if (TMR1IF) { |
|
|
1096 |
hour_time++; |
|
|
1097 |
TMR1IF = 0; |
|
|
1098 |
set_timer1 (~1000); |
|
|
1099 |
} |
|
|
1100 |
} |
|
|
1101 |
} |
|
|
1102 |
|
|
|
1103 |
setup_oscillator (OSC_4MHZ | OSC_NORMAL); |
|
|
1104 |
setup_timer_0 (RTCC_INTERNAL| RTCC_DIV_1); |
|
|
1105 |
setup_wdt (WDT_288MS); |
|
|
1106 |
setup_timer_1 (T1_INTERNAL | T1_DIV_BY_1); |
|
|
1107 |
set_timer1 (S_TICK_TIME); |
|
|
1108 |
setup_spi (FALSE); |
|
|
1109 |
setup_comparator (NC_NC_NC_NC); |
|
|
1110 |
setup_vref (FALSE); |
|
|
1111 |
setup_ccp1 (CCP_OFF); |
|
|
1112 |
setup_adc (ADC_CLOCK_INTERNAL); // doba prevodu cca 48 uS |
|
|
1113 |
setup_adc_ports (sAN0 | sAN1 | sAN2 | sAN3 | sAN5 | VSS_VDD); |
|
|
1114 |
|
|
|
1115 |
enable_interrupts (INT_TIMER1); |
|
|
1116 |
enable_interrupts (GLOBAL); |
|
|
1117 |
|
|
|
1118 |
prepare_var (); // priprav promenne pro beh programu z udaju o vlastnostech baterie |
|
|
1119 |
prepare_hour_time (); |
|
|
1120 |
|
|
|
1121 |
|
|
|
1122 |
////////////////////////////////////////////////// |
|
|
1123 |
|
|
|
1124 |
// uvodni bliknuti ledkou |
|
|
1125 |
output_high (LED1_G); |
|
|
1126 |
delay_ms (250); |
|
|
1127 |
output_low (LED1_G); |
|
|
1128 |
|
|
|
1129 |
|
|
|
1130 |
/* |
|
|
1131 |
#ifdef DEBUG |
|
|
1132 |
output_high (BATT_ON); |
|
|
1133 |
printf ("Ahoj %lu\n\r",hour_time); |
|
|
1134 |
|
|
|
1135 |
for (;;) { |
|
|
1136 |
restart_wdt (); |
|
|
1137 |
if (is_load ()) |
|
|
1138 |
break; // napajeci zdroj byl pripojen |
|
|
1139 |
delay_ms (100); |
|
|
1140 |
} |
|
|
1141 |
|
|
|
1142 |
B_cap = B_cap_2_4; |
|
|
1143 |
invalid_cap = 0; |
|
|
1144 |
|
|
|
1145 |
set_timer1 (0); |
|
|
1146 |
// zde se meri doba trvani funkci nebo vybraneho kodu |
|
|
1147 |
// selfdischarge (0); //OK |
|
|
1148 |
do_discharge (); |
|
|
1149 |
|
|
|
1150 |
c = get_timer1 (); |
|
|
1151 |
// printf ("T:%lu %lu %u \n\r",c,B_cap,chrg_eff); |
|
|
1152 |
|
|
|
1153 |
printf ("T:%lu\n\r",c); |
|
|
1154 |
output_low (BATT_ON); |
|
|
1155 |
delay_ms (250); |
|
|
1156 |
for (;;) |
|
|
1157 |
restart_wdt (); |
|
|
1158 |
#endif |
|
|
1159 |
*/ |
|
|
1160 |
|
|
|
1161 |
#ifdef DEBUG |
|
|
1162 |
invalid_cap = 0; |
|
|
1163 |
// B_cap = B_cap_3_4; |
|
|
1164 |
B_cap = B_cap_2_4; |
|
|
1165 |
#else |
|
|
1166 |
invalid_cap = 1; // nezname zbyvajici kapacitu baterie |
|
|
1167 |
B_cap = 0; // povazujeme ji za vybitou |
|
|
1168 |
#endif |
|
|
1169 |
|
|
|
1170 |
TB_avr24 = TB_DEFAULT; |
|
|
1171 |
TB_avr_tmp = 0; |
|
|
1172 |
wdt_timer = 0; |
|
|
1173 |
hour_timer = 0; |
|
|
1174 |
day_timer = 0; |
|
|
1175 |
start_TB = 1; |
|
|
1176 |
no_load = 0; |
|
|
1177 |
|
|
|
1178 |
// hlavni programova smycka |
|
|
1179 |
for (;;) { |
|
|
1180 |
restart_wdt (); |
|
|
1181 |
prepare_sleep (); |
|
|
1182 |
sleep (); |
|
|
1183 |
setup_adc_ports (sAN0 | sAN1 | sAN2 | sAN3 | sAN5 | VSS_VDD); |
|
|
1184 |
load = is_load (); // precti stav kontaktu pripojeni zateze |
|
|
1185 |
if (load != load_old) |
|
|
1186 |
load_old = load; // stav kontaktu neni platny |
|
|
1187 |
else { |
|
|
1188 |
if (load) { |
|
|
1189 |
if (! no_load) { |
|
|
1190 |
do_discharge (); // zatez pripojena, vybijime - ma vyssi prioritu |
|
|
1191 |
no_load = 1; // dalsi vybijeni je mozne az po odpojeni zateze |
|
|
1192 |
wdt_timer = 0; |
|
|
1193 |
} |
|
|
1194 |
} |
|
|
1195 |
else { |
|
|
1196 |
no_load = 0; // zatez byl odpojena |
|
|
1197 |
if (measure_VS () > VS_MIN) { // ma zdroj pro nabijeni dostatecne napeti? |
|
|
1198 |
if (input (SET)) |
|
|
1199 |
do_charge (); // zatez odpojena a pripojen zdroj pro nabijeni, nabijime - ma nizsi pioritu |
|
|
1200 |
else |
|
|
1201 |
do_set_par (); // prechazime do rezimu pro nastavovani parametru programu |
|
|
1202 |
TB_avr_tmp = 0; |
|
|
1203 |
wdt_timer = 0; |
|
|
1204 |
hour_timer = 0; |
|
|
1205 |
day_timer = 0; |
|
|
1206 |
} |
|
|
1207 |
} |
|
|
1208 |
} |
|
|
1209 |
|
|
|
1210 |
// reseni samovybijeni |
|
|
1211 |
if (wdt_timer < hour_time) |
|
|
1212 |
wdt_timer++; |
|
|
1213 |
else { |
|
|
1214 |
// uplynula hodina |
|
|
1215 |
start_TB = 1; // odstartuj mereni teploty |
|
|
1216 |
wdt_timer = 0; // natahni odmerovani hodiny |
|
|
1217 |
if (hour_timer < 23) |
|
|
1218 |
hour_timer++; |
|
|
1219 |
else { |
|
|
1220 |
// uplynul den |
|
|
1221 |
TB_avr24 = TB_avr_tmp / 24; // vypocti prumernou teplotu za den |
|
|
1222 |
if (day_timer < 90) |
|
|
1223 |
day_timer++; |
|
|
1224 |
else |
|
|
1225 |
invalid_cap = 1; // po 90 dnech uz neverime kapacite baterie |
|
|
1226 |
selfdischarge (day_timer); // uprav kapacitu baterie s ohledem na samovybijeni |
|
|
1227 |
#ifdef DEBUG |
|
|
1228 |
// printf ("TB:%u\n\r",TB_avr24); |
|
|
1229 |
#endif |
|
|
1230 |
TB_avr_tmp = 0; |
|
|
1231 |
hour_timer = 0; |
|
|
1232 |
} |
|
|
1233 |
} |
|
|
1234 |
|
|
|
1235 |
// realizace mereni teploty - je v mnoha krocich |
|
|
1236 |
if (start_TB) { |
|
|
1237 |
if (measure_temp () == 0) { |
|
|
1238 |
#ifdef DEBUG |
|
|
1239 |
// printf("T:%u ",TB_val); |
|
|
1240 |
#endif |
|
|
1241 |
TB_avr_tmp += TB_val; // pocitame prumer teploty |
|
|
1242 |
start_TB = 0; |
|
|
1243 |
} |
|
|
1244 |
} |
|
|
1245 |
} |
|
|
1246 |
|
|
|
1247 |
} |