/Designs/HAM_Constructions/IBP20/SW/V_1_1/ibp2.c |
---|
0,0 → 1,1247 |
//********************************************************************** |
// INFO BATTERY PACK |
//********************************************************************** |
// (c) OK1XGL 2008 |
// verze 1.0 - uvodni verze |
// 1.1 - referencni teplota pro samovybijeni se uklada pri zadani doby mereni samovybijeni |
// |
// |
#include "ibp2.h" |
// nastavi orientaci a klidovy stav portu |
// |
void init_ports (void) { |
set_tris_a (0b00101011); |
output_a (0b000000000); |
set_tris_b (0b11010000); |
output_b (0b00100000); |
port_b_pullups (FALSE); |
} |
////////////////////////////////////////////////// |
// |
// iterrupty |
// cele preruseni zabere 33+xx+30 cyklu |
// |
////////////////////////////////////////////////// |
// periodicky casovac |
// |
#INT_TIMER1 |
void tmr1_int (void) { |
// natahovani casovace |
set_timer1 (S_TICK_TIME); |
s_tick = 1; |
if (l_timer == 0) { |
l_timer = L_TICK_TIME; |
l_tick = 1; |
blink = ~blink; |
if (blink) |
slow_blink = ~slow_blink; |
} |
else |
l_timer--; |
} |
/////////////////////////////////////////////////// |
// |
// FUNKCE PRO PRACI S TEPLOMEREM |
// |
////////////////////////////////////////////////// |
// testuje pritomnost teplomeru, pri pritomnosti vraci 1 |
// zabere 1060 taktu |
// |
int8 TM_present() { |
int1 present; |
output_low (TM_PIN); |
output_fixed (TM_PIN); |
delay_us (500); |
disable_interrupts (GLOBAL); |
output_float (TM_PIN); |
if(!input (TM_PIN)) { |
enable_interrupts (GLOBAL); |
return (0); |
} |
delay_us (65); |
present = input(TM_PIN); |
enable_interrupts (GLOBAL); |
delay_us (440); |
if (present) |
return (0); |
else |
return (1); |
} |
// precte bajt z teplomeru |
// |
int8 TM_read_byte() { |
int8 i,data; |
for(i = 0; i < 8; ++i) { |
disable_interrupts (GLOBAL); |
output_low (TM_PIN); |
output_fixed (TM_PIN); |
delay_us (2); |
output_float (TM_PIN); |
delay_us (8); |
shift_right (&data,1,input(TM_PIN)); |
enable_interrupts (GLOBAL); |
delay_us (55); |
} |
return (data); |
} |
// zapise bajt do teplomeru |
// |
void TM_write_byte(int8 data) { |
int8 i; |
for (i = 0 ; i < 8; ++i) { |
disable_interrupts (GLOBAL); |
output_low (TM_PIN); |
output_fixed (TM_PIN); |
delay_us (5); |
if (shift_right (&data,1,0)) |
output_float (TM_PIN); |
delay_us (60); |
output_float (TM_PIN); |
delay_us (2); |
enable_interrupts (GLOBAL); |
} |
} |
// vraci 0 pri ukonceni mereni |
// vraci 1 pri rozpracovanem mereni |
// zabere max 1100 taktu na 1 cyklus |
// potrebuje 10 volani pro zmereni teploty |
// |
int8 measure_temp () { |
static int8 phase; |
static int8 tmp; |
int8 tmp2; |
switch (phase) { |
case 0: |
if (! TM_present ()) { // over pritomnost teplomeru |
phase = 0; |
TB_val = TB_DEFAULT; |
return (0); // teplomer neni pritomen, dal nelze pokracovat |
} |
break; |
case 1: |
TM_write_byte (0xcc); // preskoc na dalsi sadu prikazu |
break; |
case 2: |
TM_write_byte (0x44); // prikaz spust mereni teploty |
output_high (TM_PIN); // zapni tvrdy pullup |
output_fixed (TM_PIN); // |
break; |
case 3: |
case 4: |
case 5: // cekej nejmene 750 ms |
break; |
case 6: |
output_float (TM_PIN); // vyppni tvrdy pullup |
output_low (TM_PIN); // |
if (! TM_present ()) { // over pritomnost teplomeru |
phase = 0; |
TB_val = TB_DEFAULT; |
return (0); // teplomer neni pritomen, dal nelze pokracovat |
} |
break; |
case 7: |
TM_write_byte (0xcc); // preskoc na dalsi sadu prikazu |
break; |
case 8: |
TM_write_byte (0xbe); // prikaz precti zmerenou teplotu |
break; |
case 9: |
tmp = TM_read_byte () >> 4; // precti LSB bajt s teplotou a zahod destiny stupne |
break; |
case 10: |
tmp |= TM_read_byte () << 4; // precti MSB bajt s teplotou a sloz s LSB |
tmp2 = tmp & 0x7F; // |
if (tmp2 < 80) { // teplota je v moznem rozsahu (nahrada kontroly CRC - bylo by casove prilis dlouhe) |
if (tmp & 0x80) |
TB_val = 0; // zapornou teplotu povazujeme za nulovou |
else |
TB_val = tmp2; |
} |
phase = 0; |
return (0); |
break; |
default: |
phase = 0; |
TB_val = TB_DEFAULT; |
return (0); |
} |
phase++; |
return (1); |
} |
////////////////////////////////////////////////////// |
// |
// FUNNKCE PRO MERENI NAPETI A PROUDU |
// |
////////////////////////////////////////////////////// |
// meri velikost proudu z/do baterie a prumeruje z 8 mereni |
// zabere max 1760 taktu (1760 us) |
// |
int16 measure_IB (void) { |
int16 out; |
set_adc_channel (IB_CAN); |
delay_us (100); |
out = read_adc (ADC_START_AND_READ); |
delay_us (100); |
out += read_adc (ADC_START_AND_READ); |
delay_us (100); |
out += read_adc (ADC_START_AND_READ); |
delay_us (100); |
out += read_adc (ADC_START_AND_READ); |
delay_us (100); |
out += read_adc (ADC_START_AND_READ); |
delay_us (100); |
out += read_adc (ADC_START_AND_READ); |
delay_us (100); |
out += read_adc (ADC_START_AND_READ); |
delay_us (100); |
out += read_adc (ADC_START_AND_READ); |
out = out >> 3; |
return (out); |
} |
// meri velikost napeti baterie a provadi klouzavy prumer z 8 mereni |
// zabere max 320 taktu (320 us) |
// |
int16 measure_VB (void) { |
static int16 smpl [8]; |
static int8 i; |
int16 out; |
if (i >= 8-1) |
i = 0; |
else |
i++; |
set_adc_channel (VB_CAN); |
delay_us (100); |
smpl [i] = read_adc (ADC_START_AND_READ); |
out = smpl [0] + smpl [1] + smpl [2] + smpl [3] + |
smpl [4] + smpl [5] + smpl [6] + smpl [7]; |
out = out >> 3; |
return (out); |
} |
// meri velikost vstupniho napeti zdroje pro nabijeni |
// zabere max 200 taktu (200 us) |
// |
int16 measure_VS (void) { |
int16 out; |
set_adc_channel (VS_CAN); |
delay_us (100); |
out = read_adc (ADC_START_AND_READ); |
return (out); |
} |
// meri vystupni napeti OZ pro mereni proudu pri nulovem odberu - pro kompenzaci ofsetu OZ |
// |
int16 measure_offset (void) { |
int16 out; |
int8 i; |
// vypni vsechny spotrebice |
init_ports (); |
disable_interrupts (GLOBAL); |
ADIE = 1; |
PEIE = 1; |
delay_ms (500); |
// mer napeti OZ a vypocti prumer z 8 mereni |
set_adc_channel (IB_CAN); |
delay_us (100); |
out = 0; |
for (i = 0; i < 8; i++) { |
read_adc (ADC_START_ONLY); |
sleep (); |
out += read_adc (ADC_READ_ONLY); |
delay_us (100); |
restart_wdt (); |
} |
out = out >> 3; |
ADIE = 0; |
PEIE = 0; |
enable_interrupts (GLOBAL); |
return (out); |
} |
///////////////////////////////////////////////// |
// |
// FUNKCE PRO PRACI S LED |
// |
///////////////////////////////////////////////// |
// rozsviti vsechny led |
// |
void leds_all_on () { |
output_high (LED4_R); |
output_high (LED3_Y); |
output_high (LED2_Y); |
output_high (LED1_G); |
} |
// zhasne vsechny led |
// |
void leds_all_off () { |
output_low (LED4_R); |
output_low (LED3_Y); |
output_low (LED2_Y); |
output_low (LED1_G); |
} |
// signalizuje kapacitu baterie pri nabijeni |
// vraci cislo odpovidajici stavu nabiti |
// zabere max 40 cyklu |
// |
int8 leds_chrg (void) { |
if (B_cap >= B_cap_4_4) { |
leds_all_on (); |
return (4); // baterie plne nabita |
} |
if (B_cap > B_cap_3_4) { |
output_high (LED4_R); |
output_high (LED3_Y); |
output_high (LED2_Y); |
if (slow_blink) |
output_high (LED1_G); |
else |
output_low (LED1_G); |
return (3); |
} |
if (B_cap > B_cap_2_4) { |
output_high (LED4_R); |
output_high (LED3_Y); |
if (slow_blink) |
output_high (LED2_Y); |
else |
output_low (LED2_Y); |
output_low (LED1_G); |
return (2); |
} |
if (B_cap > B_cap_1_4) { |
output_high (LED4_R); |
if (slow_blink) |
output_high (LED3_Y); |
else |
output_low (LED3_Y); |
output_low (LED2_Y); |
output_low (LED1_G); |
return (1); |
} |
if (slow_blink) |
output_high (LED4_R); |
else |
output_low (LED4_R); |
output_low (LED3_Y); |
output_low (LED2_Y); |
output_low (LED1_G); |
return (0); |
} |
// signalizuje chybu |
// |
void leds_err () { |
output_low (LED1_G); |
output_low (LED4_R); |
if (blink) { |
output_high (LED2_Y); |
output_high (LED3_Y); |
} |
else { |
output_low (LED2_Y); |
output_low (LED3_Y); |
} |
} |
// signalizuje neznamou aktualni kapacitu baterie |
// |
void leds_invalid_cap () { |
output_low (LED2_Y); |
output_low (LED3_Y); |
if (blink) { |
output_high (LED1_G); |
output_high (LED4_R); |
} |
else { |
output_low (LED1_G); |
output_low (LED4_R); |
} |
} |
// signalizuje zbyvajici kapacitu baterie pri vybijeni |
// |
void leds_dis () { |
if (B_cap < B_cap_1_4) { |
output_low (LED1_G); |
output_low (LED2_Y); |
output_low (LED3_Y); |
output_high (LED4_R); |
return; |
} |
if (B_cap < B_cap_2_4) { |
output_low (LED1_G); |
output_low (LED2_Y); |
output_high (LED3_Y); |
output_low (LED4_R); |
return; |
} |
if (B_cap < B_cap_3_4) { |
output_low (LED1_G); |
output_high (LED2_Y); |
output_low (LED3_Y); |
output_low (LED4_R); |
return; |
} |
output_high (LED1_G); |
output_low (LED2_Y); |
output_low (LED3_Y); |
output_low (LED4_R); |
} |
// signalizuje temer vybitou baterii |
// |
void leds_VB_low () { |
output_low (LED1_G); |
output_low (LED2_Y); |
output_low (LED3_Y); |
if (slow_blink) |
output_high (LED4_R); |
else |
output_low (LED4_R); |
} |
// zobrazi cislo v rozsahu 0 - 9 v binarnim kodu na ledkach |
// |
void num_to_leds (int8 num) { |
switch (num) { |
case 0: |
output_low (LED4_R); // nejnizsi bit |
output_low (LED3_Y); |
output_low (LED2_Y); |
output_low (LED1_G); // nejvyssi bit |
break; |
case 1: |
output_high (LED4_R); // nejnizsi bit |
output_low (LED3_Y); |
output_low (LED2_Y); |
output_low (LED1_G); // nejvyssi bit |
break; |
case 2: |
output_low (LED4_R); // nejnizsi bit |
output_high (LED3_Y); |
output_low (LED2_Y); |
output_low (LED1_G); // nejvyssi bit |
break; |
case 3: |
output_high (LED4_R); // nejnizsi bit |
output_high (LED3_Y); |
output_low (LED2_Y); |
output_low (LED1_G); // nejvyssi bit |
break; |
case 4: |
output_low (LED4_R); // nejnizsi bit |
output_low (LED3_Y); |
output_high (LED2_Y); |
output_low (LED1_G); // nejvyssi bit |
break; |
case 5: |
output_high (LED4_R); // nejnizsi bit |
output_low (LED3_Y); |
output_high (LED2_Y); |
output_low (LED1_G); // nejvyssi bit |
break; |
case 6: |
output_low (LED4_R); // nejnizsi bit |
output_high (LED3_Y); |
output_high (LED2_Y); |
output_low (LED1_G); // nejvyssi bit |
break; |
case 7: |
output_high (LED4_R); // nejnizsi bit |
output_high (LED3_Y); |
output_high (LED2_Y); |
output_low (LED1_G); // nejvyssi bit |
break; |
case 8: |
output_low (LED4_R); // nejnizsi bit |
output_low (LED3_Y); |
output_low (LED2_Y); |
output_high (LED1_G); // nejvyssi bit |
break; |
case 9: |
output_high (LED4_R); // nejnizsi bit |
output_low (LED3_Y); |
output_low (LED2_Y); |
output_high (LED1_G); // nejvyssi bit |
break; |
default: |
output_low (LED4_R); // nejnizsi bit |
output_low (LED3_Y); |
output_low (LED2_Y); |
output_low (LED1_G); // nejvyssi bit |
} |
} |
/////////////////////////////////////////////////////// |
// |
// FUNKCE PRO CTENI TLACITEK A KONTAKTU |
// |
/////////////////////////////////////////////////////// |
// je pripojena zatez? |
// vraci 1 pri pripojene zatezi |
// |
int1 is_load () { |
int1 load; |
port_b_pullups (TRUE); |
delay_us (100); |
load = input (LOAD_ON); // precti stav kontaktu pripojeni zateze |
port_b_pullups (FALSE); |
return (load); |
} |
// cte stav nastavovacich tlacitek |
// vraci masky stisknutych tlacitek, 0 = klidovy stav |
// |
int8 read_keys () { |
static int1 up_key_old; |
static int1 set_key_old; |
static int8 keys; |
int1 key_state; |
key_state = input (UP); |
if (key_state != up_key_old) |
up_key_old = key_state; |
else |
if (! key_state) |
keys |= UP_MASK; |
else |
keys &= ~UP_MASK; |
key_state = input (SET); |
if (key_state != set_key_old) |
set_key_old = key_state; |
else |
if (! key_state) |
keys |= SET_MASK; |
else |
keys &= ~SET_MASK; |
return (keys); |
} |
/////////////////////////////////////////////////// |
// |
// VYKONNE FUNKCE |
// |
/////////////////////////////////////////////////// |
// vybijeni baterie |
// |
void do_discharge () { |
int16 IB_val; |
int16 I_zero; |
int16 VB_val; |
int16 dec_cap; |
int1 load, load_old; |
int1 err; |
#ifdef DEBUG |
int16 max,min; |
int16 cnt; |
#endif |
// signalizuj neduveryhodnost zbyvajici kapacity baterie |
if (invalid_cap) { |
blink = 1; |
leds_invalid_cap (); |
delay_ms (500); |
leds_all_off (); |
} |
// nastaveni AD prevodniku: reference je 2.5V posun mereni proudu o 2,51V => cim vetsi prout, tim nizzsi cislo z prevodniku |
setup_adc_ports (sAN0 | sAN1 | sAN2 | sAN3 | sAN5 | VSS_VREF); |
setup_vref (VREF_HIGH | VREF_A2 | 8); // na A2 vystup reference 2.51V |
delay_ms (1); |
I_zero = measure_offset (); // precti klidovou hodnotu, tedy offset OZ - nulovy odebirany proud |
output_high (BATT_ON); |
leds_dis (); // signalizuj zbyvajici kapacitu bateie |
err = 0; |
blink = 1; |
l_tick = 0; |
s_tick = 0; |
// jeden pruchod smycku zabere max 2000 taktu |
for(;;) { |
restart_wdt (); |
if (s_tick) { |
s_tick = 0; |
IB_val = measure_IB (); // mer proud odebirany z baterie |
if (IB_val == 0 ) { |
// proudove pretizeni |
output_low (BATT_ON); // odpoj baterii |
err = 1; // signalizuj chybu |
} |
dec_cap = I_zero - IB_val; // zbav se ofsetu OZ |
if (B_cap > dec_cap) |
B_cap = B_cap - dec_cap; // uprav zbyvajici kapacitu baterie |
if (! err) |
VB_val = measure_VB (); // napeti baterie je mozne merit jen pokud neni odpojena |
#ifdef DEBUG |
if (IB_val > max) |
max = IB_val; |
if (IB_val < min) |
min = IB_val; |
cnt++; |
#endif |
} |
if (l_tick) { |
l_tick = 0; |
if (! is_load ()) { |
return; // koncime, zatez odpojena |
} |
if (VB_val < VB_MIN) { |
// baterie zcela vybita |
B_cap = 0; // nastav prazdnou kapacitu |
invalid_cap = 0; // aktualni kapacita baterie je nyni znama |
return; |
} |
if (err) { |
leds_err (); // signalizuj chybu |
} |
else { |
if (VB_val < VB_LOW) { |
leds_VB_low (); // signalizuj temer vybitou baterii |
} |
else { |
leds_dis (); // signalizuj zbyvajici kapacitu bateie |
} |
} |
#ifdef DEBUG |
printf ("cnt:%lu z:%lu max:%ld delta:%u dec:%lu\n\r",cnt,I_zero,max,(int8)(max-min),dec_cap); |
max = 0; |
min = 1024; |
cnt = 0; |
#endif |
} |
} |
} |
// proces nabijeni baterie |
// |
void do_charge () { |
int1 chrg; |
int1 err; |
int16 I_zero; |
int16 IB_val; |
int16 inc_cap; |
int32 fast_chrg; |
int8 pwm; |
int16 duty; |
#ifdef DEBUG |
int16 max,min; |
int16 vs_val; |
#endif |
// vypocti mez do ktere budeme nabijet vyssim proudem |
// fast_chrg = (B_cap_4_4 - B_cap) / 64; |
fast_chrg = (B_cap_4_4 - B_cap) / 72; |
fast_chrg *= chrg_eff; |
fast_chrg += B_cap; |
#ifdef DEBUG |
// printf ("%lu %u %lu %lu\n\r\n\r",B_cap_4_4, chrg_eff,B_cap, fast_chrg); |
#endif |
err = 0; |
s_tick = 0; |
l_tick = 0; |
pwm = 0; |
chrg = 0; |
// nastaveni AD prevodniku, reference je VDD = 5V , zadny posun napeti pri mereni proudu => cim vyssi proud, tim vyssi cislo z prevodniku |
setup_adc_ports (sAN0 | sAN1 | sAN2 | sAN3 | sAN5 | VSS_VDD); |
setup_vref (VREF_LOW | VREF_A2 | 2); // na A2 vystup reference 0.416V |
delay_ms (1); |
I_zero = measure_offset (); // precti klidovou hodnotu, tedy ofset OZ - nulovy nabijeci proud |
if (invalid_cap == 0 && |
TB_val < TB_MAX && |
TB_VAL > TB_MIN) { |
// kapacita baterie je znama a teplota baterie je v mezich |
output_high (BATT_ON); // pripoj baterii |
output_high (CHRG_ON); // pripoj zdroj nabijeni |
delay_ms (500); // cekej na ustaleni menice |
chrg = 1; |
} |
if (measure_VS () < VS_MIN) { // kontrola napeti zatizeneho menice |
// napajeci zdroj je prilis mekky |
err = 1; // signalizuj chybu |
chrg = 0; // ukonci nabijeni |
output_low (CHRG_ON); // odpoj zdroj nabijeni |
output_low (BATT_ON); // odpoj baterii |
delay_ms (300); // cekej na ustaleni menice |
} |
// jeden pruchod smyckou zabere max 3000 taktu |
for (;;) { |
restart_wdt (); |
if (s_tick) { |
s_tick = 0; |
IB_val = measure_IB (); // mer proud dodavany do baterie 1760 taktu |
if (IB_val > I_zero) // zbav se ofsetu OZ |
IB_val -= I_zero; |
else |
IB_val = 0; |
// nasledujici sekvence zabere max 300 taktu |
if (chrg) { |
if (IB_val == 0) { // tece vubec nejaky nabijeci proud ? |
// NE netece |
err = 1; // signalizuj chybu |
chrg = 0; // ukonci nabijeni |
output_low (CHRG_ON); |
output_low (BATT_ON); |
} |
else { |
// ANO tece |
inc_cap = IB_val * chrg_eff; // uprav koeficientem ucinnosti nabijeni |
inc_cap = inc_cap >> (6-1); // zbav se vynasobeni 64x a vynasob dvema, protoze krok proudu pri nabijeni je dvojnasobny proti vybijeni |
B_cap = B_cap + inc_cap; // uprav kapacitu baterie |
} |
} |
#ifdef DEBUG |
if (IB_val > max) |
max = IB_val; |
if (IB_val < min) |
min = IB_val; |
#endif |
} |
if (l_tick) { |
l_tick = 0; |
measure_temp (); // mer teplotu baterie - 1100 taktu |
if (measure_VS () < VS_MIN) |
return; // koncime, napajeci zdroj byl odpojen |
if (is_load ()) |
return; // koncime, je pripojena zatez |
if (invalid_cap) |
leds_invalid_cap (); // signalizace nezname aktualni kapacity baterie - nutno nejdive baterii vybit |
else |
if (err) |
leds_err (); // signalizace chyby |
else { |
// signalizace nabiti baterie |
if ( leds_chrg () == 4 || TB_val > TB_MAX) { |
// baterie je plne nabita |
output_low (CHRG_ON); |
output_low (BATT_ON); |
chrg = 0; |
B_cap = B_cap_4_4; |
} |
else { |
if (B_cap > fast_chrg) |
duty = chrg_01C; // temer nabito dale nabijime 0.1C |
else |
duty = chrg_02C; // nabijeni proudem max. 0.2C |
if (pwm == 0) { |
output_high (CHRG_ON); |
chrg = 1; |
} |
else { |
if (pwm >= duty / IB_val) { // 400 taktu |
output_low (CHRG_ON); |
chrg = 0; |
} |
} |
pwm++; |
} |
} |
#ifdef DEBUG |
restart_wdt (); |
// printf ("z:%lu h:%ld add:%lu cap:%lu T:%u\n\r",I_zero,max,inc_cap,B_cap,TB_val); |
// printf ("pwm:%u z:%lu max:%lu d:%lu\n\r",pwm,I_zero,max,max-min); |
// printf ("%lu %lu\n\r",B_cap, fast_chrg); |
printf ("z:%lu max:%lu delta:%u inc:%lu\n\r",I_zero,max,(int8)(max-min),inc_cap); |
max = 0; |
min = 1024; |
#endif |
} |
} |
} |
// upravi kapacitu baterie dle samovybijeni |
// zabere max. 2000 cyklu |
// |
void selfdischarge (int8 day_cnt) { |
int8 k2; |
int16 temp; |
int32 dec_cap; |
// realizuje upravu koeficientu samovybijeni podle teploty k2 = k * Z * delta_TB |
// zmena Z je 1.05 na stupen |
if (TB_avr24 > TB_ref) |
temp = (3 * (TB_avr24 - TB_ref)) + 64; |
else { |
temp = 3 * (TB_ref - TB_avr24); |
if (temp > 64) |
temp = 0; |
else |
temp = 64 - temp; |
} |
temp = (temp * k) / 64; |
k2 = (int8)temp; |
// v prvnich 5 dnech je samovybijeni strmejsi |
if (day_cnt < 5) |
k2 = k2 * 2; |
dec_cap = k2 * CAP_BATT; |
if (B_cap > dec_cap) |
B_cap -=dec_cap; |
#ifdef DEBUG |
// printf ("k:%u k2:%u dec_cap:%lu cap:%lu ",k,k2,dec_cap,B_cap); |
#endif |
} |
////////////////////////////////////////////////////// |
// |
// PRIPRAVNE A NASTAVOVACI FUNKCE |
// |
////////////////////////////////////////////////////// |
// pripravi promenne pro beh programu |
// |
void prepare_var () { |
int16 B_cap; |
int8 tmp8; |
int16 tmp16; |
int32 tmp32; |
float tmpf; |
// priprav meze pro signalizaci stavu vybiti baterie |
B_cap = read_eeprom (B_CAP_L_ADDR); |
B_cap *= 100; |
tmp16 = read_eeprom (B_CAP_H_ADDR); |
tmp16 *= 1000; |
B_cap += tmp16; // kapacita baterie v mAh |
B_cap_4_4 = B_cap * CAP_BATT; |
// B_cap_4_4 = 100 * CAP_BATT; |
B_cap_2_4 = B_cap_4_4 / 2; |
B_cap_1_4 = B_cap_2_4 / 2; |
B_cap_3_4 = B_cap_2_4 + B_cap_1_4; |
// priprav omezeni nabijecich proudu |
tmpf = B_cap / 10; |
tmpf *= 256; |
tmpf /= 4.88; |
chrg_01C = (int16)tmpf; |
chrg_02C = chrg_01C * 2; |
// priprav koeficient ucinnosti nabijeni |
// eff = 1+(( read_eeprom (EFF_ADDR) * 5) / 100.0); // koeficient s jednickou |
// eff -= 0.1; |
// eff = 64 / eff; // ucinnost nabijeni (0-1) nasovena 64 |
// chrg_eff = (int8)(eff); // ucinnost nabijeni vhodna pro celociselnou aritmetiku |
chrg_eff = CHRG_EFF_TAB [read_eeprom (EFF_ADDR)]; // toto je vyhodnejsi varianta |
// priprav koeficient samovybijeni |
tmp8 = read_eeprom (LOSS_CAP_H_ADDR) * 10 + read_eeprom (LOSS_CAP_L_ADDR); // ztracena kapacita v procentech |
tmp32 = B_cap; |
tmp32 *= tmp8; |
tmp16 = tmp32 / 100; // ztracena kapacita v mAh |
tmp8 = read_eeprom (LOSS_DAY_H_ADDR) * 10 + read_eeprom (LOSS_DAY_L_ADDR); // pocet dni, za kterou se kapacita ztratila |
k = tmp16 / tmp8; // strmost poklesu samovybijeni v mAh / den |
TB_ref = read_eeprom (TB_REF_ADDR); // teplota, pri ktere k samovybijeni dochazelo |
#ifdef DEBUG |
// printf ("chrg_eff:%lu ",B_cap); |
// printf ("chrg_eff:%u ",chrg_eff); |
// printf ("k:%u ",k); |
#endif |
} |
// pripravi konstantu pro odmereni 1 hod pomoci wdt |
// |
prepare_hour_time () { |
int32 hour_time_cor; |
// vypocti potrebny pocet tiku wdt pro odmereni jedne hodiny |
hour_time_cor = 400 - hour_time; |
hour_time_cor *= HOUR_TIME_WDT; |
hour_time_cor /= hour_time; |
hour_time = HOUR_TIME_WDT + (int16)hour_time_cor; |
} |
// priprav vse pro minimalizaci spotreby ve spanku |
// |
void prepare_sleep () { |
leds_all_off (); |
output_low (BATT_ON); |
output_low (CHRG_ON); |
setup_vref (FALSE); |
} |
// nastavi parametry programu |
// |
void do_set_par () { |
int8 par_num; // cislo parametru |
int8 par_val; // hodnota parametru |
int8 key_timer; // pro osetreni zakmitu nastavovacich tlacitek |
int8 keys; // stav nastavovacich tlacitek |
int1 set_par; // jsme v rezimu nastavovani hodnoty parametru |
int1 wait_release; // cekame na uvolneni tlacitka |
leds_all_on (); // oznam, ze jsme v nastavovacim rezimu |
delay_ms (1000); |
par_num = 0; |
s_tick = 0; |
l_tick = 0; |
key_timer = 0; |
wait_release = 0; |
set_par = 0; |
num_to_leds (par_num); // zobraz zvoleny parametr |
for (;;) { |
restart_wdt (); |
if (s_tick) { |
s_tick = 0; |
if (key_timer != 0) |
key_timer--; |
else { |
key_timer = 5; |
keys = read_keys (); // precti stav tlacitek |
if (keys & SET_MASK) { |
// tlacitko SET je stisknuto - rezim vyberu parametru |
if (set_par) { |
if (par_val != read_eeprom (par_num)) { // prechazime z rezimu nastaveni parametru, uloz zvoleny parametr |
write_eeprom (par_num, par_val); // uloz jen pokud byl zmenen |
if (par_num == LOSS_DAY_H_ADDR || |
par_num == LOSS_DAY_L_ADDR) |
write_eeprom (TB_REF_ADDR,TB_avr24); // pokud byla zmenena hodnota ztracene kapacity samovybijenim, uloz TB_avr24 jako refrerencni |
} |
num_to_leds (par_num); // zobraz zpatky zvoleny parametr |
set_par = 0; |
} |
else { |
// vybirame parametr |
if (keys & UP_MASK) { |
if (! wait_release) { |
if (par_num < 6) |
par_num++; |
else |
par_num = 0; |
num_to_leds (par_num); // zobrazeni vybraneho parametru |
wait_release = 1; // cekame na uvolneni tlacitka UP |
} |
} |
else |
wait_release = 0; // tlacitko UP bylo uvolneno |
} |
} |
else { |
// tlacitko SET je uvolneno - rezim nastaveni parametru |
if (! set_par) { |
par_val = read_eeprom (par_num); // prechazime z rezimu vyberu parametru, vyzvedni zvoleny parametr |
num_to_leds (par_val); // zobraz hodotu parametru |
set_par = 1; |
} |
else { |
// nastavujeme parametr |
if (keys & UP_MASK) { |
if (! wait_release) { |
if (par_val < PAR_MAX_TAB [par_num]) |
par_val++; |
else |
par_val = 0; |
num_to_leds (par_val); // zobraz hodnotu parametru |
wait_release = 1; // cekame na uvolneni tlacitka UP |
} |
} |
else |
wait_release = 0; |
} |
} |
} |
} |
if (l_tick) { |
l_tick = 0; |
if (measure_VS () < VS_MIN) |
break; // koncime, napajeci zdroj odpojen |
} |
} |
prepare_var (); // konec nastavovani, aktualizuj promenne programu |
} |
/////////////////////////////////////////////////// |
// HLAVNI FUNKCE |
/////////////////////////////////////////////////// |
main () { |
int1 load_old; |
int1 load; |
int1 no_load; |
int1 start_TB; // spust mrereni teploty baterie |
int16 wdt_timer; // pro odmereni hodiny pomoci wdt |
int8 hour_timer; // pro odmerovani hodin |
int8 day_timer; // pro odmerovani dni od nabiti |
int16 TB_avr_tmp; // pro vypocet prumerne teploty |
#ifdef DEBUG |
int16 c; |
int16 inc_cap,IB_val,I_zero; |
int8 val; |
#endif |
init_ports (); |
if (restart_cause () != WDT_TIMEOUT) { |
// mereni skutecne doby behu wdt proved pro vseshny resety krome wdt |
setup_oscillator (OSC_4MHZ | OSC_NORMAL); |
delay_ms (100); |
setup_timer_1 (T1_INTERNAL | T1_DIV_BY_1); |
setup_wdt (WDT_288MS); |
hour_time = 0; |
set_timer1 (~1000); |
restart_wdt (); |
for (;;) { |
if (TMR1IF) { |
hour_time++; |
TMR1IF = 0; |
set_timer1 (~1000); |
} |
} |
} |
setup_oscillator (OSC_4MHZ | OSC_NORMAL); |
setup_timer_0 (RTCC_INTERNAL| RTCC_DIV_1); |
setup_wdt (WDT_288MS); |
setup_timer_1 (T1_INTERNAL | T1_DIV_BY_1); |
set_timer1 (S_TICK_TIME); |
setup_spi (FALSE); |
setup_comparator (NC_NC_NC_NC); |
setup_vref (FALSE); |
setup_ccp1 (CCP_OFF); |
setup_adc (ADC_CLOCK_INTERNAL); // doba prevodu cca 48 uS |
setup_adc_ports (sAN0 | sAN1 | sAN2 | sAN3 | sAN5 | VSS_VDD); |
enable_interrupts (INT_TIMER1); |
enable_interrupts (GLOBAL); |
prepare_var (); // priprav promenne pro beh programu z udaju o vlastnostech baterie |
prepare_hour_time (); |
////////////////////////////////////////////////// |
// uvodni bliknuti ledkou |
output_high (LED1_G); |
delay_ms (250); |
output_low (LED1_G); |
/* |
#ifdef DEBUG |
output_high (BATT_ON); |
printf ("Ahoj %lu\n\r",hour_time); |
for (;;) { |
restart_wdt (); |
if (is_load ()) |
break; // napajeci zdroj byl pripojen |
delay_ms (100); |
} |
B_cap = B_cap_2_4; |
invalid_cap = 0; |
set_timer1 (0); |
// zde se meri doba trvani funkci nebo vybraneho kodu |
// selfdischarge (0); //OK |
do_discharge (); |
c = get_timer1 (); |
// printf ("T:%lu %lu %u \n\r",c,B_cap,chrg_eff); |
printf ("T:%lu\n\r",c); |
output_low (BATT_ON); |
delay_ms (250); |
for (;;) |
restart_wdt (); |
#endif |
*/ |
#ifdef DEBUG |
invalid_cap = 0; |
// B_cap = B_cap_3_4; |
B_cap = B_cap_2_4; |
#else |
invalid_cap = 1; // nezname zbyvajici kapacitu baterie |
B_cap = 0; // povazujeme ji za vybitou |
#endif |
TB_avr24 = TB_DEFAULT; |
TB_avr_tmp = 0; |
wdt_timer = 0; |
hour_timer = 0; |
day_timer = 0; |
start_TB = 1; |
no_load = 0; |
// hlavni programova smycka |
for (;;) { |
restart_wdt (); |
prepare_sleep (); |
sleep (); |
setup_adc_ports (sAN0 | sAN1 | sAN2 | sAN3 | sAN5 | VSS_VDD); |
load = is_load (); // precti stav kontaktu pripojeni zateze |
if (load != load_old) |
load_old = load; // stav kontaktu neni platny |
else { |
if (load) { |
if (! no_load) { |
do_discharge (); // zatez pripojena, vybijime - ma vyssi prioritu |
no_load = 1; // dalsi vybijeni je mozne az po odpojeni zateze |
wdt_timer = 0; |
} |
} |
else { |
no_load = 0; // zatez byl odpojena |
if (measure_VS () > VS_MIN) { // ma zdroj pro nabijeni dostatecne napeti? |
if (input (SET)) |
do_charge (); // zatez odpojena a pripojen zdroj pro nabijeni, nabijime - ma nizsi pioritu |
else |
do_set_par (); // prechazime do rezimu pro nastavovani parametru programu |
TB_avr_tmp = 0; |
wdt_timer = 0; |
hour_timer = 0; |
day_timer = 0; |
} |
} |
} |
// reseni samovybijeni |
if (wdt_timer < hour_time) |
wdt_timer++; |
else { |
// uplynula hodina |
start_TB = 1; // odstartuj mereni teploty |
wdt_timer = 0; // natahni odmerovani hodiny |
if (hour_timer < 23) |
hour_timer++; |
else { |
// uplynul den |
TB_avr24 = TB_avr_tmp / 24; // vypocti prumernou teplotu za den |
if (day_timer < 90) |
day_timer++; |
else |
invalid_cap = 1; // po 90 dnech uz neverime kapacite baterie |
selfdischarge (day_timer); // uprav kapacitu baterie s ohledem na samovybijeni |
#ifdef DEBUG |
// printf ("TB:%u\n\r",TB_avr24); |
#endif |
TB_avr_tmp = 0; |
hour_timer = 0; |
} |
} |
// realizace mereni teploty - je v mnoha krocich |
if (start_TB) { |
if (measure_temp () == 0) { |
#ifdef DEBUG |
// printf("T:%u ",TB_val); |
#endif |
TB_avr_tmp += TB_val; // pocitame prumer teploty |
start_TB = 0; |
} |
} |
} |
} |
/Designs/HAM_Constructions/IBP20/SW/V_1_1/ibp2.h |
---|
0,0 → 1,166 |
//********************************************************************** |
// INFO BATTERY PACK |
//********************************************************************** |
// (c) OK1XGL 2008 |
#include <16F88.h> |
#device *=16 |
#device adc=10 |
#fuses WDT,INTRC_IO, NOPUT, NOMCLR, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG, NOPROTECT, NOFCMEN, NOIESO, CCPB3 |
#use delay(clock=4000000,RESTART_WDT) |
#use FAST_IO (A) |
#use FAST_IO (B) |
// definice pinu |
// vystupy LED diody |
#define LED1_G PIN_A6 |
#define LED2_Y PIN_A7 |
#define LED3_Y PIN_A4 |
#define LED4_R PIN_B0 |
// analogove vstupy |
#define I_SENSE PIN_A0 |
#define IB_CAN 0 |
#define V_SENSE PIN_A1 |
#define VB_CAN 1 |
#define TM_PIN PIN_B7 |
#define TB_CAN 6 |
#define REF_25V PIN_A3 |
// vstupy rizeni funkcnosti |
#define SOURCE_ON PIN_B6 // analogovy vstup |
#define VS_CAN 5 |
#define LOAD_ON PIN_B4 |
// vystupy rizeni funkcnosti |
#define CHRG_ON PIN_B1 |
#define BATT_ON PIN_B3 |
// nastavovaci signaly |
#define SET PIN_A5 |
#define UP PIN_B7 |
#define UP_MASK 0x01 // maska pro stisknute tlacitko UP |
#define SET_MASK 0x02 // maska pro stisknute tlacitko SET |
// debug seriovka |
#ifdef DEBUG |
#use rs232 (baud = 9600, xmit = PIN_B5, DISABLE_INTS) |
#endif |
#define VS_MIN_mV 8000 // minimalni vstupni napeti napajeciho zdroje pro nabijeni |
#define VB_MIN_mV 10000 // minimalni napeti baterie - dojde k odpojeni |
#define VB_LOW_mV 11000 // nizke napeti baterie - upozorneni pred odpojenim |
#define TB_MAX 45 // max teplota baterie pri nabijeni |
#define TB_MIN 5 // min teplota baterie pri nabijeni |
#define TB_DEFAULT 25 // teplota baterie, kdyz teplomer neni pouzit |
#define VREF_DIS_mV 2500 |
#define VREF_CHRG_mV 5000 |
#define VS_STEP_mV ((VREF_CHRG_mV / 1024.0) * ((8.2 + 1) / 1)) // rozliseni mereni vstupniho napeti mV () |
#define VB_STEP_mV ((VREF_DIS_mV / 1024.0) * ((68 + 10) / 10.0)) // rozliseni mereni napeti baterie v mV (19 mV -> 1.9 mv na clanek) |
//#define VS_MIN (int16)(VS_MIN_mV / VS_STEP_mV) |
#define VS_MIN (int16)44 |
#define VB_MIN (int16)(VB_MIN_mV / VB_STEP_mV) |
#define VB_LOW (int16)(VB_LOW_mV / VB_STEP_mV) |
#define I_STEP_mA ((VREF_DIS_mV / 1024.0) * 10 * 0.1) // rozliseni mereni proudu v mV (2.44 mA) |
#define TICK_mS 4 // tik kratkeho casovace v ms |
#define S_TICK_TIME ~4000 // hodnota pro natazeni kratkeho casovace |
#define L_TICK_TIME 300 / TICK_mS // |
#define HOUR_TIME_WDT 9000 // cas v ms / 400 ms nastav na 1 hod |
#define CAP_BATT ((60.0 * 60.0 * 1000.0) / (TICK_ms * I_STEP_mA)) // pro prevod kapacity baterie na vnitrni reprezentaci |
// adresy parametru programu v eeprom |
#define B_CAP_H_ADDR 0 |
#define B_CAP_L_ADDR 1 |
#define EFF_ADDR 2 |
#define LOSS_CAP_H_ADDR 3 |
#define LOSS_CAP_L_ADDR 4 |
#define LOSS_DAY_H_ADDR 5 |
#define LOSS_DAY_L_ADDR 6 |
#define TB_REF_ADDR 7 |
// maximalni hodnoty parametru programu |
const int8 PAR_MAX_TAB [8] = {5, |
9, |
9, |
9, |
9, |
6, |
9}; |
// tabulka pro ziskani koeficientu ucinnosti |
// hodnoty se ziskaji ze vztahu: 64 / koeficient ucinnosti (pr: 64 / 1.2 = 53) |
const int8 CHRG_EFF_TAB [10] = {71, // ucinnost 0.9 |
67, // 0.95 |
64, // 1.0 |
61, // 1.05 |
58, // 1.10 |
55, // 1.15 |
53, // 1.20 |
51, // 1.25 |
49, // 1.30 |
47}; // 1.35 |
// globalni promenne |
int8 TB_val; // teplota baterie |
int8 TB_ref; // teplota baterie, pri ktere se merilo samovybijeni |
int8 TB_avr24; // prumerna teplota baterie za 24 hod |
int8 l_timer; // pro dlouhy periodicky casovac |
int1 s_tick; // kratky tik periodickeho casovace |
int1 l_tick; // dlouhy tik periodickeho casovace |
int1 blink; // zrcadlo pro rychle blikani ledkami |
int1 slow_blink; // zrcadlo pro pomale blikani ledkami |
int1 invalid_cap; // neplatny zaznam o aktualni kapacite baterie |
int32 B_cap; // aktualini kapacita baterie |
int16 hour_time; // cas pro odmereni 1 hod pomoci wdt |
// promenne vypocitane z parametru programu |
int32 B_cap_4_4; // mez pro plnou kapacitu baterie |
int32 B_cap_3_4; // mez pro 3/4 kapacitu baterie |
int32 B_cap_2_4; // mez pro 2/3 kapacitu baterie |
int32 B_cap_1_4; // mez pro 1/4 kapacitu baterie |
int16 chrg_01C; // regulace proudu na 0.1C |
int16 chrg_02C; // regulace proudu na 0.2C |
int8 chrg_eff; // ucinnost nabijeni |
int8 k; // strmost samovybijeni |
// definice potrebnych registru CPU |
#bit ADIE = 0x8c.6 // povoleni interruptu od AD |
#bit PEIE = 0x0b.6 // povoleni interruptu od periferii |
#bit ADIF = 0x0c.6 |
#bit TMR1IF = 0x0c.0 // preteceni casovace 1 |
// Makro pro nastaveni pinu jao vystup (reverzni funke k output_float () ) |
#define output_fixed(pin) { #asm BCF ((pin) / 8 + 0x80).((pin) % 8) #endasm } |
// defaultni parametry programu ulozene v eeprom |
#rom 0x2100={3, // kpacita baterie tisice |
5, // kapacita baterie stovky |
0, // ucinnost nabijeni ve tvaru 1.xx s krokem 05 |
3, // ztracena kapacita samovybijenim desitky procent |
0, // ztracena kapacita samovybijenim jednotky procent |
3, // za dobu desitky dni |
0, // za dobu jednotky dni |
25} // referencni teplota pri ktere probihalo samovybijeni |
/Designs/HAM_Constructions/IBP20/SW/V_1_1/ibp2.hex |
---|
0,0 → 1,454 |
:1000000008308A00CF2C0000FF00030E8301A100FE |
:100010007F08A0000A08A8008A01A00E0408A20018 |
:100020007708A3007808A4007908A5007A08A6003C |
:100030007B08A700831383128C308400001C2228C5 |
:100040000C183528220884002308F7002408F8003B |
:100050002508F9002608FA002708FB0028088A006E |
:10006000210E8300FF0E7F0E09008A1151280A100D |
:100070008A100A1182070534093409340934093415 |
:100080000634093400340A108A100A1182074734F2 |
:10009000433440343D343A343734353433343134F6 |
:1000A0002F34F0308F005F308E002D14AC08031D0C |
:1000B00063284B30AC00AD140430AD062D1D622812 |
:1000C0000830AD066428AC030C108A1122282B30AE |
:1000D00065008501D03066002030860083168117C8 |
:1000E000831200347C3084008313000803198928AC |
:1000F0000130F800BF30F7006400F70B7C28F80BE4 |
:100100007A284A30F700F70B832800006400800B40 |
:10011000782800341030FE00F701FA01FD0CFC0CC9 |
:10012000031C9A2883162008F7070318FA0A2108E7 |
:10013000FA078312FA0CF70CF90CF80CFE0B8E2858 |
:1001400000348E30F7007D08F8007C08F900FA01D1 |
:10015000F808031DB5287908F800F9010830F702FE |
:10016000F808031DB528F701BD280310F81BBC28AB |
:10017000F90DF80DF703B528F813000000348316C5 |
:10018000200803193029A800240803193029A807DA |
:100190000318D1287F30A802031C30290319302905 |
:1001A000D5288130A807031830292808F700F8015E |
:1001B000F901FA012108AC00AC172208AB002308B2 |
:1001C000AA001830A800A9012A1CFE282708FA074F |
:1001D000031CF028F90A031DF028F80A0319A917CF |
:1001E0002608F907031CF728F80A0319A917250898 |
:1001F000A200A2172208F8070318A917A90DF80CE6 |
:10020000F90CFA0CAC0CAB0CAA0C0310A80BE328ED |
:100210000130F70703183029F81B1529AC0DFA0D2A |
:10022000F90DF80DF70303193029AC1F2629FA0A36 |
:10023000031D2629F90A031D2629F80A031D26296C |
:10024000F80CF90CFA0CF70A031930292108A90057 |
:100250002508A906A91F2E29F8173429F8133429CF |
:10026000F701F801F901FA01000083120034831646 |
:100270002008B63CA000FA012108FC00A1170310D9 |
:10028000A10CA20CA30CFA0CF90CF80CF70CA00BA7 |
:100290003F29FC1F5629F709F809F909FA09F70A55 |
:1002A0000319F80A0319F90A0319FA0A8312003428 |
:1002B000F801F901F701FA0183162108031D6329EA |
:1002C000200803197D291030FE000310FC0DFD0DE0 |
:1002D000F70DFA0D21087A02031D70292008770214 |
:1002E000031C79292008F702031CFA032108FA02EB |
:1002F0000314F80DF90DFE0B65290000831200347C |
:10030000831620080319462AAC0024080319462A3C |
:10031000AC02031C90297F30AC070318462A9629AB |
:100320008130AC02031C462A0319462A2C08F70028 |
:10033000F801F901FA01AB012108AA00AA17220865 |
:10034000A9002308A8001930AC002708A802031848 |
:10035000B9290130A9020318B929AA020318B92939 |
:10036000AB020318B929AB0AAA0AA90A2708A807E9 |
:10037000EB292608A9020318D4290130AA02031880 |
:10038000D429AB020318D429AB0AAA0A2608A90764 |
:100390002708A807031CEB29A90A031DEB29AA0AB1 |
:1003A000031DEB29AB0AEB2925088038AA020318A4 |
:1003B000EA290130AB020318EA29AB0A2508803884 |
:1003C000AA072608A907031CC829AA0A031DC829C9 |
:1003D000AB0AC8297A14AC0BEE29F9290310A80D31 |
:1003E000A90DAA0DAB0D0310FA0DF90DF80DAD0D09 |
:1003F000A5292D1C012A0310F80CF90CFA0CAD0CE0 |
:10040000042AF7030319462AAD1B2D2A0310A80D51 |
:10041000A90DAA0DAB0D2708A8020318192A01304F |
:10042000A9020318192AAA020318192AAB02031CED |
:100430003C2A2608A9020318242A0130AA0203181C |
:10044000242AAB02031C3C2A25088038AA02031880 |
:100450002D2A0130AB02031C3C2AFA0A031D3C2A58 |
:10046000F90A031D3C2AF80A031D3C2AF70A03195E |
:10047000462AF80CF90CFA0C2108AC002508AC0649 |
:10048000AC1F442AF8174A2AF8134A2AF701F80140 |
:10049000F901FA01000083128A11D52B8E30F70082 |
:1004A00083162008F7022108F9002208F800F9173E |
:1004B000F7080319662A0310F908031D622AF808D1 |
:1004C0000319662AF90CF80CF70B5B2AA11F6D2A99 |
:1004D000F809F909F80A0319F90A000083128A11C8 |
:1004E000E82BF701F8017E08031083162018F707A0 |
:1004F000F70CF80CA018F707F70CF80C2019F70701 |
:10050000F70CF80CA019F707F70CF80C201AF707EE |
:10051000F70CF80CA01AF707F70CF80C201BF707DC |
:10052000F70CF80CA01BF707F70CF80C831200343B |
:1005300020308316AC00A801A901AA01AB01230851 |
:10054000FA002208F9002108F8002008F70003103B |
:10055000771CB82A2408A80725080318250FA9071F |
:1005600026080318260FAA0727080318270FAB072A |
:10057000AB0CAA0CA90CA80CFA0CF90CF80CF70C93 |
:10058000AC0BA72A83120034F701F801F901FA0134 |
:100590008316A801A901AA01AB0127082604250496 |
:1005A00024040319032B2030AC000310A00DA10D6F |
:1005B000A20DA30DA80DA90DAA0DAB0D27082B02A6 |
:1005C000031DEC2A26082A02031DEC2A250829020D |
:1005D000031DEC2A24082802031CFD2A2408A80273 |
:1005E0002508031C250FA9022608031C260FAA02B2 |
:1005F0002708031C270FAB020314F70DF80DF90DA4 |
:10060000FA0DAC0BD52A0000A830840083138312A6 |
:100610000034013003178D0083168C130C148312E1 |
:100620000C080313EB01EA006B08FD006A08FC00EC |
:100630008316A1016430A00083128A207908EB00A0 |
:100640007808EA0003178D0183168C130C148312AB |
:100650000C080313EE01ED006E08FD006D08FC00B0 |
:1006600003308316A100E830A00083128A207908A5 |
:10067000EE007808ED006D08EA076E0803186E0FAB |
:10068000EB076B08FD006A08FC00A1207A088316BE |
:10069000A3007908A2007808A1007708A000A701AC |
:1006A000A6013430A5009130A4008312BF207A083F |
:1006B0008316A3007908A2007808A1007708A0009B |
:1006C000831237217A08B7007908B6007808B50098 |
:1006D0007708B4000310370CBF00360CBE00350C91 |
:1006E000BD00340CBC0003103F0CC3003E0CC20024 |
:1006F0003D0CC1003C0CC00040083C07B8003D0860 |
:10070000B90041080318410FB9073E08BA00420872 |
:100710000318420FBA073F08BB0043080318430FF2 |
:10072000BB076B08FD006A08FC008316A1010A30B4 |
:10073000A000831258217908FA007808FC00790893 |
:10074000FD00A1207A08F6007908F5007808F40089 |
:100750007708F30076088316A3007508A2007408D2 |
:10076000A1007308A000A701A601A5018730A4007D |
:100770008312BF207A08F6007908F5007808F400A3 |
:100780007708F30076088316A3007508A2007408A2 |
:10079000A1007308A000F630A7002830A6001C3086 |
:1007A000A5008130A400831280297A08F600790818 |
:1007B000F5007808F4007708F30076088316A300A4 |
:1007C0007508A2007408A1007308A00083124E2AC5 |
:1007D0007908C5007808C4000310440DC600450D13 |
:1007E000C700023003178D0083168C130C1483127C |
:1007F0000C0803134320F800C800033003178D00D2 |
:1008000083168C130C1483120C08FD00FE000A30B2 |
:1008100083160313A00083127122043003178D0086 |
:1008200083168C130C1483120C0878070313EC0046 |
:10083000F201F1016B08F0006A08EF0072088316FC |
:10084000A3007108A2007008A10083126F0883162C |
:10085000A000A701A601A50183126C088316A400BD |
:10086000831298227A08F2007908F1007808F000E3 |
:100870007708EF0072088316A3007108A2007008C1 |
:10088000A10083126F088316A000A701A601A5018D |
:100890006430A4008312C4227808EE007708ED00CB |
:1008A000053003178D0083168C130C1483120C086B |
:1008B000FD00FE000A3083160313A000831271228C |
:1008C000063003178D0083168C130C1483120C084A |
:1008D00078070313EC006E08FD006D08FC0083161A |
:1008E000A10183126C088316A00083125821780896 |
:1008F000C900073003178D0083168C130C14831264 |
:100900000C080313AA0000343208903CE5000130C3 |
:10091000E6003308031C330FE602E701E80168082C |
:100920008316A300831267088316A2008312660849 |
:100930008316A100831265088316A000A701A601F3 |
:100940002330A5002830A400831298227A08E800FA |
:100950007908E7007808E6007708E500680883165C |
:10096000A300831267088316A20083126608831609 |
:10097000A100831265088316A000A701A6018312B7 |
:1009800033088316A500831232088316A40083124D |
:10099000C4227A08E8007908E7007808E6007708BA |
:1009A000E50028306507B2006608B300233003185D |
:1009B0002430B3078A15832D0610051285130513FD |
:1009C0000034DC248611861083169D0183128A155B |
:1009D0009D2D8316811364002030F700F70BEE2C59 |
:1009E0000000000073108312061A73148316811717 |
:1009F000003073180130F80083120034851305129B |
:100A00002D1D052D05170614072D0513061000349E |
:100A100067200B138B138B1B0A2D83160C17831265 |
:100A20000B170230F600FA30FC007220F60B132D83 |
:100A30000030F8001F08C73978049F006400203098 |
:100A4000F700F70B212D00000000F401F301F50180 |
:100A50007508073C031C442D1F1563001F192E2D1C |
:100A60001E08FA0083161E08F3077A0803187A0F87 |
:100A7000F40764002030F700F70B3C2D0000000065 |
:100A80006400F50A8312282DF40CF30CF40CF30C1B |
:100A9000F40CF30C1F30F40583160C1383120B13A4 |
:100AA000C0308B047308F8007408F9000034310872 |
:100AB0004302031C722D031D6D2D30084202031CDE |
:100AC000722D031D6D2D2F084102031C722D031D75 |
:100AD0006D2D40082E020318722D05138513051283 |
:100AE0000614AC2D31083F02031C8D2D031D882DEB |
:100AF00030083E02031C8D2D031D882D2F083D025A |
:100B0000031C8D2D031D882D3C082E0203188D2DEE |
:100B10000513851305160610AC2D31083B02031C86 |
:100B2000A82D031DA32D30083A02031CA82D031D78 |
:100B3000A32D2F083902031CA82D031DA32D38084F |
:100B40002E020318A82D0513851705120610AC2DCB |
:100B5000051785130512061000340030F8001F0831 |
:100B6000C73978049F0064002030F700F70BB62DDA |
:100B7000000000001F151F19BB2D1E08FA00831668 |
:100B80001E08F3007A08F40064002030F700F70B29 |
:100B9000C72D0000000083121F151F19CD2D1E0840 |
:100BA000FA0083161E08F3077A0803187A0FF40771 |
:100BB00064002030F700F70BDB2D000000008312EB |
:100BC0001F151F19E12D1E08FA0083161E08F307D2 |
:100BD0007A0803187A0FF40764002030F700F70B47 |
:100BE000EF2D0000000083121F151F19F52D1E08A0 |
:100BF000FA0083161E08F3077A0803187A0FF40721 |
:100C000064002030F700F70B032E00000000831271 |
:100C10001F151F19092E1E08FA0083161E08F30758 |
:100C20007A0803187A0FF40764002030F700F70BF6 |
:100C3000172E0000000083121F151F191D2E1E08FD |
:100C4000FA0083161E08F3077A0803187A0FF407D0 |
:100C500064002030F700F70B2B2E000000008312F9 |
:100C60001F151F19312E1E08FA0083161E08F307E0 |
:100C70007A0803187A0FF40764002030F700F70BA6 |
:100C80003F2E0000000083121F151F19452E1E085D |
:100C9000FA0083161E08F3077A0803187A0FF40780 |
:100CA000F40CF30CF40CF30CF40CF30C1F30F405FF |
:100CB0007308F8007408F900831200340513061055 |
:100CC0002D1D652E85170516672E85130512003418 |
:100CD0002D1E742E2D15FE240230EE00FA30FC007D |
:100CE0007220EE0B6E2EDC2483161F129F161B083B |
:100CF00080392F389B00C8309D000130FC008312E2 |
:100D0000722008257908E8007808E700861557253D |
:100D10006D112D15AD102D1064002D1C642F2D109C |
:100D2000AD257908E6007808E500E508031D9D2E4D |
:100D3000E608031D9D2E86116D1565086702EB0000 |
:100D40006808EC006608031C660FEC02B108031D7E |
:100D5000B62EB008031DB62E6C082F02031CC42E3D |
:100D6000031DB62E2E086B020318C42E6B08AE02AC |
:100D70006C08031C6C0FAF020030031C0130B00282 |
:100D80000030031C0130B1026D19642F5C08063C71 |
:100D90000318CC2EDC01CD2EDC0A0830F8001F0829 |
:100DA000C73978049F0064002030F700F70BD62E77 |
:100DB0000000000003105C0D4C3E840083131F15DF |
:100DC0001F19E02E1E08FA0083161E088000840AF0 |
:100DD0007A08800083124E084C078316A000831205 |
:100DE0004D088316A10083124F0803184F0FF92EE8 |
:100DF000FC2E8316A1078312500883162007A20039 |
:100E00002108A300831251080318510F082F0B2F3C |
:100E10008316A3078312520883162207A40023080F |
:100E2000A500831253080318530F172F1A2F831688 |
:100E3000A5078312540883162407A6002508A700D7 |
:100E4000831255080318550F262F292F8316A7073D |
:100E50008312560883162607A8002708A9008312C4 |
:100E600057080318570F352F382F8316A9078312F9 |
:100E7000580883162807AA002908AB0083125908CE |
:100E80000318590F442F472F8316AB0783125A08B4 |
:100E900083162A078312EE0083162B088312EF00B5 |
:100EA0005B0803185B0FEF07EF0CEE0CEF0CEE0C7A |
:100EB000EF0CEE0C1F30EF056E08F8006F08F9001C |
:100EC0007908EA007808E900AD1C942FAD10E924F8 |
:100ED000F808031D6C2F952F6A08023C031C7C2F19 |
:100EE000031D762F69080C3C031C7C2FB101B00157 |
:100EF000AF01AE012D12952F6D1D802F5E26942F10 |
:100F00006A08023C031C932F031D8A2F6908403C8A |
:100F1000031C932F051385130512AD1D912F061485 |
:100F2000922F0610942F57258C2E8A15C12D28300C |
:100F3000F8001F08C73978049F0064002030F700CC |
:100F4000F70BA02F000000001F151F19A52F1E086A |
:100F5000FA0083161E08F3007A08F4007308F800FC |
:100F60007408F90083120034861383168613640014 |
:100F7000A630F700F70BBA2F83120B138B138B1BC2 |
:100F8000BE2F831686178312861BCB2FC0308B048F |
:100F90000030F800E32F64001530F700F70BCE2F78 |
:100FA0007410861B7414C0308B0464009230F700F8 |
:100FB000F70BD82F741CE02F0030F800E32FE32F3D |
:100FC0000130F800E32F00340614051685170517C5 |
:020FD0000034EB |
:10100000F5017508073C031C23280B138B138B1B5E |
:101010000628861383168613640000000000000073 |
:1010200000000310F40C0318861764001330F70057 |
:10103000F70B18280000861764000000C0308312E8 |
:101040008B04F50A01280034F4017408073C031CE2 |
:101050004A280B138B138B1B2A288613831686139F |
:1010600064000000861764000230F700F70B362892 |
:101070008312861B3D2803103E280314F50CC03054 |
:101080008B0464001130F700F70B442800000000C7 |
:10109000F40A25287508F80000344A08003A0319B4 |
:1010A0007028013A03197D28033A03198128013A6F |
:1010B00003198928073A03198928013A031989284D |
:1010C000033A03198A28013A03199B280F3A031996 |
:1010D0009F28013A0319A328033A0319A928C22813 |
:1010E0008A11B4278A15F808031D7C28CA01193013 |
:1010F000A9000030F800CB28C828CC30F40000202C |
:10110000C8284430F4000020861783168613831203 |
:10111000C828C82883168617831286138A11B42715 |
:101120008A15F808031D9A28CA011930A900003051 |
:10113000F800CB28C828CC30F4000020C828BE30E6 |
:10114000F4000020C8282420780ECB000F30CB05F7 |
:10115000C8282420780EF700F030F7057708CB0474 |
:101160004B087F39F30073084F3C031CBD28CB1F8D |
:10117000BB28A901BD287308A900CA010030F800E6 |
:10118000CB28C828CA011930A9000030F800CB28A4 |
:10119000CA0A0130F80000342E083402F300350882 |
:1011A000F4002F08031C2F0FF4023608F500300856 |
:1011B000031C300FF5023708F6003108031C310F0D |
:1011C000F60276088316A3007508A2007408A10031 |
:1011D0007308A000A701A601A5014830A4008A1148 |
:1011E0008312C4228A157A08EF007908EE00780885 |
:1011F000ED007708EC006F088316A30083126E08D9 |
:101200008316A20083126D088316A10083126C0856 |
:101210008316A000A701A601A50183124808831622 |
:10122000A4008A11831298228A157A08EF0079089F |
:10123000EE007808ED007708EC002E08EC072F0888 |
:1012400003182F0FED0730080318300FEE07310891 |
:101250000318310FEF07E5102D10AD10F0016510E8 |
:1012600083161F129F121B0880392F389B00E23013 |
:101270009D000130FC008A11831272208A158A11A8 |
:1012800008258A157908E7007808E6002D1A5C29F8 |
:1012900029082C3C031C5C292908053C03185C29FF |
:1012A000861586140230F300FA30FC008A11722091 |
:1012B0008A15F30B542965148A1197278A15790822 |
:1012C000F4007808F300F408031D772973082B3C19 |
:1012D000031C7729E5146510861086110230F3008F |
:1012E0009630FC008A1172208A15F30B7029640075 |
:1012F0002D1CCE292D108A11AD258A157908E900FB |
:101300007808E80067086902031C9329031D8C29EB |
:1013100068086602031893296608E8026708031C38 |
:10132000670FE9029529E901E801651CCE29E80863 |
:10133000031DA229E908031DA229E51465108610E2 |
:101340008611CE296908FD006808FC008316A101FA |
:10135000831248088316A0008A1183128A208A15F6 |
:101360007908EB007808EA00EB0CEA0CEB0CEA0CCD |
:10137000EB0CEA0CEB0CEA0CEB0CEA0C0730EB057F |
:101380006A08AE076B0803186B0FAF07003003182D |
:101390000130B007003003180130B107AD1CD02A6E |
:1013A000AD104D208A1197278A157908F400780826 |
:1013B000F300F408031DE02973082B3C0318D12A1D |
:1013C0008A11E9248A15F808031DD12A2D1EEC295B |
:1013D0008A11FE248A15D02AE51CF2298A115E267C |
:1013E0008A15D02A37083102031C0E2A031D082A49 |
:1013F00036083002031C0E2A031D082A35082F0266 |
:10140000031C0E2A031D082A34082E02031C0E2A70 |
:101410008A11E4278A150430F8007B2A3B08310240 |
:10142000031C2F2A031D242A3A083002031C2F2AEA |
:10143000031D242A39082F02031C2F2A031D242AE6 |
:101440002E08380203182F2A061405168517AD1D1D |
:101450002B2A05172C2A05130330F8007B2A3F0896 |
:101460003102031C502A031D452A3E083002031C8A |
:10147000502A031D452A3D082F02031C502A031D34 |
:10148000452A2E083C020318502A06140516AD1DE5 |
:101490004B2A85174C2A851305130230F8007B2A46 |
:1014A00043083102031C712A031D662A42083002D8 |
:1014B000031C712A031D662A41082F02031C712A8E |
:1014C000031D662A2E0840020318712A0614AD1D5A |
:1014D0006B2A05166C2A0512851305130130F800D6 |
:1014E0007B2AAD1D752A0614762A0610051285136F |
:1014F00005130030F8007808043C0319832A2908F2 |
:101500002D3C03188F2A8610861165103708B1000C |
:101510003608B0003508AF003408AE00D02A6F0896 |
:101520003102031CAA2A031DA52A6E083002031CDF |
:10153000AA2A031DA52A6D082F02031CAA2A031D2F |
:10154000A52A2E086C020318AA2A4508F2004408AE |
:10155000F100AE2A4708F2004608F100F008031D2A |
:10156000B42A86146514CF2A7208FD007108FC00A5 |
:1015700069088316A100831268088316A0008A11E7 |
:10158000831258218A157908FA007808FA08031D91 |
:10159000CF2A78087002031CCF2A86106510F00A43 |
:1015A00077298A15D82D6A08003A0319F32A013AD7 |
:1015B0000319F82A033A0319FD2A013A0319022BE9 |
:1015C000073A0319072B013A03190C2B033A0319A5 |
:1015D000112B013A0319162B0F3A03191B2B013A51 |
:1015E0000319202B252B0610051285130513292B13 |
:1015F0000614051285130513292B061005168513ED |
:101600000513292B0614051685130513292B06101F |
:10161000051285170513292B0614051285170513C6 |
:10162000292B0610051685170513292B06140516F8 |
:1016300085170513292B0610051285130517292B6D |
:101640000614051285130517292B0610051285139C |
:10165000051300348A11E4278A150430EA00FA30B1 |
:10166000FC008A1172208A15EA0B2F2BE5012D1040 |
:10167000AD10E701E91069106508EA00D3226400A3 |
:101680002D1C052C2D10E7080319482BE703052C0A |
:101690000530E7006A10861B6A14F701AD1A77144B |
:1016A0006A08770601390319592BAD126A18AD166D |
:1016B0005E2B6A185D2B5D145E2B5D106A10851A17 |
:1016C0006A14F7012D1B77146A087706013903198C |
:1016D0006D2B2D136A182D17722B6A18712BDD14C0 |
:1016E000722BDD105D08F8007808E800E81CDF2B9D |
:1016F000691CCD2B650803178D0083168C130C1401 |
:1017000083120C08031366020319C82B650803171C |
:101710008D000313660803178C0083168C130C15B9 |
:10172000831203130B08F7008B138316031755302E |
:101730008D00AA308D008C148C189C2B0C1177080E |
:10174000831203138B046508053C0319AB2B650852 |
:10175000063C031DC82B073003178D0003132B080D |
:1017600003178C0083168C130C15831203130B08BC |
:10177000F7008B138316031755308D00AA308D00A8 |
:101780008C148C18C12B0C117708831203138B0453 |
:101790006508EA00D3226910DE2B681CDD2BE918EE |
:1017A000DC2B6508053C031CD72BE50AD82BE5018B |
:1017B0006508EA00D322E914DE2BE910052C69182C |
:1017C000F02B650803178D0083168C130C148312FD |
:1017D0000C080313E6006608EA00D3226914052CFE |
:1017E000681C042CE918032C65088A1137208A1517 |
:1017F000F80066020318FE2BE60AFF2BE6016608D6 |
:10180000EA00D322E914052CE910AD1C162CAD100A |
:101810008A1197278A157908EB007808EA00EB0807 |
:10182000031D162C6A082B3C0318172C3F2B8A111A |
:1018300009238A158A15D82D2B082A020318312C62 |
:101840002A082B02ED000330FE006D088316A0006D |
:101850008A11831271228A1540307807E700E80167 |
:10186000552C2B082A02ED000330FE006D0883166C |
:10187000A0008A11831271228A15E8017808E70016 |
:10188000E808031D472C6708403C03184A2CE80170 |
:10189000E701552C6708403CE7006808031C680F07 |
:1018A000532C0030542C003CE8006808FD00670809 |
:1018B000FC008316A101831249088316A0008A1137 |
:1018C00083128A208A15790CE800780CE700E80C6E |
:1018D000E70CE80CE70CE80CE70CE80CE70CE80C6C |
:1018E000E70C0330E8056708E6006508043C031CC4 |
:1018F0007B2C0310E60DFD016608FC008A11A12077 |
:101900008A157A088316A3007908A2007808A10036 |
:101910007708A000A701A6013430A5009130A400EB |
:101920008A118312BF208A157A088316A3007908CA |
:10193000A2007808A1007708A0008A11831237213D |
:101940008A157A08EC007908EB007808EA00770835 |
:10195000E9006C083102031CCD2C031DBF2C6B0861 |
:101960003002031CCD2C031DBF2C6A082F02031C60 |
:10197000CD2C031DBF2C2E0869020318CD2C69083D |
:10198000AE026A08031C6A0FAF026B08031C6B0FE0 |
:10199000B0026C08031C6C0FB1028A150D2E840175 |
:1019A00083131F308305603083168F001F129F1230 |
:1019B0001B0880399B0007309C008312CA01CB01B1 |
:1019C000CC01CD01CE01CF01D001D101D201D30193 |
:1019D000D401D501D601D701D801D901DA01DB0143 |
:1019E000DC01AD122D13DD018A1167208A15030871 |
:1019F0001839F70083160E08033977040E148E1475 |
:101A0000831503160B3C0319342D60308F006430AE |
:101A1000FC008A11831272208A15853090000C30E8 |
:101A2000F700073081018130840083130008F0390A |
:101A30000738800064000008F739F719F039770497 |
:101A40008000B301B201FC308F0017308E006400BB |
:101A50000C1C322DB20A0319B30A0C10FC308F0093 |
:101A600017308E00282D831660308F000108C7398B |
:101A7000083881000C30F700073083128101813073 |
:101A8000840083130008F0390738800064000008E0 |
:101A9000F739F719F0397704800085309000F0307D |
:101AA0008F005F308E0094120030940083169400F3 |
:101AB00007309C00050864000230F700F70B5E2D2C |
:101AC000000000001C0883120D1383169D01831271 |
:101AD0009701970183161F1383121F179F178316F1 |
:101AE0009F1783121F1483161F129F121B08803921 |
:101AF0002F389B000C14C03083128B048A110923E9 |
:101B00008A158A11842C8A150517FA30FC008A116F |
:101B100072208A1505132D16B101B001AF01AE0177 |
:101B20001930AB00E401E301E001DF01E101E20172 |
:101B3000DE155E1164008A11E12C8A15630083169C |
:101B40001F129F121B0880392F389B008A118312A5 |
:101B5000E9248A157818AE2DDE10AF2DDE14F701BA |
:101B60005E18F7145E08770602390319BB2D5E1064 |
:101B7000DE185E14DE2DDE1CC62D5E19C52D8A1101 |
:101B8000682E8A155E15E001DF01DE2D5E118A11D7 |
:101B900097278A157908E6007808E500E608031D0E |
:101BA000D52D65082C3C0318DE2D851ACC282A2B50 |
:101BB000E401E301E001DF01E101E2016008330239 |
:101BC000031CEC2D031DE82D32085F020318EC2DD9 |
:101BD000DF0A0319E00A102EDE15E001DF016108BB |
:101BE000163C031CF52DE10A102E6408FD00630865 |
:101BF000FC008316A1011830A0008A11831258211D |
:101C00008A157808AB006208593C031C092EE20AC9 |
:101C10000A2E2D166208E5001C2CE401E301E10107 |
:101C2000DE1D1B2E4D20F808031D1B2E2908E3077F |
:0A1C30000318E40ADE119A2D630088 |
:104200000300050000000300000003000000190087 |
:04400E001C2FFC3F28 |
:00000001FF |
;PIC16F88 |