/Designs/HAM Constructions/HF_TRAMP/FW/V1_6/VFO.C
0,0 → 1,1558
//**********************************************************************
// program pro rizeni TRXu
//**********************************************************************
// (c) OK1XGL 2005
// verze 1.0.0 - uvodni verze
// verze 1.0.1 - prechod 16F877 a usazeni sibnalu na porty
// verze 1.0.2 = odladeni zakladnich funkci - muzeme delat tistak
// verze 1.0.3 - definitivni usazeni signalu - hotovy DPS
// verze 1.0.4 - prvni pouzitelna verze
// verze 1.1.0 - SIGNAL ATN1 PRESUNUT NA RE0 A SIGNAL ATN2 PRESUNUT NA RC0 !!!!!
// verze 1.2.0 - doprobramovan jednopakovy klic
// verze 1.3.0 - elbug zmenen na dvoupakovy a cely presunut do preruseni
// verze 1.4.0 - po zapnuti se RX naladi na QRP kmitocet na danem pasmu
// - PSV se povazuje za platne jen kdyz je skutecne zaklicovano
// verze 1.5.0 - upraven zpusob cteni dat z AD prevodniku
// - pwm rozsirena na 157 kroku
// - doplneno ALC pro vykon a nastaveni vykonu v 0.5W jednotkach
// verze 1.6.0 - provedena kalibrace S-metru
 
 
// Poznamky:
// zobrazeni kmitoctu na LCD trva 30ms !!!
// pri rychlosti klicovani 200zn/s je sirka impulzu (tecka) cca 30ms
// timer2 vyhrazen na generovani tonu a ma nastaven kmitocet 800Hz, ton se generuje PWM, rizeni vykonu tez PWM 800Hz je baze
// timer 1 vyhrazen pro elbug
 
 
//DODELAT: - pri BK provozu je treba, aby se pri prepnuti na prjem mezi elementy znacky nezobrazoval S-metr, protoze
// se to tak rychle nestiha zobrazovat a je lepsi,aby se zobrazovalo stale psv a vykon. Nyni je toho dosazeno tak,
// ze pokud je aktivni elbug, tak se zobrazeni nedela ovsem toto reseni nebude fungovat pri externim elbugu
// spravne reseni je timerem, ktery bude vykryvat cas mezi znackami
// - projit kod a nektere veci ucesat
 
 
 
#include "vfo.h"
#include <lcd.c>
 
 
//#define ADC_LCD // misto obvyklych udaju zobrazuje hodnoty AD prevodniku
//#define NO_FILTER_CONTROL // vyrazuje prubeznou kontrolu pritomnosti filtru pro prislusne pasmo
 
 
/////////// FUNKCE PRO ZOBRAZOVANI NA LCD /////////
 
// podpora zobrazeni RIT
// POZOR: pred pouzitim je nutno vynulovat promennou lcd_pos !!!
void rit_lcd_putc(int8 c)
{
lcd_pos++;
if(lcd_pos==2) lcd_putc('.'); // prida tecku za KHZ
lcd_putc(c);
} // rit_lcd_putc
 
 
 
// podpora zobrazeni kmitoctu VFO
// POZOR: pred pouzitim je nutno vynulovat promennou lcd_pos !!!
void vfo_lcd_putc(int8 c)
{
lcd_pos++;
// za MHz dopln pismenko VFO
if(lcd_pos==3)
if(vfo_index)
if(bit_test(_SPLIT)) lcd_putc('\21'); // vyplnene b
else lcd_putc('b');
else if(bit_test(_SPLIT)) lcd_putc('\22'); // vyplnene a
else lcd_putc('a');
// za KHz dopln tecku
if(lcd_pos==6)
if(step_index) lcd_putc(':'); // hrube ladeni
else lcd_putc('.'); // jemne ladeni
lcd_putc(c);
} //vfo_lcd_putc
 
 
// podpora zobrazeni vykonu a psv
// POZOR: pred pouzitim je nutno vynulovat promennou lcd_pos !!!
void pwr_lcd_putc(int8 c)
{
lcd_pos++;
if(lcd_pos==2) lcd_putc('.');
lcd_putc(c);
} // pwr_lcd_putc
 
 
 
// podpora zobrazeni napeti baterie
// POZOR: pred pouzitim je nutno vynulovat promennou lcd_pos !!!
void batt_lcd_putc(int8 c)
{
lcd_pos++;
if(lcd_pos==3) lcd_putc('.');
lcd_putc(c);
} // batt_lcd_putc
 
 
 
 
/////////// FUNKCE PRO PRACI S DDS /////////
 
// odesle 16 bitovy zaznam do DDS
//
void dds_send(int16 record)
{
int8 i;
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#use fast_io(D)
 
output_low(DDS_FSYNC); // zacatek komunikace s DDS
i=16;
do
{
if(bit_test(record,15)) output_high(DDS_SDATA); // vystav datovy bit, zaciname MSB
else output_low(DDS_SDATA);
output_low(DDS_SCK); // hodinovy impulz
output_high(DDS_SCK);
record=record<<1; // na dalsi bit
} while(--i);
 
output_high(DDS_FSYNC); // konec komunikace s DDS
#use standard_io(A)
#use standard_io(B)
#use standard_io(C)
#use standard_io(D)
} // dds_send
 
 
 
 
// naplni registr0 pro kmitocet v DDS (28 bitu)
//
void dds_freq0(int32 freq)
{
int16 record;
 
// posli ridici slovo
dds_send(CTRL_FREQ0);
 
// zapis pozadovane frekvence
// zapis LSB
record=(int16)freq;
bit_set(record,14); // zapis do frekvencniho registru 0
bit_clear(record,15);
dds_send(record);
// zapis MSB
record=(int16)((freq<<2)>>16); // divny zapis, ale >> 14 dava hrozny vysledek
bit_set(record,14); // zapis do frekvencniho registru 0
bit_clear(record,15);
dds_send(record);
} // dds_freq0
 
 
 
/////////// FUNKCE PRO RIZENI PRIPOSLECHU /////////
 
// vypne generovani tonu priposlechu
//
#inline
void tone_off()
{
int8 a;
a=input(TONE);
} // tone_off()
 
 
 
// zapne generovani tonu priposlechu
//
#inline
void tone_on()
{
output_low(TONE);
} // tone_on
 
 
 
 
/////////////////////////////////
// Prerusovaci rutiny
/////////////////////////////////
// rezie preruseni je cca 30+30 cyklu
 
// preruseni od zmeny polohy kroutitka
#int_EXT
void Encoder_handler()
{
#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
#use fast_io(d)
 
 
int1 dir;
 
dir=input(ENCODER_DIR); // zapamatuj si smer krouceni
bit_set(_ENC_CHNG); // oznam zmenu polohy kroutitka
if(dir) enc_delta++; // pridej
else enc_delta--; // uber
 
#use standard_io(a)
#use standard_io(b)
#use standard_io(c)
#use standard_io(d)
} // Encoder_handler
 
 
 
// periodicke tiky, granularita TICK_TIME
// citace/ casovace se granularitou TICK_TIME
#INT_TIMER0
void Tick_handler()
{
#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
#use fast_io(d)
 
set_timer0(TICK_TIME); // znovu natahni timer
 
// mereni napeti z prevodniku
if(bit_test(_ADC_START))
{
read_adc(ADC_START_ONLY); // spust prevod
bit_clear(_ADC_START); // priste budeme cist vysledek
} else
{
adc_val=read_adc(ADC_READ_ONLY); // vyzvedni vysledek
 
if(bit_test(_KEYING)) // hodnoty vykonu aktualizuj jen pokud je zaklicovano
{
if(adc_ch==1) fwd_val=adc_val;
if(adc_ch==0) rev_val=adc_val;
}
if(adc_ch==2) batt_val=adc_val;
else if(adc_ch==3) smtr_val=adc_val;
else if(adc_ch==4) bnd_val=adc_val;
if(adc_ch>=4) adc_ch=0; // mame 5 kanalu
else adc_ch++;
set_adc_channel(adc_ch); // priste nasledujici kanal
bit_set(_ADC_START); // priste budeme spoustet prevod
}
 
// klicovani
if(bit_test(_TXDELAY)) // jen pokud tx_delay vyprsel
{
if(!bit_test(_ELBUG_ON))
keyer=(~input_b()) & 0b10000000; // pokud neni zapnut elbug, zavzorkuj stav klice
 
if((keyer!=0 && !bit_test(_ELBUG_ON)) || // pri vypnutem elbugu rizeno stavem pak
(bit_test(_ELBUG_OUT) && bit_test(_ELBUG_ON))) // pri zapnutem elbugu rizeno stavem _ELBUG_ON
{
// zaklicuj
output_high(KEYING);
tone_on();
bit_clear(_RUN_VOX);
bit_set(_KEYING);
adc_ch=0; // zacneme merit dopredny vykon
set_adc_channel(adc_ch);
bit_set(_ADC_START); // priste spustime prevod ADC
} else
{
// prestan klicovat
output_low(KEYING);
vox_timer=vox_time; // natahni vox_timer
bit_set(_RUN_VOX);
tone_off();
bit_clear(_KEYING);
}
bit_clear(_TXDELAY);
}
 
 
// periodicky timer na aktualizaci kde ceho
if(update_timer==0xFF) update_timer=UPDATE_TIME;
else update_timer--;
 
// vox timer
if(bit_test(_RUN_VOX))
if(vox_timer!=0) vox_timer--;
else
{
// vox vyprsel
bit_clear(_RUN_VOX);
output_low(RXTX); // prepni zpet na prijem
bit_clear(_TRANSMIT);
bit_set(_DDS_UPDATE);
}
 
// timer pro zjisteni dlouheho stisku tlacitek
if(key_timer!=0) key_timer--;
 
 
// periodicke cteni tlacitek
#use fast_io(C)
keys_work=(~input_c()) & KEY_MASK; // precti stav tlacitek
#use standard_io(C)
if(keys_work!=keys_old) keys_old=keys_work; // neshoda zapamatuj si novy stav
else
{
// shoda
if(keys_work!=0)
{
// tlacitko je STISKNUTO
if(keys==0)
{
// akceptujeme jen pokud bylo zpracovano vse predchozi
keys=keys_work; // zapamatuj si nove tlacitko
key_timer=KEY_LONG; // natahni casovac pro zjisteni dlouheho stisku
} else
{
// neco je jeste ke zpracovani
if(key_timer==0 && !bit_test(_KEYS_RELEASE))
{
// jde o dlouhy stisk tlacitka
bit_set(_KEYS_LONG);
bit_set(_KEYS_VALID);
}
}
} else
{
// tlacitko je UVOLNENO
if(key_timer!=0)
{
// jde o kratky stisk tlacitka
bit_set(_KEYS_VALID);
key_timer=0;
} else if(bit_test(_KEYS_RELEASE))
{
keys_flags=0; // jde o klidovy stav - tlacitka zpracovana
keys=0;
}
}
}
 
#use standard_io(a)
#use standard_io(b)
#use standard_io(c)
#use standard_io(d)
} // Tick_handler
 
 
 
 
// periodicke tiky kazdych 5ms
// vyuzito pro rizeli LCD_LED
//
#INT_TIMER2
void led_handler()
{
#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
#use fast_io(d)
 
 
flash_timer++;
 
// rizeni LED
// pri prijmu bez attenuatoru sviti zelena
// pri prijmu s attenuatorem sviti zluta
// pri vysilani sviti cervena
// pri vybite baterii pri prijmu led blika
 
 
if(bit_test(_TRANSMIT))
{
// vysilani - rozsvid cervenou LED
if(bit_test(_LED_UPDATE)) output_high(LCD_LED1);
else output_low(LCD_LED1);
output_low(LCD_LED2);
} else
{
if(bit_test(_BATT_LOW) && bit_test(flash_timer,7))
{
// zhasni led
output_low(LCD_LED1);
output_low(LCD_LED2);
} else
{
// prijem - rozsvid zelenou nebo zlutou led
if(bit_test(_LED_UPDATE))
{
output_high(LCD_LED2);
output_low(LCD_LED1);
} else
{
output_low(LCD_LED2);
if(bit_test(_ATTN)) output_high(LCD_LED1);
else output_low(LCD_LED1);
}
}
}
 
if(bit_test(_LED_UPDATE)) bit_clear(_LED_UPDATE);
else bit_set(_LED_UPDATE);
 
#use standard_io(a)
#use standard_io(b)
#use standard_io(c)
#use standard_io(d)
} // led_handler
 
 
 
 
// cteni pak, klice
#INT_RB
void paddle_handler()
{
#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
#use fast_io(d)
 
keyerb=(~input_b()); // precti stav pak
if(bit_test(_ELBUG_ON)) keyerb=keyerb & 0b11000000; // platne jsou obe paky
else keyerb=keyerb & 0b10000000; // platna je paka tecek
 
if(!bit_test(_TXDELAY)) // reagujeme jen kdyz nebezi TXDELAY
{
if(!bit_test(_ELBUG_ON))
{
// RUCNI KLICOVANI
set_timer0(TICK_TIME); // txdelay je dano jednim zakladnim tikem, natahni tik
_T0IF=0;
bit_set(_TXDELAY); // spustime TXDELAY
} else
{
// ELBUG
// nastav priznaky pak
if(bit_test(_ELBUG_REV))
{
if(bit_test(keyerb,6)) bit_set(_ELBUG_DOT);
if(bit_test(keyerb,7)) bit_set(_ELBUG_DASH);
} else
{
if(bit_test(keyerb,7)) bit_set(_ELBUG_DOT);
if(bit_test(keyerb,6)) bit_set(_ELBUG_DASH);
}
if(!bit_test(_ELBUG_BSY))
{
// spusteni elbugu
setup_timer_1(T1_INTERNAL | T1_DIV_BY_8); // spust casovac
_TMR1IF=1;
}
}
if(!bit_test(_TRANSMIT) && keyerb!=0) // pri stisku pak prejdeme na vysilani pokud tomu jiz tak neni
{
bit_set(_TRANSMIT); // priznak stavu vysilani
output_high(RXTX); // prepni TRX na vysilani
bit_set(_DDS_UPDATE); // nastav vysilaci kmitocet
}
}
 
#use standard_io(a)
#use standard_io(b)
#use standard_io(c)
#use standard_io(d)
} // paddle_handler
 
 
 
// elbug
//
#int_timer1
void elbug_handler()
{
#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
#use fast_io(d)
 
 
if(bit_test(_ELBUG_SP))
{
// odvysilali jsem tecku nebo carku - musime dovysilat mezeru
bit_clear(_ELBUG_SP); // priste budeme vysilat podle stavu pak
bit_clear(_ELBUG_OUT);
set_timer1(elbug_dot_sp); // natahni casovac na mezeru
set_timer0(TICK_TIME); // txdelay je dano jednim zakladnim tikem, natahni tik
_T0IF=0;
bit_set(_TXDELAY); // spustime TXDELAY
return;
}
 
if(bit_test(_ELBUG_BSY))
{
// odvysilali jsme posloupnost tecka-mezera nebo carka-mezera
// nuluj priznak prave dovysilaneho elementu
if(bit_test(_ELBUG_LAST)) bit_clear(_ELBUG_DASH);
else bit_clear(_ELBUG_DOT);
// dale se rozhodujeme podle stavu pak
keyer=(~input_b()) & 0b11000000; // precti stav pak
 
// nastav priznak pak podle stisknute paky
if(bit_test(_ELBUG_REV))
{
if(bit_test(keyer,6)) bit_set(_ELBUG_DOT);
if(bit_test(keyer,7)) bit_set(_ELBUG_DASH);
} else
{
if(bit_test(keyer,7)) bit_set(_ELBUG_DOT);
if(bit_test(keyer,6)) bit_set(_ELBUG_DASH);
}
 
if(bit_test(_ELBUG_REAL) && keyer==0) // nestisknuto nic
{
// pri realnem klicovani po uvolneni pak se uz dal nic nevysila
bit_clear(_ELBUG_DOT);
bit_clear(_ELBUG_DASH);
}
}
 
// prepnuti na vysilani pokud tomu uz tak neni
if(!bit_test(_TRANSMIT) &&
(bit_test(_ELBUG_DOT) || bit_test(_ELBUG_DASH)))
{
bit_set(_TRANSMIT); // priznak stavu vysilani
output_high(RXTX); // prepni TRX na vysilani
bit_set(_DDS_UPDATE); // nastav vysilaci kmitocet
}
 
// nastav hodnotu casovace podle stisknute paky
if(bit_test(_ELBUG_DOT))
{
if(bit_test(_ELBUG_DASH))
{
// stisknuty obe paky - vysilej opak priznaku LAST
if(bit_test(_ELBUG_LAST))
{
bit_clear(_ELBUG_LAST);
set_timer1(elbug_dot_sp); // natahni casovac na tecku
} else
{
bit_set(_ELBUG_LAST);
set_timer1(elbug_dash); // natahni casovac na carku
}
} else
{
bit_clear(_ELBUG_LAST);
set_timer1(elbug_dot_sp); // natahni casovac na tecku
}
} else if(bit_test(_ELBUG_DASH))
{
bit_set(_ELBUG_LAST);
set_timer1(elbug_dash); // natahni casovac na carku
} else
{
// NENI CO VYSILAT -KONCIME
bit_clear(_ELBUG_BSY);
setup_timer_1(T1_DISABLED); // zastav casovac
return;
}
 
bit_set(_ELBUG_BSY); // elbug bezi
bit_set(_ELBUG_SP); // priste musime vysilat mezeru
bit_set(_ELBUG_OUT);
set_timer0(TICK_TIME); // txdelay je dano jednim zakladnim tikem, natahni tik
_T0IF=0;
bit_set(_TXDELAY); // spustime TXDELAY
 
#use standard_io(a)
#use standard_io(b)
#use standard_io(c)
#use standard_io(d)
} // elbug_handler
 
 
 
/////////// FUNKCE PRO OVLADANI UTLUMU /////////
 
// natavi utlum
//
void Attn_0dB()
{
output_low(ATN1);
output_low(ATN2);
output_high(ATNC);
delay_ms(RELE_PULSE);
input(ATNC); // prepni ANTC zpet do tretiho stavu (vstup)
delay_ms(RELE_PULSE);
input(ATN1);
input(ATN2);
}
 
 
// natavi utlum
//
void Attn_6dB()
{
output_high(ATN1);
output_low(ATNC);
delay_ms(RELE_PULSE);
input(ATNC); // prepni ANTC zpet do tretiho stavu (vstup)
output_low(ATN2);
output_high(ATNC);
delay_ms(RELE_PULSE);
input(ATNC); // prepni ANTC zpet do tretiho stavu (vstup)
delay_ms(RELE_PULSE);
input(ATN1);
input(ATN2);
}
 
 
// natavi utlum
//
void Attn_12dB()
{
output_low(ATN1);
output_high(ATNC);
delay_ms(RELE_PULSE);
input(ATNC); // prepni ANTC zpet do tretiho stavu (vstup)
output_high(ATN2);
output_low(ATNC);
delay_ms(RELE_PULSE);
input(ATNC); // prepni ANTC zpet do tretiho stavu (vstup)
delay_ms(RELE_PULSE);
input(ATN1);
input(ATN2);
}
 
 
// natavi utlum
//
void Attn_18dB()
{
output_high(ATN1);
output_high(ATN2);
output_low(ATNC);
delay_ms(RELE_PULSE);
input(ATNC); // prepni ANTC zpet do tretiho stavu (vstup)
delay_ms(RELE_PULSE);
input(ATN1);
input(ATN2);
}
 
 
 
/*
// precte z prevodnihu hornich 8 bitu
//
int8 adc()
{
return(read_adc()>>8) ;
} // adc
*/
 
 
/////////// FUNKCE PRO PRACI S EEPROM /////////
 
// aktualizuje kontrolni soucet
//
void update_eeprom()
{
int8 i;
int8 crc;
crc=0;
for(i=0;i<EE_ADR_CRC;i++) crc+=read_eeprom(i);
crc=0-crc;
write_eeprom(EE_ADR_CRC,crc);
} // update_eeprom
 
 
 
// zkontroluje obsah pameti eeprom a pokud je poskozen, nAstavi defaultni parametry
//
void check_eeprom()
{
int8 i;
int8 crc;
 
crc=0;
for(i=0;i<=EE_ADR_CRC;i++) crc=crc+read_eeprom(i);
 
if(crc!=0)
{
i=EE_ADR_POWER;
while(i<BAND_NUM) write_eeprom(i++,PAR_LIMIT[PAR_POWER][0]); // minimalni vykon na vsech pasmech
write_eeprom(EE_ADR_KEYER,20); // nastaveno 20 WPM
write_eeprom(EE_ADR_VOX,6); // vox 300ms
write_eeprom(EE_ADR_BATT,0); // konstantni hodntota,dale se nemeni
write_eeprom(EE_ADR_KEYER_REV,0); // nereverzuj paky
write_eeprom(EE_ADR_KEYER_MODE,0); // doplnkove klicovani
write_eeprom(EE_ADR_ATTN,PAR_LIMIT[PAR_VOX][0]); // utlum vypnut
update_eeprom(); // aktualizuj kontorlni soucet
}
 
} // check_eeprom
 
 
 
 
 
/////////////////////////////////////
// VYKONNE FUNKCE HLAVNI SMYCKY
/////////////////////////////////////
 
 
// zpracovani zmeny polohy kroutitka
// trva max 600cyklu (600us)
//
// CHELO BY TO UCESAT POMOCI KONSTRUKCE IF - RETURN
#inline
void enc_chng()
{
int32 freq_dds;
signed int32 delta_freq;
signed int16 delta_rit;
 
if(bit_test(_MNU) || bit_test(_MNU2))
{
// NASTAVUJEME PARAMETRY
if(enc_delta<ENC_HISTEREZE && enc_delta>-ENC_HISTEREZE) return; // zmeny pod minimum si nevsimej
 
if(enc_delta>0)
{
// nastala zmena +1
if(bit_test(_MNU2))
{
if(par_index<PAR_NUM-3)
{
par_index++; // zmena typu parametru pokud projde kontrola horni meze
bit_set(_LCD2_UPDATE);
}
} else if(par[par_index]<PAR_LIMIT[par_index][1]) // zmena hodnoty parametru pokud projde kontrola horni meze
{
par[par_index]++;
bit_set(_PAR_UPDATE); // pozadavek aktualizace parametru
}
} else
{
// nastala zmena -1
if(bit_test(_MNU2))
{
if(par_index>0)
{
par_index--; // zmena typu parametru pokud projde kontrola dolni meze
bit_set(_LCD2_UPDATE);
}
} else if(par[par_index]>PAR_LIMIT[par_index][0]) // zmena hodnoty parametru pokud projde kontrola dolni meze
{
par[par_index]--;
bit_set(_PAR_UPDATE); // pozadavek aktualizace parametru
}
}
enc_delta=0; // zmena provedena
} else
{
// LADIME KMITOCET
if(bit_test(_RIT))
{
// ladime RIT
delta_rit=enc_delta*RIT_STEP;
enc_delta=0;
if(freq_rit+delta_rit <=RIT_LIMIT[1] &&
freq_rit+delta_rit >=RIT_LIMIT[0]) freq_rit+=delta_rit;
} else
{
// ladime VFO
delta_freq=enc_delta*FREQ_STEP[step_index];
enc_delta=0;
freq_dds=freq_vfo[vfo_index]+delta_freq;
if(freq_dds <=BAND_LIMIT[band_index][1] &&
freq_dds >=BAND_LIMIT[band_index][0]) freq_vfo[vfo_index]+=delta_freq;
}
bit_set(_DDS_UPDATE); // pozadujeme zmenu kmitoctu v DDS
}
bit_clear(_ENC_CHNG); // zmena polohy kroutitka zpracovana
} // enc_chng
 
 
 
 
 
// aktualizuje parametry
//
#inline
void par_update()
{
 
// int16 power;
 
bit_clear(_PAR_UPDATE);
 
switch(par_index)
{
case PAR_ATTN:
bit_set(_ATTN); // pri utlumu bude misto zelene led svitit zluta
switch(par[PAR_ATTN])
{
case 1: Attn_6dB();
break;
case 2: Attn_12dB();
break;
case 3: Attn_18dB();
break;
default:Attn_0dB();
bit_clear(_ATTN); // zadny utlum, zpet zelena led
break;
}
break;
case PAR_POWER:
// set_pwm2_duty(par[PAR_POWER]);
// power=par[PAR_POWER];
// set_pwm2_duty(power<<1);
//!!!!!
power=par[PAR_POWER]*5; // vykon je v nasobcich 0.5W
break;
case PAR_KEYER:
if(par[PAR_KEYER]<=PAR_LIMIT[PAR_KEYER][0]) bit_clear(_ELBUG_ON); ///elbug_flags=0; // vypni elbug
else
{
// zapni elbug a nastav rychlost
bit_set(_ELBUG_ON);
elbug_dot_sp=~(ELBUG_CONST/par[PAR_KEYER]); // preved na hodnotu citace TMR1
elbug_dot_sp++;
elbug_dash=(elbug_dot_sp<<1)+elbug_dot_sp; // *3, ale rychleji
}
 
break;
case PAR_VOX:
vox_time=par[PAR_VOX];
if(vox_time!=0) vox_time=vox_time*10; // cas je ve 50ms jednotkach
else vox_time=1; // minimalni vox je 5ms
break;
case PAR_KEYER_REV:
if(par[PAR_KEYER_REV]) bit_set(_ELBUG_REV); //
else bit_clear(_ELBUG_REV);
break;
case PAR_KEYER_MODE:
// if(par[PAR_KEYER_MODE]) bit_set(_ELBUG_REAL); //
// else bit_clear(_ELBUG_REAL);
break;
}
bit_set(_LCD2_UPDATE); // pozadujeme update 2. radku dispeje
} // par_update()
 
 
 
 
// aktualizuje kmitocet v dds
// trva max. cca 2500cyklu (2.5ms)
//
#inline
void dds_update()
{
int32 freq_dds;
signed int32 delta_freq;
signed int32 freq_rit2;
 
 
if(!bit_test(_TRANSMIT))
{
// PRIJEM
if(band_index>=SUB_IF_INDEX) freq_dds=freq_vfo[vfo_index]-FREQ_IF; // pri prijmu na 14MHz se odecita kmitocet mezifrekvence
else freq_dds=freq_vfo[vfo_index]+FREQ_IF; // pri prijmu pod 14MHz se pricita kmitocet mezifrekvence
 
if(bit_test(_RIT))
{
freq_rit2=freq_rit; // prevod na signed int32, chyba v C, neumi int32 + signed int16
freq_dds=freq_dds+freq_rit2; // je-li zapnut RIT, udelej korekci kmitoctu
}
bit_set(_LCD1_UPDATE); // pozadujeme zmenit kmitocet na lcd
} else
{
// VYSILANI
if(bit_test(_SPLIT)) // pri split se pouzije opacne vfo
freq_dds=freq_vfo[(~vfo_index)];
else freq_dds=freq_vfo[vfo_index];
}
 
dds_freq0((int32)((float)freq_dds*CONVERT_CONST)); // odesli jej do DDS trva to cca 2050 cylklu (2.05ms)
bit_clear(_DDS_UPDATE); // kmitocet v dds zmenen
// bit_set(_LCD1_UPDATE); // pozadujeme zmenit kmitocet na lcd
} // dds_update
 
 
 
 
// aktualizuje zobrazeni na lcd - 1.radek
// trva max. 3000cyklu (30ms) !!!!!!
//
//#inline
#separate
int8 lcd1_update()
{
int16 rit_val;
 
lcd_gotoxy(1,1);
bit_clear(_LCD1_UPDATE);
 
if(bit_test(_MNU2)) printf(lcd_putc,"PARAM: "); // zobraz ze vybirame typ parametru
else if(bit_test(_MNU))
{
// zobraz nazev parametru
switch(par_index)
{
case PAR_ATTN: printf(lcd_putc,"ATTN: ");
break;
case PAR_POWER: printf(lcd_putc,"POWER: ");
break;
case PAR_KEYER: printf(lcd_putc,"KEYER: ");
break;
case PAR_VOX: printf(lcd_putc,"DELAY: ");
break;
case INF_BATT: printf(lcd_putc,"BATTERY:");
break;
case PAR_KEYER_MODE: printf(lcd_putc,"MODE: ");
break;
case PAR_KEYER_REV: printf(lcd_putc,"REVERSE:");
break;
 
}
} else if(bit_test(_RIT))
{
// POZN: fce printf spatne zachazi se znaminkovimi cisly, proto je znamenko
// zobrazeno samostatne a rit je preveden na neznamenkove cislo
printf(lcd_putc,"RIT:");
if(freq_rit<0) lcd_putc('+');
else lcd_putc('-');
rit_val=abs(freq_rit);
lcd_pos=0;
printf(rit_lcd_putc,"%04LU",rit_val); // zobraz RIT na LCD
} else
{
lcd_pos=0;
printf(vfo_lcd_putc,"%8LD",freq_vfo[vfo_index]); // zobraz kmitocet na LCD
}
} // lcd1_update
 
 
 
// pomocna funkce pro zobrazeni vykonu a psv na lcd
//
#separate
void lcd_pwr_psv()
{
#ifdef ADC_LCD
printf(lcd_putc,"F%2X R%2X",pwr_val,psv_val);
#else
 
// vysilani - zobrazujeme vykon a psv
if(pwr_val>99) printf(lcd_putc,">10");
else
{
lcd_pos=0;
printf(pwr_lcd_putc,"%02U",pwr_val);
}
printf(lcd_putc,"W ");
if(psv_val>99) printf(lcd_putc,">10");
else
{
lcd_pos=0;
printf(pwr_lcd_putc,"%02U",psv_val);
}
#endif
} // lcd_pwr_psv
 
 
 
// aktualizuje zobrazeni na lcd - 2.radek
// trva max 2000 cyklu (2ms)
//
//#inline
#separate
void lcd2_update()
{
int8 i;
int16 vox;
int16 batt;
 
bit_clear(_LCD2_UPDATE);
lcd_gotoxy(1,2);
 
if(bit_test(_MNU2))
{
// zobraz vybrany parametr
switch(par_index)
{
case PAR_POWER: printf(lcd_putc,"POWER ");
break;
case PAR_VOX: printf(lcd_putc,"DELAY ");
break;
case INF_BATT: printf(lcd_putc,"BATTERY ");
break;
case PAR_KEYER_MODE: printf(lcd_putc,"MODE ");
break;
case PAR_KEYER_REV: printf(lcd_putc,"REVERSE ");
break;
 
}
} else if(bit_test(_MNU))
{
// zobraz hodnotu parametru
switch(par_index)
{
case PAR_ATTN: printf(lcd_putc,"-%2U dB ",par[PAR_ATTN]*6); // krok je po 6dB
break;
case PAR_POWER: if(!bit_test(_TRANSMIT))
{
lcd_pos=0;
printf(pwr_lcd_putc,"%02UW PTT",power); // prijem - zobraz pozadovany vykon a vyzvu k vysilani
} else lcd_pwr_psv(); // vysilani - zobraz vykon a psv
break;
case PAR_KEYER: if( par[PAR_KEYER]<=PAR_LIMIT[PAR_KEYER][0]) printf(lcd_putc,"OFF ");
else printf(lcd_putc,"%2U ",par[PAR_KEYER]);
break;
case PAR_VOX:
vox=par[PAR_VOX];
vox=vox*50; // ve 50ms jednotkach
printf(lcd_putc,"%4LU ms ",vox);
break;
case INF_BATT:
#ifdef ADC_LCD
printf(lcd_putc,"%3X V ",batt_val);
#else
// zobraz napeti baterie na desetiny voltu
batt=batt_val;
batt=(batt*10)/16;
lcd_pos=0;
printf(batt_lcd_putc,"%03UV ",(int8)batt);
 
#endif
break;
case PAR_KEYER_MODE:
if(par[PAR_KEYER_MODE]) printf(lcd_putc,"B ");
else printf(lcd_putc,"A ");
break;
case PAR_KEYER_REV:
if(par[PAR_KEYER_REV]) printf(lcd_putc,"YES ");
else printf(lcd_putc,"NO ");
break;
 
}
} else if(bit_test(_TRANSMIT)) lcd_pwr_psv(); // vysilani - zobraz vykon a psv
else if(!bit_test(_ELBUG_BSY)) // v mezerach mezi znackami elbugu S-metr nezobrazuj
{
// prijem - zobrazujeme S-metr
#ifdef ADC_LCD
printf(lcd_putc,"SMTR:%2X ",smtr_val);
#else
if(smtr_val<=S_METER[0]) lcd_putc('2');
else lcd_putc(' ');
if(smtr_val<=S_METER[1]) lcd_putc('3');
else lcd_putc(' ');
if(smtr_val<=S_METER[2]) lcd_putc('4');
else lcd_putc(' ');
if(smtr_val<=S_METER[3]) lcd_putc('5');
else lcd_putc(' ');
if(smtr_val<=S_METER[4]) lcd_putc('6');
else lcd_putc(' ');
if(smtr_val<=S_METER[5]) lcd_putc('7');
else lcd_putc(' ');
if(smtr_val<=S_METER[6]) lcd_putc('8');
else lcd_putc(' ');
if(smtr_val<=S_METER[8]) lcd_putc('\23');
else if(smtr_val<=S_METER[7]) lcd_putc('9');
else lcd_putc(' ');
#endif
}
} // lcd2_update()
 
 
 
 
// nastavi pasmo podle pripojeneho filtru
//
//#inline
void set_band()
{
// int8 adc_band;
 
set_adc_channel (BND_CH); // prepni ADC na vstup signalu BAND
delay_ms(20);
 
// opakuj dokud neni pripojen vhodny filtr
for(;;)
{
bnd_val=read_adc() & BAND_ADC_MASK;
// prohlidni tabulku moznych filtru
band_index=BAND_NUM;
while(band_index--)
{
if(bnd_val==BAND_ADC[band_index]) return; // platny filtr pritomen
}
printf(lcd_putc,"\rCONNECT\n");
printf(lcd_putc," FILTER");
delay_ms(500);
}
} // set_band
 
 
 
 
// mereni analogovych vstupu
//
// doba trvani max 3000 cyklu (3ms)
#separate
void analog_inputs()
{
static int8 count;
int16 k;
int32 pom32,pom32_2; // pro vypocet dopredneho vykonu
int16 pom16,pom16_2; // pro vypocet PSV
signed int8 delta;
 
 
#ifndef NO_FILTER_CONTROL // vyrazuje prubeznou kontrolu pritomnosti filtru pro prislusne pasmo
if((bnd_val & BAND_ADC_MASK)!=BAND_ADC[band_index]) reset_cpu(); // fittr byl odpojen
#endif
 
// mereni napeti baterie
if(batt_val+5<=BATT_MIN) bit_set(_BATT_LOW); // baterie je vybita
 
// vypocti aktualni vykon a psv a reguluj vykon
if(bit_test(_TRANSMIT))
{
#ifdef ADC_LCD // vypina zpracovani - zobrazuje prime hodnoty z prevodniku
pwr_val=fwd_val;
psv_val=rev_val;
#else
// vypocti vykon na desetiny watu
pom32=fwd_val;
pom32=pom32*pom32; // vykon je umerny kvadratu napeti
// vynasobime *10 - vykon bude 100mW jednotkach
// realizuje *10, je vyrazne casove kratsi ( o cca 500cyklu)
pom32_2=pom32<<3;
pom32_2=pom32_2+pom32;
pom32_2=pom32_2+pom32;
pwr_val=pom32_2/PWR_FWD_CONST; // vydelime kalibracni konstantou pro dopredny vykon
 
// vypocti PSV na desetinu
if(fwd_val>=0 && rev_val==0) psv_val=10; // psv je 1.0 pokud je odrazeny vykon nulovy
else
{
pom16=fwd_val;
pom16=pom16<<4; // vynasobime *16 pro vetsi presnost
k=pom16/rev_val; // pomer odpovidajici ciniteli odrazu
if(k<=16) psv_val=250; // PSV se blizi nekonecnu
else if(k>337) psv_val=10; // psv je lepsi jak 1.1 tedy ho povazujeme za 1.0
else
{
// toto realizuje vyraz (k+16)*10
pom16=k+16;
pom16_2=pom16<<3;
pom16_2=pom16_2+pom16;
pom16_2=pom16_2+pom16;
// vypocet psv
psv_val=pom16_2/(k-16);
}
}
 
// rizeni vykonu (ALC)
if(psv_val>BAD_PSV) delta=PWR_LIM-pwr_val; // pri spatnem PSV omez vykon
else delta=power-pwr_val;
if(delta<-PWR_HIST_HI && pwm_val>PWM_MIN)
{
if(delta<-10) pwm_val=pwm_val-4;
else pwm_val--;
pom16=pwm_val;
set_pwm2_duty(pom16<<1);
} else if(delta>PWR_HIST_LO && pwm_val<PWM_MAX)
{
if(delta>10) pwm_val=pwm_val+4;
else pwm_val++;
pom16=pwm_val;
set_pwm2_duty(pom16<<1);
}
#endif
}
 
// zobrazeni na LCD delame mene casto
if(count>4)
{
bit_set(_LCD2_UPDATE);
count=0;
} else count++;
}// analog_inputs
 
 
/*
void pwr_control()
{
int16 aaa;
signed int8 delta;
 
if(bit_test(_TRANSMIT))
{
delta=power-pwr_val;
if(delta<-1 && pwm_val>27)
{
if(delta<-10) pwm_val=pwm_val-4;
else
pwm_val--;
aaa=pwm_val;
set_pwm2_duty(aaa<<1);
} else if(delta>2 && pwm_val<157)
{
if(delta>10) pwm_val=pwm_val+4;
else
pwm_val++;
aaa=pwm_val;
set_pwm2_duty(aaa<<1);
}
}
} // pwr_control
*/
 
 
 
 
/////////////////////////////////
///// HLAVNI FUNKCE /////
/////////////////////////////////
void main()
{
int8 ee_adr;
 
int8 a;
int8 b;
signed int8 c;
 
 
 
// inicializace LCD
lcd_init();
// definice specialnich znaku
lcd_define_char(2,LCD_CHAR_a_FILL);
lcd_define_char(1,LCD_CHAR_b_FILL);
lcd_define_char(3,LCD_CHAR_9_FILL);
 
// nastaveni smeru signalu a jejich klidovych stavu
port_b_pullups(TRUE);
output_high(DDS_FSYNC); // zapis_so DDS neaktivni
output_low(DDS_SDATA); // data do 0
output_high(DDS_SCK); // hodiny do neaktivniho stavu
output_low(RXTX); // prepni na prijem
output_low(KEYING); // neklicuj
output_low(LCD_LED2); // zhasni led
output_low(LCD_LED1); // zhasni led
input(TONE); // vypni priposlech
output_low(PWR_CTRL); // nulovy vykon
 
output_low(ATN1);
output_low(ATN2);
output_low(ATNC);
 
// inicializace DDS
dds_send(CTRL_RESET); // pozadujeme reset
dds_send(CLR_PHASE0);
dds_send(CLR_PHASE1);
 
 
// zakladni nastaveni ridicich promennych programu
update_timer=UPDATE_TIME; // natahni periodicky timer pro LCD
flags=0; // nuluj priznaky ridici program
elbug_flags=0; // nuluj priznaky pro elbug
keys_flags=0;
adc_flags=0;
adc_ch=0;
pwm_val=PWM_MIN;
enc_delta=0; // zadna zmena od kroutitka
keys=0; // zadna tlacitka nejsou stisknuta
freq_rit=0; // nuluj RIT
 
// uvodni hlaseni programu
lcd_gotoxy(1,1);
printf(lcd_putc,NAME);
lcd_gotoxy(1,2);
printf(lcd_putc,VERSION);
delay_ms(1000);
 
// nastaveni AD prevodniku
setup_adc(ADC_CLOCK_DIV_8);
setup_adc_ports(AN0_AN1_AN2_AN3_AN4); // povoleny porty AN0-AN4
 
set_band(); // nastav pasmo podle pripojeneho filtru nebo cekej na jeho pripojeni
 
check_eeprom(); // kontrola platnosti obsahu eeprom, pri poruse nastav defaultni parametry
 
// obnoveni a nastaveni parametru programu
par[PAR_POWER]=read_eeprom(EE_ADR_POWER+band_index); // vyzvedni nastaveny vykon pro dane pasmo
power=par[PAR_POWER]*5;
 
par[PAR_KEYER]=read_eeprom(EE_ADR_KEYER); // vyzvedni rychlost klice
if(par[PAR_KEYER]<=PAR_LIMIT[PAR_KEYER][0]) elbug_flags=0; // vypni elbug
else
{
// zapni elbug a nastav rychlost
bit_set(_ELBUG_ON);
elbug_dot_sp=~(ELBUG_CONST/par[PAR_KEYER]); // preved na hodnotu citace TMR1
elbug_dot_sp++;
elbug_dash=(elbug_dot_sp<<1)+elbug_dot_sp; // *3, ale rychleji
}
 
par[PAR_VOX]=read_eeprom(EE_ADR_VOX); // vyzvedni vox
vox_time=par[PAR_VOX];
if(vox_time!=0) vox_time=vox_time*20; // cas je ve 100ms jednotkach
else vox_time=2;
 
par[PAR_KEYER_REV]=read_eeprom(EE_ADR_KEYER_REV); // vyzvedni chapani pak
if(par[PAR_KEYER_REV]) bit_set(_ELBUG_REV); //
else bit_clear(_ELBUG_REV);
 
 
par[PAR_KEYER_REV]=read_eeprom(EE_ADR_KEYER_REV); // vyzvedni mod elbugu
// if(par[PAR_KEYER_REV]) bit_set(_ELBUG_REAL); //
// else bit_clear(_ELBUG_REAL);
bit_clear(_ELBUG_REAL); // mod elbugu je zatim vzdy doplnkovy
 
par[PAR_ATTN]=PAR_LIMIT[PAR_ATTN][0]; // attenuator vzdy vypnut
Attn_0dB();
freq_vfo[0]=START_FREQ[band_index]; // QRP volaci kmitocet BAND_LIMIT[band_index][0] ; // po zapnuti ma VFO nejmensi kmitocet pasma
freq_vfo[1]=START_FREQ[band_index]; // QRP volaci kmitocet BAND_LIMIT[band_index][0] ; // po zapnuti ma VFO nejmensi kmitocet pasma
bit_set(_DDS_UPDATE); // pozadujeme nastavit kmitocet v dds
step_index=0; // defaultne jemny krok ladeni
vfo_index=0; // defaultne vfoA
 
 
 
// nastaveni zakladniho tiku
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_128);
set_timer0(TICK_TIME);
 
// nastaveni pro generovani priposlechu, rizeni LCD_LED a PWM pro rizeni vykonu
setup_timer_2(T2_DIV_BY_16,TONE_SET,4); // zajisti pro PWM rozliseni 8.28 bitu
setup_ccp1(CCP_PWM); // pro generovani tonu
set_pwm1_duty((TONE_SET+1)/2); // strida cca 1:1
tone_off(); // priposlech vypnut
setup_ccp2(CCP_PWM); // pro rizeni vykonu
set_pwm2_duty((int16)27); //
setup_timer_1(T1_DISABLED); // elbug je v klidu
 
 
#use fast_io(b)
keyer=(~input_b()) & 0b11000000; // precti stav pak
#use standard_io(b)
 
if(bit_test(keyer,6)) bit_clear(_ELBUG_ON); // pokud je ori zapnuti stisknuta paka carek, je pripojen rucni klic
 
 
// povoleni preruseni
enable_interrupts(INT_EXT); // preruseni od zmeny polohy kroutitka
enable_interrupts(INT_TIMER0); // zakadni tik
enable_interrupts(INT_TIMER2); // preruseni pro rizeni vykonu, LED a generovani priposlechu
enable_interrupts(INT_TIMER1); // preruseni pro elbug
enable_interrupts(INT_RB); // preruseni od stavu pak klice
enable_interrupts(GLOBAL);
 
 
 
 
 
//#define TEST
#ifdef TEST
 
bit_set(_TRANSMIT);
//bit_set(_MNU);
 
fwd_val=150;
rev_val=10;
smtr_val=150;
bnd_val=0x20;
 
a=50;
b=5;
 
 
// testovaci smycka pro zjistovani doby behu testovane funkce
setup_timer_1(T1_INTERNAL|RTCC_DIV_1);
set_timer1(0);
 
//Analog_inputs();
 
c=b-a;
 
setup_timer_1(T1_DISABLED);
lcd_gotoxy(1,1);
printf(lcd_putc,"T:%LU",get_timer1());
lcd_gotoxy(1,2);
printf(lcd_putc,"%D",c);
 
for(;;);
 
#else
 
 
 
// HLAVNI SMYCKA
for(;;)
{
 
/////////////////
// pozadavek na zmenu kmitoctu (max. 2,5ms)
if(bit_test(_DDS_UPDATE)) dds_update();
 
////////////////
// nastala zmena polohy kroutitka
if(bit_test(_ENC_CHNG)) enc_chng();
 
/////////////////
// zmena parametru
if(bit_test(_PAR_UPDATE)) par_update();
 
/////////////////
// pozadavek zmeny kmitoctu na lcd - 1.radek (zabere 30ms !!!!!)
// PODMINKU NUTNO UPRAVIT
if(bit_test(_LCD1_UPDATE) && update_timer==0 && !bit_test(_ELBUG_BSY)) lcd1_update();
 
 
/////////////////
// pozadavek na zmenu informaci na lcd - 2.radek (max 2ms)
if(bit_test(_LCD2_UPDATE) && update_timer==0)
{
lcd2_update();
update_timer=0xFF; // ukonci okno,kdy je timer vyprseny
}
 
 
/////////////////
// periodicka mereni (max 3ms)
if(update_timer==0)
{
analog_inputs();
update_timer=0xFF; // ukonci okno,kdy je timer vyprseny
}
 
 
/////////////////
// stisknuta tlacitka
 
if(bit_test(_KEYS_VALID)) // stisknuto nejake tlacitko
{
// kratky stisk libovolneho tlacitka ukonci nastavovani
if(bit_test(_MNU) && !bit_test(_KEYS_LONG))
{
bit_clear(_MNU); // vypni nastavovani
enc_delta=0; // zahod nacitane zbyle impulzy korutitka
if(bit_test(_ELBUG_ON_TMP)) bit_set(_ELBUG_ON); // obnov zapnuti elbugu pokud byl zapnut
 
if(par_index!=PAR_ATTN) // stav attenuatoru se neuklada do eeprom
{
ee_adr=EE_ADDR[par_index];
if(par_index==PAR_POWER) ee_adr=ee_adr+band_index; // pro parametr vykonu urci adresu eeprom pro dane pasmo
if(read_eeprom(ee_adr)!=par[par_index]) // pokud doslo ke zmene parametru, aktualizuj ho v eeprom
{
write_eeprom(ee_adr,par[par_index]);
update_eeprom();
}
}
bit_set(_LCD1_UPDATE);
bit_set(_LCD2_UPDATE);
} else
{
// ktere tlacitko je stisknuto?
if(keys==KEY_SPLIT) // SPLIT/MNU
{
if(bit_test(_KEYS_LONG))
{
// dlouhy stisk - vstup do MENU
bit_set(_MNU2); // prvni stisk - vyber parametr
par_index=PAR_POWER;
bit_set(_LCD1_UPDATE);
bit_set(_LCD2_UPDATE);
} else
{
// kratky stisk - pokracovani v MENU
if(bit_test(_MNU2))
{
if(par_index==PAR_POWER)
{
// zapamatuj si , zda je elbug zapnut nebo vypnut
if(bit_test(_ELBUG_ON)) bit_set(_ELBUG_ON_TMP);
else bit_clear(_ELBUG_ON_TMP);
bit_clear(_ELBUG_ON); // pri nastavovani vykonu je elbug vypnut
}
bit_clear(_MNU2); // druhy stisk - prejdi do vybraneho parametru
bit_set(_MNU);
} else
{
// kratky stisk - funkce SPLIT
if(bit_test(_SPLIT)) bit_clear(_SPLIT);
else bit_set(_SPLIT);
}
bit_set(_LCD1_UPDATE);
}
} // KEY_SPLIT
 
// ostani tlacitka jsou aktivni jen kdyz nejsme ve vyberu parametru
if(!bit_test(_MNU2))
{
if(keys==KEY_RIT) // RIT/STEP
{
if(bit_test(_KEYS_LONG))
{
// dlouhy stisk - funkce STEP
if(step_index) step_index=0;
else step_index=1;
bit_set(_LCD1_UPDATE);
} else
{
// kratky stisk - funkce RIT
if(bit_test(_RIT))
{
bit_clear(_RIT);
freq_rit=0; // pri vypnuti RIT vynuluj
} else bit_set(_RIT);
bit_set(_DDS_UPDATE);
}
} // KEY_RIT
 
if(keys==KEY_CHNGVFO) // prepni VFO/srovnej VFO
{
if(bit_test(_KEYS_LONG))
{
// dlouhy stisk - funkce srovnej VFO
if(vfo_index) freq_vfo[0]=freq_vfo[1];
else freq_vfo[1]=freq_vfo[0];
} else
{
// kratky stisk - funkce prepni VFO
if(vfo_index) vfo_index=0;
else vfo_index=1;
bit_set(_DDS_UPDATE);
}
} // KEY_CHNGVFO
 
if(keys==KEY_ATTN) // ATTN/ELBUG
{
if(bit_test(_KEYS_LONG))
{
// dlouhy stisk - funkce ELBUG
par_index=PAR_KEYER;
bit_set(_MNU);
bit_set(_LCD1_UPDATE);
bit_set(_LCD2_UPDATE);
} else
{
// kratky stisk - funkce ATTN - mozne jen pokud se nevysila
par_index=PAR_ATTN;
bit_set(_MNU);
bit_set(_LCD1_UPDATE);
bit_set(_LCD2_UPDATE);
}
} // KEY_ATTN
}
}
bit_clear(_KEYS_VALID); // tlacitko zpracovano
bit_set(_KEYS_RELEASE); // budeme cekat na uvolneni tlacitek
}
 
} // hlavni smycka
#endif
}
// End of File
/Designs/HAM Constructions/HF_TRAMP/FW/V1_6/VFO.H
0,0 → 1,315
//**********************************************************************
// program pro rizeni TRXu - HLAVICKOVY SOUBOR
//**********************************************************************
// (c) OK1XGL 2005
 
 
#include <16F877.h>
#device ADC=8;
#fuses XT,NOWDT,NOPROTECT,BROWNOUT,NOLVP,NOCPD
#use delay (clock=4000000,restart_wdt)
 
 
// LCD display
#define LCD_RS PIN_D2 /* rizeni registru LCD displeje */
#define LCD_E PIN_D3 /* enable LCD displeje */
#define LCD_DATA_LSB PIN_D4 /* pripojeni LSB bitu datoveho portu LCD displeje (celkem 4 bity vzestupne za sebou) */
#define LCD_LED1 PIN_B5
#define LCD_LED2 PIN_B4
 
#define LCD_CHAR_a_FILL "\x80\x80\x0E\x01\x0F\x1F\x0F\x80" /* male a s s vyplnenym briskem */
#define LCD_CHAR_b_FILL "\x10\x10\x16\x1F\x1F\x1F\x1E\x80" /* male b s vyplnenym briskem */
#define LCD_CHAR_9_FILL "\x0E\x1F\x1F\x0F\x01\x02\x0C\x80" /* 9 s vyplnenym briskem */
 
// smimac polohy - ladeni
#define ENCODER_CLK PIN_B0 /* musi zde byt ,je od nej preruseni */
#define ENCODER_DIR PIN_B1
 
// tlacitka
#define KEY_ATN_KEY PIN_C7
#define KEY_SPLIT_MNU PIN_C4
#define KEY_A_B PIN_C5
#define KEY_RIT_STEP PIN_C6
#define KEYPORT PORTC
// masky pro jednotlive funkce na tlacitkach
#define KEY_MASK 0b11110000 /* maska pouzitych tlacitek */
#define KEY_LONG 100 /* doba, po, ktere je povazuje stisk tlacitka za dlouhy v jednotkach zakladniho tiku */
 
#define KEY_RIT 0b01000000 /* funkce RIT/STEP */
#define KEY_SPLIT 0b00010000 /* funkce SPLIT/MNU */
#define KEY_CHNGVFO 0b00100000 /* prepni VFO/srovnej VFO */
#define KEY_ATTN 0b10000000 /* nastav utlum/rychlost elbugu */
 
 
// tlg. klic
#define KEY_DASH PIN_B6
#define KEY_DOT PIN_B7
 
// ridici signaly TRXu
#define RXTX PIN_B2 /* prepinac prijem vysilani 1= vysilani*/
#define KEYING PIN_B3 /* klicovaci signal */
#define MUTE PIN_C3 /* uzavira NF cestu pri vysilani */
#define TONE PIN_C2 /* generovani tonu odposlechu NEMENIT!!! PWM1 je jen zde */
#define PWR_CTRL PIN_C1 /* vystup PWM2 pro rizeni vystupniho vykonu PA NEMENIT !!!*/
 
 
// DDS signaly
#define DDS_FSYNC PIN_D0 /* enable prenosu dat aktivni v log0 */
#define DDS_SCK PIN_D5 /* musi zde byt, hodiny sestupna hrana */
#define DDS_SDATA PIN_D4 /* musi zde byt, seriova data */
#define DDS_FSEL PIN_D1 /* prepnuti frekvencnich registru */
 
// rizeni attenuatoru
#define ATN1 PIN_E0
#define ATN2 PIN_C0
#define ATNC PIN_E1
#define RELE_PULSE 10 /* delka prepinaciho pulzu pro rele v ms jednotkach */
 
 
// analogove vsupni signaly
#define REF PIN_A1
#define FWD PIN_A0
#define MTR12V PIN_A2
#define SMTR PIN_A3
#define BAND PIN_A5
// cisla pouzitych kanalu
#define REF_CH 0
#define FWD_CH 1
#define MTR12V_CH 2
#define SMTR_CH 3
#define BND_CH 4
 
 
// konstanty verze programu
#define NAME "VERSION "
#define VERSION " V1.6 "
 
// konstanty timeru0
#define TICK_TIME 0xFFFF-(5000/128)+1 /* zakladni tik TMR0 bude 5ms */
#define UPDATE_TIME 10 /* doba, po ktere se muze updatovat kde co v jedntkach tick_time */
 
// konstanty timeru2
#define TONE_SET 0x4d /* konstanta urcujici kmitocet priposlechu, zde 800Hz */
 
// konstanty kmitoctu pro VFO
#define CONVERT_CONST 5.36870912 /* 2^28/50000000 , tedy 2^28/kmitocet hodin DDS*/
#define FREQ_IF 4999600L /* kmitocet mezifrekvence v Hz */
#define SUB_IF_INDEX 3 /* index pasma, od ktereho se mezifrekvencni kmitocet odecita */
// zakladni nastaveni ridiciho registru DDS
#define CTRL_FREQ0 0b0010000000000000 /* prepni se do freq0 */
#define CTRL_FREQ1 0b0010100000000000 /* prepni se do freq1 */
#define CTRL_RESET 0b0010000100000000 /* pozaduj reset */
#define CLR_PHASE0 0b1100000000000000 /* nuluj fazovy registr 0 */
#define CLR_PHASE1 0b1110000000000000 /* nuluj fazovy registr 1 */
 
#define ENC_HISTEREZE 10 /* necitlivost kroutitka pri nastavovani parametru v impulzech */
 
#define BAND_NUM 4 /* pocet pasem */
// tabulka meznich kmitoctu v Hz pro jednotliva pasma
int32 const BAND_LIMIT[BAND_NUM][2] = {
//{1800000,2000000},
{3500000,3620000},
{7000000,7045000},
{10100000,10150000},
{14000000,14120000}
//{18068000,18168000}
//{21000000,21450000}
};
 
 
int32 const START_FREQ[BAND_NUM] = {
//1810000,
3560000,
7030000,
10116000,
14060000,
//18096000,
//21060000
};
 
#define RIT_STEP 10 /* krok RITu v Hz */
signed int16 const RIT_LIMIT[2] = {-2000,2000}; /* rozsah RITu v Hz */
 
int16 const FREQ_STEP[2]={20,1000}; /* tabulka ladicich kroku v Hz */
 
// tabulka dekodovani pasma
#define BAND_ADC_MASK 0b11100000
int8 const BAND_ADC[BAND_NUM]= {
//0x00, /* 160m */
0x20, /* 80m */
0x40, /* 40m */
0x60, /* 30m */
0x80 /* 20m */
//0x82, /* 17m */
//0x84 /* 15m */
};
 
 
// hodnoty napeti z prevodniku odpovidajici prislusnym S stupnum
int8 const S_METER[9]= {
0xC7, /* S2 */
0xBA, /* S3 */
0xA8, /* S4 */
0x91, /* S5 */
0x82, /* S6 */
0x79, /* S7 */
0x73, /* S8 */
0x6C, /* S9 */
0x60 /* S9 + cca 10dB */
};
 
 
 
// priznaky v promenne flags
#define _DDS_UPDATE flags,0 /* pozadavek zmeny kmitoctu DDS */
#define _LCD1_UPDATE flags,1 /* pozadavek aktualizace udaje v 1.radku LCD */
#define _LCD2_UPDATE flags,2 /* pozadavek aktualizace udaje ve 2. radku LCD */
#define _PAR_UPDATE flags,3 /* pozadavek aktualizace vybraneho parametru */
#define _RIT flags,4 /* misto kmitoctu zobrazuj RIT */
#define _SPLIT flags,5 /* zapnut rezim SPRIT */
#define _TRANSMIT flags,6 /* je prepnuto na vysilani */
#define _LED_UPDATE flags,7 /* zrcadlo stavu LED */
#define _ENC_CHNG flags,8 /* doslo ke zmene polohy korutitka */
#define _TXDELAY flags,9 /* bezi spozdeni mezi stiskem klice a zaklicovanim vysilace */
#define _ATTN flags,10 /* je zapnuty utlum */
#define _MNU flags,11 /* rezim nastavovani hodnoty parametru */
#define _MNU2 flags,12 /* rezim vyberu parametru */
#define _RUN_VOX flags,13 /* bezi vox timer */
#define _BATT_LOW flags,14 /* baterie je vybita */
#define _KEYING flags,15 /* je zaklicovan vysilac */
 
// priznaky promenne keys_flags
#define _KEYS_LONG keys_flags,0 /* tlacitko stisknuto po dlouhou dobu */
#define _KEYS_VALID keys_flags,1 /* tlacitka jsou platna */
#define _KEYS_RELEASE keys_flags,2 /* cekej na uvolneni tlacitka = ukonceni reakce na tlacitko */
 
// priznaky promenne adc_flags
#define _ADC_START adc_flags,0 /* spust_prevod */
 
// priznaky promenne elbug_flags
#define _ELBUG_ON elbug_flags,0 /* klicovani bude rizeno elbugem */
#define _ELBUG_BSY elbug_flags,1 /* probiha generovani signalu _ELBUG */
#define _ELBUG_OUT elbug_flags,2 /* vystup z elbugu */
#define _ELBUG_SP elbug_flags,3 /* priste vysilej mezeru */
#define _ELBUG_DOT elbug_flags,4 /* byla stisknuta paka tecek */
#define _ELBUG_DASH elbug_flags,5 /* byla stisknuta paka carek */
#define _ELBUG_LAST elbug_flags,6 /* minula stisknuta paka 0=dot 1=dash */
#define _ELBUG_REV elbug_flags,7 /* reverzni chapani pak */
#define _ELBUG_REAL elbug_flags,8 /* zapnuto realne klicovani */
#define _ELBUG_ON_TMP elbug_flags,9 /* pro zapamatovani stavu _ELBUG_ON pri nastavovani vykonu */
 
// konstanta pro odmereni nejmensiho elementu elbugu (tecka nebo tez mezera)
#define ELBUG_CONST ((60*1000)/(5*5*2))*125 /* 60 - prevod na vteriny */
/* 1000 - prevod na ms */
/* 5 - prevod WPM na LPM */
/* 5 - pocet tecek v 1sec pro 200WPM */
/* 2 - zajima nas sirka tecky */
/* 125 - prevodni konstanta pro timer */
 
#define PAR_NUM 7 /* pocet parametru TRXu */
// cisla (indexy) parametru TRXu
// poradi urcuje poradi ve vyberovem menu
// parametry za volnym radkem v menu nejsou, vybiraji se na funkcnich tlacitkach
#define PAR_POWER 0 /* vykon vysilace */
#define PAR_VOX 1 /* doba prepnuti zpet na prijem */
#define INF_BATT 2 /* napeti baterie */
#define PAR_KEYER_REV 3 /* zap/vyp reverzni chapani pak */
#define PAR_KEYER_MODE 4 /* doplnkove nebo realne klicovani */
 
#define PAR_KEYER 5 /* rychlost elbugu */
#define PAR_ATTN 6 /* attenuator */
 
 
 
// tabulka mezi pro jednotlive parametry
int8 const PAR_LIMIT[PAR_NUM][2] = {
{0,16}, /* vykon ve 0.5w jednotkach */
{0,40}, /* meze pro vox v 50ms jednotkach */
{0,0}, /* hodnota napeti baterie */
{0,1}, /* meze pro zap/vyp reverzi pak */
{0,1}, /* mod klicovani */
{5,40}, /* meze pro elbug ve WPM */
{0,3} /* meze pro attenuator 0,-6,-12 a -18dB */
};
 
// adresy jednotlivych parametru ulozenych v eeprom
#define EE_ADR_POWER 0 /* BAND_NUM bajtu - pro kazde pasmo jeden bajt */
#define EE_ADR_VOX BAND_NUM
#define EE_ADR_BATT EE_ADR_VOX+1
#define EE_ADR_KEYER_REV EE_ADR_BATT+1
#define EE_ADR_KEYER_MODE EE_ADR_KEYER_REV+1
#define EE_ADR_KEYER EE_ADR_KEYER_MODE+1
#define EE_ADR_ATTN EE_ADR_KEYER+1
#define EE_ADR_CRC EE_ADR_ATTN+1 /* kontrolni soucet eeprom */
 
// pole adres parametru ulozenych v eeprom
int8 const EE_ADDR[PAR_NUM] = {
EE_ADR_POWER,
EE_ADR_VOX,
EE_ADR_BATT, // napeti baterie se neuklada, zde je zapsana konstantni hodnota
EE_ADR_KEYER_REV,
EE_ADR_KEYER_MODE,
EE_ADR_KEYER,
EE_ADR_ATTN
};
 
 
#define BATT_MIN 173 // napeti baterie, od ktere se povazuje za vybitou (hodnota z prevodniku pro 10.8V)
#define BAD_PSV 18 // od PSV > 1.8 se omezi vykon
#define PWR_LIM 10 // vykon pri spatnem psv je omezen na 1W
#define PWM_MIN 27 // minimalni hodnota pro PWM2
#define PWM_MAX 157 // maximalni hodnota pro PWM2
#define PWR_HIST_LO 2 // spodni povolena odchylka od pozadovaneho vykonu v nasobcich 100mW
#define PWR_HIST_HI 1 // horni povolena odchylka od pozadovaneho vykonu v nasobcich 100mW
#define PWR_FWD_CONST 5600 // prevodni konstatna pro prevod napeti z ADC na vykon
 
 
int8 lcd_pos; // poloha znaku na LCD pro specialni fce s nazvy xxx_lcd_putc
int32 freq_vfo[2]; // pozadovany kmitocet vfoA a vfoB
signed int16 freq_rit; // rozladeni +- pri prijmu
signed int8 enc_delta; // +-pocet impulzu zmeny kroutitka
 
int8 update_timer; // periodicky casovac pro aktualizaci kde ceho
int8 key_timer; // casovac pro rozpoznani dlouheho stisku tlacitka
int16 vox_timer; // casovac pro automaticke prepnuti na prijem po urcite dobe bez vysilani
int16 vox_time; // hodnota vox timeru, 0 = plny BK
int8 flash_timer; // pro blikani ledkou pri vybite baterii
 
int8 keys; // obsahuje tlacitka, ktera byla stisknuta (0=klidovy stav)
int8 keys_work; // pro precteni stavu tlacitek v preruseni
int8 keys_old; // predchozi stav tlacitek, pro osetreni zakmitu
int8 keyer; // obsahuje stav stisknutych pak elbugu
int8 keyerb; // obsahuje aktualni stav pak elbugu
 
int1 step_index; // index do tabulky moznych kroku ladeni
int1 vfo_index; // index do tabulky VFO
int8 band_index; // index do tabulky rozsahu kmitoctu
 
int16 flags; // stavove priznaky pro rizeni programu
int16 elbug_flags; // stavove priznaky pro rizeni elbugu
int8 keys_flags; // stavove priznaky tlacitek
int8 adc_flags; // stavove priznaky pro rizeni ADC
int8 par[PAR_NUM]; // parametry TRXu
int8 par_index; // cislo nastavovaneho parametru
 
int8 adc_ch; // citac kanalu ADC
int8 adc_val; // napeti z ADC aktualniho kanalu
int8 smtr_val; // hodnota napeti z ADC odpovidajici S-metru
int8 pwr_val; // hodnota aktualniho vykonu v 100mW jednotkach
int8 psv_val; // hodnota psv v desetinovych jednotkach
int8 fwd_val; // napeti z ADC odpovidajici doprednemu vykonu
int8 rev_val; // napeti z ADC odpovidajici odrazenemu vykonu
int8 bnd_val; // napeti z ADC odpovidajici pasmu
int8 batt_val; // napeti z ADC odpovidajici napeti baterie
int8 pwm_val; // hodnota pro PWM2 - rizeni vykony PA
int8 power; // pozadovany vykon PA
int16 elbug_dot_sp; // hotnota timeru 1 pro generovani tecky a mezery
int16 elbug_dash; // hordnota timeru1 pro generovani carky
 
 
#bit _T0IF = 0x0B.2 // priznak preteceni timeru0 - vyuziva se pri spousteni TXDELAY
// (vyuziva se pro nej prave timer0) aby byla jistota, ze se TXDELAY
// skutecne odmeri
 
#bit _TMR1IF = 0x0C.0 // priznak preruseni od timeru 1 - pro vyprovokovani preteceni (start elbugu)
// End of File
/Designs/HAM Constructions/HF_TRAMP/FW/V1_6/VFO.HEX
0,0 → 1,723
:1000000010308A0000280000FF00030E8301A100C9
:100010000A08A0008A010408A2007708A300780853
:10002000A4007908A5007A08A6007B08A70083131E
:1000300083128B1D1D280B1844280B1E21288B189A
:1000400047288C308400001C27280C184A288C3044
:100050008400801C2D288C184D288B1E31280B19EC
:100060005028220884002308F7002408F8002508F7
:10007000F9002608FA002708FB0020088A00210E54
:100080008300FF0E7F0E09008A110A12CC2A8A1102
:100090000A12D5298A110A12FB2A8A110A12A72AE2
:1000A0008A110A12EB290A108A100A118207E03419
:1000B000673435340034A0343C3437340034C03431
:1000C000CF346A34003488347F346B3400342034C5
:1000D0001D349A3400347034E0349A34003480345F
:1000E0009F34D534003440347434D73400340A108B
:1000F0008A100A1182074034523436340034F03406
:1001000044346B340034A0345B349A340034E0342B
:100110008934D63400340A108A100A118207143444
:100120000034E83403340A108A100A11820720349C
:100130004034603480340A108A100A118207003477
:1001400010340034283400340034003401340034D6
:10015000013405342834003403340A108A100A119B
:100160008207003404340534063407340834093473
:100170000A108A100A11820728340C34013406341C
:100180000A108A100A118207503441345234413423
:100190004D343A3400340A108A100A11820741346F
:1001A000543454344E343A3400340A108A100A114C
:1001B000820750344F345734453452343A34203463
:1001C000203400340A108A100A1182074B34453457
:1001D0005934453452343A342034203400340A102F
:1001E0008A100A118207443445344C34413459345E
:1001F0003A342034203400340A148A100A11820759
:1002000042344134543454344534523459343A34F9
:1002100000340A148A100A1182074D344F344434D2
:1002200045343A3400340A148A100A1182075234D1
:100230004534563445345234533445343A3400341A
:100240000A148A100A1182075234493454343A3459
:1002500000340A148A100A11820750344F3457347C
:100260004534523400340A148A100A118207443487
:1002700045344C344134593400340A148A100A117C
:10028000820742344134543454344534523459345E
:10029000203400340A148A100A1182074D344F3476
:1002A0004434453400340A148A100A118207523447
:1002B00045345634453452345334453420340034B4
:1002C0000A148A100A1182072D3425343234553429
:1002D0002034643442342034203400340A148A1028
:1002E0000A118207253430343234553457342034DF
:1002F00050345434543400340A148A100A118207DA
:10030000253434344C34553420346D347334203433
:10031000203400340A148A100A1182070D34433441
:100320004F344E344E344534433454340A3400345C
:100330000A148A100A1182072034463449344C3496
:1003400054344534523400340A148A100A11820796
:10035000803480340E3401340F341F340F34803431
:1003600000340A148A100A1182070E341F341F3415
:100370000F34013402340C34803400340A148A10EF
:100380000A118207563445345234533449344F34B9
:100390004E34203400340A148A100A1182072034A3
:1003A000563431342E343634003483163F108312E1
:1003B000861CDD2983163F148312441483163F1CC8
:1003C000E5298312B40AE72983168312B4038B103C
:1003D0008A110A123128D9308100481CF2291F15D0
:1003E0004810272A1F19F2291E08D200C41F012A0B
:1003F000510BFC295208D600D108031D012A5208CE
:10040000D7005108023C031D082A5208D900152ABA
:100410005108033C031D0F2A5208D300152A510826
:10042000043C031D152A5208D8005108033C031848
:100430001B2AD1011C2AD10A510DF700F70DF70D27
:10044000F830F7051F08C73977049F004814C41C0B
:10045000612A45182F2A0608FF3A8039BF00BF08D5
:100460000319342A451C382A451D4E2A451C4E2A9C
:100470008615601160088316870083120711C41265
:10048000C417D101510DF700F70DF70DF830F7053E
:100490001F08C73977049F004814602A86113A085C
:1004A000B8003908B700C4166015600883168700C5
:1004B000C0018312071D5F2A8316C00A8312C4136A
:1004C000C410350F662A0A30B500672AB503C41E6A
:1004D000782AB708031D6F2AB8080319742A370849
:1004E0000319B803B703782AC4120611431343143F
:1004F000B608031DB6030708FF3AF039BD003E08F1
:100500003D020319862A3D08BE00A32ABD0803192F
:10051000992ABC08031D912A3D08BC006430B6002E
:10052000982AB608031D982A4719982A4714C71411
:10053000A32AB60803199F2AC714B601A32A471D88
:10054000A32AC701BC010B118A110A123128BB0A68
:10055000431FB12AC31FAE2A8616AF2A861206127F
:10056000C32A441FB82ABB1FB82A86120612C32A00
:10057000C31FBD2A06168612C32A0612441DC22AAC
:100580008616C32A8612C31FC72AC313C82AC317D5
:100590008C108A110A1231280608FF3AC000451C47
:1005A000D42AC030C005D62A8030C005C418F72A26
:1005B0004518DF2AD93081000B11C414EF2AC51F5A
:1005C000E62A401B4516C01BC516EA2AC01B451665
:1005D000401BC516C518EF2AB53090000C14431BFC
:1005E000F72AC0080319F72A4317061543140B10FE
:1005F0008A110A123128C51D082BC51145115D0845
:100600008F005C088E00D93081000B11C414582B68
:10061000C51C252B451F0E2BC5120F2B4512060896
:10062000FF3AC039BF00C51F1A2B3F1B4516BF1B21
:10063000C5161E2BBF1B45163F1BC516461C252B7A
:10064000BF08031D252B4512C512431B2E2B451A2F
:100650002B2BC51E2E2B431706154314451E462B68
:10066000C51E402B451F3A2B45135D088F005C08C3
:100670008E003F2B45175F088F005E088E00452BCC
:1006800045135D088F005C088E00512BC51E4E2B54
:1006900045175F088F005E088E00512BC510900132
:1006A000582BC514C5154515D93081000B11C4143C
:1006B0000C108A110A1231287E30840000080319B8
:1006C000722B0130F800BF30F7006400F70B652B88
:1006D000F80B632B4A30F700F70B6C2B000064001B
:1006E000800B612B003408080F398316A600250EF5
:1006F000F700F030F7057708F039260483128800F8
:100700008815831688116400831288118316881156
:10071000831200348316A308031D922B8312081141
:10072000942B83168312081583160811A40E24082F
:10073000A500831273238316A40E2408A500831238
:10074000732364000C30F700F70BA42B00000000AB
:1007500000341430FE005C230F30831688058312AA
:1007600008118316081183128811831688118312C9
:10077000E6016608023C031CC72B0230FE005C2326
:1007800003308316A50083127323E60AB92B640095
:100790000C30F700F70BCA2B000000000230831664
:1007A000A5008312732364000C30F700F70BD62BDF
:1007B00000000000E6016608023C031CEF2B6608FF
:1007C000B820E7008316A301831267088316A400EC
:1007D00083128A230230FE005C23E60ADB2B8A1197
:1007E0000A160E2801308316A300831267088316A9
:1007F000A40083128A230034081010308316B0003E
:10080000AF1F062C83120816082C831683120812B9
:100810008812881603108316AE0DAF0DB00B002C96
:1008200083120814003401307E028316A1002008D0
:10083000023C031D1D2C4030A10721088038A20076
:10084000A3012208A40083128A2300347D080C3AF5
:100850000319342C063A03193E2C073A0319462C87
:10086000053A03194D2C542C8316A3010130A40022
:1008700083128A230230FE005C23622C0130FE00CA
:1008800002308316A00083121324622C0130FE0074
:100890008316A00083121324622C8316A301103048
:1008A000A40083128A23622C7D081F3C031C5A2C4F
:1008B0000730FD0501308316A3007D08A4008312D4
:1008C0008A23622C00342030F8001F08C7397804CE
:1008D0009F001430FE005C231F151F196D2C1E088D
:1008E000E039D8000430C2004208C203003A0319BC
:1008F000802C42089320F800580203199E2C742C77
:10090000E60166088A21E60AF700FD002624093080
:100910006602031D812CE60166089821E60AF700AD
:10092000FD00262407306602031D8C2C0230E600F1
:10093000FA30FE005C23E60B982C6C2C8A110A1608
:100940004929E901E8016808093C031CB32C68083F
:1009500003178D0083168C130C1483120C080313D9
:10096000E907E80AA32CE909E90A0A3003178D0010
:100970000313690803178C0083168C130C1583125C
:1009800003130B08F7008B138316031755308D00E4
:10099000AA308D008C148C18CB2C0C117708831284
:1009A00003138B040034E701E60166080A3C031CCC
:1009B000E52C660803178D0083168C130C14831224
:1009C0000C080313E707E60AD52CE7080319A92D3D
:1009D000E6016608033C031C0A2D6608E60AE800E7
:1009E00003178D008C0183168C130C1583120313CF
:1009F0000B08F7008B138316031755308D00AA30B0
:100A00008D008C148C18022D0C117708831203139F
:100A10008B04E92C083003178D0014308C008316EA
:100A20008C130C15831203130B08F7008B1383161A
:100A3000031755308D00AA308D008C148C181E2D94
:100A40000C117708831203138B04043003178D00F5
:100A500006308C0083168C130C15831203130B08BD
:100A6000F7008B138316031755308D00AA308D00C5
:100A70008C148C18392D0C117708831203138B04F6
:100A8000053003178D008C0183168C130C1583120F
:100A900003130B08F7008B138316031755308D00D3
:100AA000AA308D008C148C18532D0C1177088312EA
:100AB00003138B04063003178D008C0183168C13EF
:100AC0000C15831203130B08F7008B1383160317FF
:100AD00055308D00AA308D008C148C186D2D0C11A2
:100AE0007708831203138B04073003178D008C01E2
:100AF00083168C130C15831203130B08F7008B134A
:100B00008316031755308D00AA308D008C148C1875
:100B1000872D0C117708831203138B0409300317F8
:100B20008D008C0183168C130C15831203130B0894
:100B3000F7008B138316031755308D00AA308D00F4
:100B40008C148C18A12D0C117708831203138B04BD
:100B5000A1248A110A164C29F701F8017008031024
:100B60007118F707F70CF80CF118F707F70CF80CE9
:100B70007119F707F70CF80CF119F707F70CF80CD7
:100B8000711AF707F70CF80CF11AF707F70CF80CC5
:100B9000711BF707F70CF80CF11BF707F70CF80CB3
:100BA0000034F701F801F901FA018316A801A9013F
:100BB000AA01AB0127082604250424040319102EDA
:100BC0002030AC000310A00DA10DA20DA30DA80DA7
:100BD000A90DAA0DAB0D27082B02031DF92D260820
:100BE0002A02031DF92D25082902031DF92D2408C9
:100BF0002802031C0A2E2408A8022508031C250F1E
:100C0000A9022608031C260FAA022708031C270F87
:100C1000AB020314F70DF80DF90DFA0DAC0BE22D34
:100C20000000A8308400831200341030F700FA016D
:100C3000F601FD0CFC0C031C252E83162008FA0778
:100C40000318F60A2108F6078312F60CFA0CF90CC1
:100C5000F80CF70B192E00348316091083120910B3
:100C600060106008831687008312071083168910AE
:100C7000831289140A30FE005C23831689140A301B
:100C8000FE0083125C23831609148312601460082B
:100C90008316870083120034B630F700FA01F90199
:100CA000F80183162008210422042304031D5A2E70
:100CB000F701672E0310F81B662EA00DA10DA20DE3
:100CC000A30DFA0DF90DF80DF70B5A2EF813831238
:100CD0008A110A166B2B831624080319DC2EAC002C
:100CE00028080319DC2EAC0703187D2E7F30AC02D8
:100CF000031CDC2E0319DC2E812E8130AC07031877
:100D0000DC2E2C08F700F801F901FA012508B000E3
:100D1000B0172608AF002708AE001830AC00AD01B0
:100D20002E1CAA2E2B08FA07031C9C2EF90A031D61
:100D30009C2EF80A0319AD172A08F907031CA32EE5
:100D4000F80A0319AD172908A600A6172608F80700
:100D50000318AD17AD0DF80CF90CFA0CB00CAF0C74
:100D6000AE0C0310AC0B8F2E0130F7070318DC2EEE
:100D7000F81BC12EB00DFA0DF90DF80DF70303198C
:100D8000DC2EB01FD22EFA0A031DD22EF90A031D43
:100D9000D22EF80A031DD22EF80CF90CFA0CF70A21
:100DA0000319DC2E2508AD002908AD06AD1FDA2E8B
:100DB000F817E02EF813E02EF701F801F901FA0117
:100DC000000083128A110A16882B83162408B63C69
:100DD000A400FA012508A800A5170310A50CA60C6D
:100DE000A70CFA0CF90CF80CF70CA40BED2EA81FAD
:100DF000042FF709F809F909FA09F70A0319F80A9B
:100E00000319F90A0319FA0A83128A110A16952B93
:100E1000A90A2908023C031D102F2E30FD002624AC
:100E20007008FD00262400340408EF00690EF03835
:100E3000EB00EB07E23EEC00323EEE0069080F39B2
:100E4000EC07EC07EE07E93EED00ED07ED07680E55
:100E50000F39ED07EE07ED0DEE0DEE09EE0D68080A
:100E60000F39EE07EB0D0730EA000A30EE07ED030D
:100E7000031C362FED07EC03031C3A2FEC07EB03A2
:100E8000031C3E2FEB07EA03031C422F6A30840049
:100E900007306F0584076E30040203196B2F0008BA
:100EA000F700031D592F6F1A692FEF195B2F2030A0
:100EB0005C2F0830EF003030F707E9010408E80044
:100EC0007708EA007708F0000827680884006A08B5
:100ED000F700840A4B2F0008F7003030F707770837
:100EE000F00008278A150A126829A90A2908033C74
:100EF000031D8F2FC11C862FC31E822F1130FD00B2
:100F00002624852F6230FD0026248F2FC31E8C2FB0
:100F10001230FD0026248F2F6130FD002624290881
:100F2000063C031D9C2F411C992F3A30FD002624BE
:100F30009C2F2E30FD0026247C08FD002624003442
:100F40006F08F8016E020318A82F6E08F700B42F7F
:100F5000F7010830F000EE0DF70D6F087702031867
:100F6000F700F80DF00BAB2F0034A90A2908023C5A
:100F7000031DBD2F2E30FD0026246D08FD00262404
:100F800000345408633C0318CF2F3E30FD00262464
:100F90003130FD0026243030FD002624D72FA90152
:100FA0005408EB000130EC008A15F5218A11573006
:100FB000FD0026242030FD0026245508633C03183C
:100FC000EB2F3E30FD0026243130FD00262430304A
:100FD000FD002624F32FA9015508EB000130EC0099
:080FE0008A15F5218A11003485
:101000000408F100F01F14282D30FC008A11752708
:101010008A15ED09EE09EF09F009ED0A0319EE0A48
:101020000319EF0A0319F00A3B30F6009A30F50075
:10103000CA30F400F3010A30F20070088316A300EE
:1010400083126F088316A20083126E088316A10014
:1010500083126D088316A0007608A7007508A60005
:101060007408A5007308A4008A118312D1258A157B
:101070000008ED00840A0008EE00840A0008EF0072
:10108000840A0008F000FD308407F708031D5A2881
:101090007208013A03195A28710803195B280F399D
:1010A00072020319552803186228F030711B0030B2
:1010B000F7005B28F1013030F7077708FC008A1150
:1010C00075278A1576088316A3007508A200740890
:1010D000A1007308A000A701A601A5010A30A40081
:1010E0008A118312D1258A157A08F6007908F5004D
:1010F0007808F4007708F300F20B1D288A150A120D
:101100008C290130FE008316A0008A11831213245B
:101110008A15C310441EA528E80168088A11C0205A
:101120008A15E80AF700FD008A1126248A15063080
:101130006802031D8D280330E9002030FD008A116C
:1011400026248A15E90B9D288C29C41D30295008B6
:10115000F93E03182F29073E8F29E80168088A11F4
:10116000CB208A15E80AF700FD008A1126248A158B
:1011700005306802031DAE280330E9002030FD0071
:101180008A1126248A15E90BBE282F29E801680850
:101190008A11D5208A15E80AF700FD008A11262455
:1011A0008A1508306802031DC7282F29E80168083E
:1011B0008A11E2208A15E80AF700FD008A11262428
:1011C0008A1508306802031DD7282F29E80168080E
:1011D0008A11EF208A15E80AF700FD008A112624FB
:1011E0008A1508306802031DE7282F29E8016808DE
:1011F0008A11FC208A15E80AF700FD008A112624CE
:101200008A1508306802031DF7282F29E8016808AD
:101210008A1109218A15E80AF700FD008A1126249F
:101220008A1505306802031D07290330E9002030C4
:10123000FD008A1126248A15E90B17292F29E801B8
:1012400068088A1113218A15E80AF700FD008A113F
:1012500026248A1508306802031D20292F298C298D
:10126000431E6A29E80168088A1120218A15E80AC4
:10127000F700FD008A1126248A1504306802031D38
:101280003329B31F49292B30FD008A1126248A15E2
:101290004E292D30FD008A1126248A153308FA00C4
:1012A0003208B31F5C293208003CF700FA0133080A
:1012B000031C330FFA027708E6007A08E700A90159
:1012C000093084006708E9006608E8008A11142FD5
:1012D0008A158C29A9010030C1180130F700F70DDB
:1012E000F70DFC30F70577082A3E84000008E90076
:1012F000840A0008EA00840A0008EB00840A000857
:10130000EC00083084006C08F0006B08EF006A08FD
:10131000EE006908ED0000288A110A169B2E0A14B7
:101320008A100A118207C628E628F6281F290629EE
:10133000D628AD286D13ED126C08EE006430EF0076
:101340008A11A0278A157708EC007808031DC829A0
:10135000ED1AC829ED19DA296D1BB4296D18B429C5
:101360006D19B429ED1BDA296D1CC029ED1BDA2992
:101370006D1BC0296D18DA296D19C029ED1BDA29FA
:1013800020306D1E3030FD008A1126248A15DA299E
:10139000ED16ED1FD42978088000F8002D30FD00EF
:1013A0008A1126248A15ED1330307807FD008A1142
:1013B00026248A156D1BE7296C08EE000A30EF0021
:1013C0008A11A0278A157708EC006D17A529ED1F53
:1013D000EE292D30FD008A1126248A1530306C0745
:1013E000FD008A1126248A1500346C13EC126B0858
:1013F000EE006430EF008A11A0278A157708EB0011
:101400007808031D232AEC1A232AEC19352A6C1BB1
:101410000F2A6C180F2A6C190F2AEC1B352A6C1C2A
:101420001B2AEC1B352A6C1B1B2A6C18352A6C19DD
:101430001B2AEC1B352A20306C1E3030ED008A113F
:10144000B5278A15352AEC16EC1F2F2A780880005C
:10145000F8002D30ED008A11B5278A15EC133030D5
:101460007807ED008A11B5278A156C1B422A6B0894
:10147000EE000A30EF008A11A0278A157708EB00EA
:101480006C17002AEC1F492A2D30ED008A11B52770
:101490008A1530306B07ED008A11B5278A150034A4
:1014A0000408F2006C0EF038EE00EE07E23EEF00AA
:1014B000323EF1006C080F39EF07EF07F107E93E04
:1014C000F000F007F0076B0E0F39F007F107F00D91
:1014D000F10DF109F10D6B080F39F107EE0D073031
:1014E000ED000A30F107F003031C722AF007EF0346
:1014F000031C762AEF07EE03031C7A2AEE07ED039E
:10150000031C7E2A6D308400073072058407713019
:1015100004020319A92A0008F700031D952A721A6C
:10152000A72AF219972A2030982A0830F200303082
:10153000F707EC010408EB007708ED007708FD00E1
:101540008A1126248A156B0884006D08F700840A26
:10155000872A0008F7003030F7077708FD008A1166
:1015600026248A158A150A12252CA90A2908033C63
:10157000031DBF2A2E30FD008A1126248A156D080E
:10158000FD008A1126248A1500346C13EC126B08B6
:10159000EE006430EF008A11A0278A157708EB006F
:1015A0007808031DF12AEC1AF12AEC19FF2A6C1BAA
:1015B000DF2A6C18DF2A6C19DF2AEC1BFF2A6C1C4F
:1015C000EB2AEC1BFF2A6C1BEB2A6C18FF2A6C1908
:1015D000EB2AEC1BFF2A20306C1E3030ED00B522C8
:1015E000FF2AEC16EC1FFB2A78088000F8002D304B
:1015F000ED00B522EC1330307807ED00B5226C1BFE
:101600000C2B6B08EE000A30EF008A11A0278A1518
:101610007708EB006C17D02AEC1F112B2D30ED0052
:10162000B52230306B07ED00B5228A150A12562C10
:1016300043110130FE0002308316A0008A1183128C
:1016400013248A15441E962B5008FB3E0318952B35
:10165000053E402DEB016B088A1129218A15EB0A02
:10166000F700FD008A1126248A1505306B02031D40
:101670002B2B0330EC002030FD008A1126248A1524
:10168000EC0B3B2B952BEB016B088A1133218A1550
:10169000EB0AF700FD008A1126248A1505306B023B
:1016A000031D442B0330EC002030FD008A1126245A
:1016B0008A15EC0B542B952BEB016B088A113D21FD
:1016C0008A15EB0AF700FD008A1126248A150830D6
:1016D0006B02031D5D2B952BEB016B088A114A21D0
:1016E0008A15EB0AF700FD008A1126248A150430BA
:1016F0006B02031D6D2B0430EC002030FD008A11BD
:1017000026248A15EC0B7D2B952BEB016B088A1197
:1017100053218A15EB0AF700FD008A1126248A1549
:1017200008306B02031D862B952B3D2DC41DB32C59
:101730005008F93E0318B22C073E492D4F08F0001F
:101740000630F1008A11AC258A157808EB002D309F
:10175000FD008A1126248A156B08EC001130ED007B
:101760009A210430EC006C088A1160218A15EC0A79
:10177000F700FD008A1126248A1509306C02031D2A
:10178000B32BB22C431BDB2BA9015B08EB00013010
:10179000EC00F5210430EB006B088A116E218A15EC
:1017A000EB0AF700ED008A11B5278A1509306B02A4
:1017B000031DCC2BDE2B8A11C1278A15B22C4E08B3
:1017C000053C031CFC2B4F30FD008A1126248A1592
:1017D0004630FD008A1126248A154630FD008A1104
:1017E00026248A150530EB002030FD008A112624BE
:1017F0008A15EB0BF42B0A2C4E08EC001130ED008F
:101800009A210630EB002030FD008A1126248A152B
:10181000EB0B032CB22CE8014A08E7006808FD0036
:101820006708FC008316A1013230A0008A118312E0
:1018300015268A157908E8007808E7000130840049
:101840006808EC006708EB00502A0430EB006B08D6
:101850008A117C218A15EB0AF700FD008A112624E3
:101860008A1509306B02031D272CB22CEA01590896
:10187000E9006A08FD006908FC008316A1010A302E
:10188000A0008A11831215268A15790CEA00780CBB
:10189000E900EA0CE90CEA0CE90CEA0CE90C0F305F
:1018A000EA05A9016908EB00EC01C52A5630ED00F4
:1018B000B5220430EB002030ED00B522EB0B5B2CA1
:1018C000B22CCD080319732C4230FD008A11262456
:1018D0008A150730EB002030FD008A1126248A1576
:1018E000EB0B6B2C812C4130FD008A1126248A15CC
:1018F0000730EB002030FD008A1126248A15EB0BFF
:101900007A2CB22CCC0803199E2C5930FD008A1178
:1019100026248A154530FD008A1126248A15533065
:10192000FD008A1126248A150530EB002030FD00C9
:101930008A1126248A15EB0B962CB12C4E30FD0013
:101940008A1126248A154F30FD008A1126248A1513
:101950000630EB002030FD008A1126248A15EB0B9F
:10196000AA2CB22C3D2D431FB92C8A11C1278A15F0
:101970003D2DC5183D2D5308C73C031CC52C3230E6
:10198000FD008A1126248A15CA2C2030FD008A11F8
:1019900026248A155308BA3C031CD42C3330FD008E
:1019A0008A1126248A15D92C2030FD008A1126247C
:1019B0008A155308A83C031CE32C3430FD008A111F
:1019C00026248A15E82C2030FD008A1126248A1549
:1019D0005308913C031CF22C3530FD008A1126245B
:1019E0008A15F72C2030FD008A1126248A15530809
:1019F000823C031C012D3630FD008A1126248A15F5
:101A0000062D2030FD008A1126248A155308793CC2
:101A1000031C102D3730FD008A1126248A15152D40
:101A20002030FD008A1126248A155308733C031CBC
:101A30001F2D3830FD008A1126248A15242D2030D0
:101A4000FD008A1126248A155308603C031C2E2DA4
:101A50001330FD008A1126248A153D2D53086C3C55
:101A6000031C382D3930FD008A1126248A153D2D9E
:101A70002030FD008A1126248A158A110A16A52E07
:101A80000A148A100A1582072A2B432B5C2B852BFC
:101A90006C2B0A148A100A158207C22B0B2C362CC9
:101AA000822C612CDF2B9E2B20308316AC00A801EA
:101AB000A901AA01AB012308FA002208F9002108B4
:101AC000F8002008F7000310771C742D2408A807DD
:101AD00025080318250FA90726080318260FAA07AB
:101AE00027080318270FAB07AB0CAA0CA90CA80CEE
:101AF000FA0CF90CF80CF70CAC0B632D83128A1559
:101B00000A12E42DF801F901F701FA018316210800
:101B1000031D8D2D20080319A72D1030FE00031082
:101B2000FC0DFD0DF70DFA0D21087A02031D9A2D0B
:101B300020087702031CA32D2008F702031CFA03D8
:101B40002108FA020314F80DF90DFE0B8F2D000089
:101B5000831200345808E039F50042088A119320B6
:101B60008A15F80075020319B72D8A01002805307F
:101B70005907AD3C03184417431F072FEB01EA0137
:101B8000E9015608E8006B088316A30083126A086F
:101B90008316A200831269088316A10083126808C5
:101BA0008316A00083126B088316A70083126A08AD
:101BB0008316A600831269088316A500831268089D
:101BC0008316A4008312542D7A08EB007908EA00EA
:101BD0007808E9007708E800680DEC00690DED0071
:101BE0006A0DEE006B0DEF00EC0DED0DEE0DEF0D3F
:101BF000EC0DED0DEE0DEF0DF830EC056808EC077F
:101C000069080318690FED076A0803186A0FEE07E1
:101C10006B0803186B0FEF076808EC0769080318D7
:101C2000690FED076A0803186A0FEE076B080318BF
:101C30006B0FEF076F088316A30083126E088316DD
:101C4000A20083126D088316A10083126C0883160C
:101C5000A000A701A6011530A500E030A4008A115C
:101C60008312D1258A157708D400D708031D3B2E8F
:101C70000A30D500A72EF1015608F000F00DF10D45
:101C8000F00DF10DF00DF10DF00DF10DF030F0054E
:101C90007108FD007008FC008316A101831257082B
:101CA0008316A000831282257908E7007808E600F1
:101CB000E708031D622E6608103C031C622EFA30F2
:101CC000D500A72E6708003C0318702EFF3A031DAD
:101CD0006D2E6608513C0318702E0A30D500A72ED1
:101CE00010306607F0006708F1000318F10A700D64
:101CF000F200710DF300F20DF30DF20DF30DF8305B
:101D0000F2057008F2070318F30A7108F307700868
:101D1000F2070318F30A7108F30710306602F700A0
:101D20006708FA000030031C0130FA027708F5005A
:101D30007A08F6007308FD007208FC007A08831622
:101D4000A1007708A000831282257808D5005508E5
:101D5000123C0318AF2E54080A3CF400B22E54086B
:101D60005B02F4007408803A7E3C031CDC2E5A08A7
:101D70001B3C0318DC2E7408803A753C031CC32EF0
:101D80000430DA02C42EDA03F1015A08F00003101D
:101D9000700DF500710DF600F60CF50CF60CF50C57
:101DA000F60C75089B00F60C760C3039F7001D0810
:101DB000CF3977049D00072FF41B072F7408023CCE
:101DC0000318072F5A089C3C031C072FF41BEF2E07
:101DD00074080A3C0318EF2E0430DA07F02EDA0AF2
:101DE000F1015A08F0000310700DF500710DF600B6
:101DF000F60CF50CF60CF50CF60C75089B00F60CC1
:101E0000760C3039F7001D08CF3977049D00610842
:101E1000043C03180E2F4315E1010F2FE10A8A112C
:041E20000A16AF2EC1
:1020000084011F30830583161F149F141F159F1111
:10201000FF308312E000E1010A12A92B0A16831691
:10202000A3015030A4000A1283128A230A16023038
:10203000FE000A125C230A16E60166080A12A421B1
:102040000A16E60AF700E7000A12F2230A16083019
:102050006602031D1D288316A3010330A4000A1283
:1020600083128A230A160230FE000A125C230A1623
:102070008316A3014830A4000A1283128A230A1689
:102080000230FE000A125C230A161030E7000A1222
:10209000F2230A161030E7000A12F2230A1616304D
:1020A000E7000A12F2230A160330E6001F30E700A9
:1020B0000A12F2230A16E60B56281E30E7000A120F
:1020C000F2230A168030E7000A12F2230A1683165A
:1020D000A3010330A4000A1283128A230A160230D5
:1020E000FE000A125C230A168316A3015830A400CE
:1020F0000A1283128A230A160230FE000A125C2397
:102100000A16E60166080A12B1210A16E60AF70065
:10211000E7000A12F2230A1608306602031D82281D
:102120008316A3010330A4000A1283128A230A161D
:102130000230FE000A125C230A168316811308106F
:102140008312081483160812831208128316881249
:1021500083128816831606118312061183168611C0
:1021600083128611831606128312061283168612B4
:102170008312861260156008831687008312E010B0
:102180006008831687008312871083160910831254
:1021900009106010600883168700831207108316E9
:1021A00089108312891021308316AF00AE010A1204
:1021B0008312FC230A16C0308316AF00AE010A1248
:1021C0008312FC230A16E0308316AF00AE010A1218
:1021D0008312FC230A160A30B500C401C301C601EC
:1021E000C501C701C801D1011B30DA00B401BC012F
:1021F000B301B2010130FE008316A0000A1283125F
:1022000013240A16E60166080A12BE210A16E60A17
:10221000F700FD000A1226240A1608306602031D84
:1022200003290130FE0002308316A0000A12831237
:1022300013240A16E60166080A12CB210A16E60ADA
:10224000F700FD000A1226240A1605306602031D57
:102250001B290330E7002030FD000A1226240A164D
:10226000E70B2B290430E600FA30FE000A125C234B
:102270000A16E60B34291F179F1383169F13831228
:102280001F1483161F109F141F119F110A1283120F
:10229000632C0A160A12D32C0A16420803178D0063
:1022A00083168C130C1483120C080313C9004908FD
:1022B000F0000530F1000A12AC250A167808DB00A0
:1022C000083003178D0083168C130C1483120C082E
:1022D0000313CE004E08053C031C7129C601C5013D
:1022E0009C2945148316A3010230A2004930A100A5
:1022F000F030A000A701A601A50183124E088316A5
:10230000A4000A128312D1250A167708DC00DC0922
:102310007808DD00DD09DC0A0319DD0A03105C0D15
:10232000E6005D0DE7005C086607DE006708DF0079
:102330000318DF0A5D08DF07043003178D008316DA
:102340008C130C1483120C080313CA00BA014A0838
:10235000B900B908031DAF29BA080319C0293A0802
:10236000FD003908FC008316A1011430A0000A12F8
:10237000831215260A167908BA007808B900C3290D
:10238000BA010230B900063003178D0083168C1392
:102390000C1483120C080313CC00CC080319D229A7
:1023A000C517D329C513063003178D0083168C1368
:1023B0000C1483120C080313CC004610CF010A1230
:1023C0002C260A16420DF700F70DFC30F7057708AA
:1023D000E6000330E60766080A1277200A16FA00BC
:1023E000E60366080A1277200A16F900E603660873
:1023F0000A1277200A16F80066030A1277200A16D6
:10240000F7007A08AD007908AC007808AB007708CF
:10241000AA00420DF700F70DFC30F7057708E6003B
:102420000330E60766080A1277200A16FA00E60368
:1024300066080A1277200A16F900E60366080A12EF
:1024400077200A16F80066030A1277200A16F700AA
:102450007A08B1007908B0007808AF007708AE00BC
:1024600043144110C11083160108C0390638810099
:10247000D930831281001830F800063892004D30B0
:1024800083169200831260116008831687008312FE
:1024900007110C30970027309500601560088316EF
:1024A0008700C0018312071D582A8316C00A8312B1
:1024B000E010600883168700831287100C309D009F
:1024C00006309B001D08CF3930389D00900106086A
:1024D000FF3AC039BF003F1B45100B168B16831601
:1024E0008C140C1483128B15C0308B04431CDD2B11
:1024F000431B1C2B4208023C0318B42A0030C118AD
:102500000130F700F70DF70DFC30F70577082A3E8C
:10251000840000088316A100840A0008A200840A2F
:102520000008A300840A0008A400FD308407B0302E
:1025300021028312E600831622088312E700493045
:10254000031C4A30E702831623088312E8004C304C
:10255000031C4D30E802831624088312E900003082
:10256000031C0130E902E92A0030C1180130F700EC
:10257000F70DF70DFC30F70577082A3E84000008B8
:102580008316A100840A0008A200840A0008A300A0
:10259000840A0008A400FD308407B03021078312AC
:1025A000E600831622088312E700493003184A30F8
:1025B000E707831623088312E8004C3003184D30D8
:1025C000E807831624088312E9000030031801305D
:1025D000E907431E1A2B3208F7003308F800F90107
:1025E000FA01B31FF52AF903FA037A08F100790812
:1025F000F0007808EF007708EE006E086607F70035
:102600006708F8006F0803186F0FF8076808F900EB
:1026100070080318700FF9076908FA0071080318A9
:10262000710FFA077A08E9007908E8007808E700EE
:102630007708E600C314592BC31E3C2B0030C11C85
:102640000130F700F70DF70DFC30F70577082A3E4B
:1026500084000008F700840A0008F800840A0008D3
:10266000F900840A0008FA00E9007908E80078080F
:10267000E7007708E600592B0030C1180130F70059
:10268000F70DF70DFC30F70577082A3E84000008A7
:10269000F700840A0008F800840A0008F900840A98
:1026A0000008FA00E9007908E8007808E7007708F0
:1026B000E60069088316A300831268088316A20047
:1026C000831267088316A100831266088316A00090
:1026D0000A1283124C2E0A1677088316A000780877
:1026E000A1007908A2007A08A3002308A700220805
:1026F000A6002108A5002008A4007730AB00CC304C
:10270000AA002B30A9008130A8000A1283126B2E78
:102710000A167A088316A7007908A6007808A5008B
:102720007708A4000A128312E52E0A167A08831687
:10273000A7007908A6007808A5007708A400270854
:10274000AB002608AA002508A9002408A80020300C
:10275000AF00AE010A128312FC230A168316290861
:10276000AD002808AC002D17AD132D08AF002C08C4
:10277000AE000A128312FC230A168316280DAF003E
:10278000290DB0002A0DB1002B0DB200AF0DB00D18
:10279000B10DB20DFC30AF05F901FA013208AD0000
:1027A0003108AC002D17AD132D08AF002C08AE007A
:1027B0000A128312FC230A164310441C812DC419EB
:1027C000E32B441E302CB41BE92B3408093C031CBA
:1027D000EE2B3408803A763C031C812DB41B122C5E
:1027E0003408003C0318122C441EFD2B5008033CF7
:1027F000031CFC2BD00A4315112C493050078400D0
:102800000008F0000310500D013E0A129B200A162A
:10281000F80070020318112C493050078400800A18
:10282000C3152E2C441E1A2CD0080319192CD003C2
:1028300043152E2C4930500784000008F000031087
:10284000500D0A129B200A16F8007008780203182F
:102850002E2C4930500784008003C315B401802D0D
:10286000431E742C3408F0000A30F1000A12AC2523
:102870000A167808FA01F700F71BFA03EE007A0847
:10288000EF00B4016E083207F0003308F1000318BE
:10289000F10A6F08F107F11B572C7108073C031C64
:1028A000732C031D572C7008D03C031C732C6E082E
:1028B0003207F2003308F3000318F30A6F08F30736
:1028C000F31F6D2C7308F73C0318732CFF3A031D9C
:1028D0006D2C72082F3C0318732C6E08B207031876
:1028E000B30A6F08B3077F2DF3013408F200B41B5D
:1028F000F303003041180130F7000310F70D77089B
:10290000F100770A0A128B200A16FA0071080A12DF
:102910008B200A16F4007A08F5007308FD0072088F
:10292000FC007A088316A1007408A0000A12831222
:1029300015260A167908FA007808F7007908F800D1
:10294000F901FA01F81FA62CF903FA037A08ED0041
:102950007908EC007808EB007708EA00B401003051
:10296000C1180130F700F70DF70DFC30F7057708B7
:102970002A3E84000008F100840A0008F200840A5C
:102980000008F300840A0008F4006A087107F700E1
:102990007208F8006B0803186B0FF8077308F9004A
:1029A0006C0803186C0FF9077408FA006D08031817
:1029B0006D0FFA077A08E9007908E8007808E7005F
:1029C0007708E600420DF700F70DF70DF830F70530
:1029D0007708043EF1000330F10771080A12532012
:1029E0000A16FA00F10371080A1253200A16F900B8
:1029F000F10371080A1253200A16F80071030A1233
:102A000053200A16F70069087A02031C7F2D031D64
:102A1000192D68087902031C7F2D031D192D6708E5
:102A20007802031C7F2D031D192D66087702031CF5
:102A30007F2D420DF700F70DF70DF830F7057708F9
:102A4000F3000330F30773080A1253200A16FA0042
:102A5000F30373080A1253200A16F900F3037308EC
:102A60000A1253200A16F80073030A1253200A169A
:102A7000F7007A086902031C7F2D031D4F2D79088A
:102A80006802031C7F2D031D4F2D78086702031C6D
:102A90007F2D031D4F2D77086602031C7F2D00300C
:102AA000C1180130F700F70DF70DFC30F705770876
:102AB0002A3E84006A080007F700840A0008F8002C
:102AC0006B0803186B0FF807840A0008F9006C08FC
:102AD00003186C0FF907840A0008FA006D08031840
:102AE0006D0FFA07FD30840777088000840A7808A4
:102AF0008000840A79088000840A7A0880004314E0
:102B00004410C31D912EC3115008063A0319982D85
:102B1000063A03192E2E053A0319382E043A0319E2
:102B20006A2E023A0319882E073A03198F2E902E27
:102B300044154F08013A0319A42D033A0319D32D64
:102B4000013A0319022E262E831609108312091446
:102B500083168910831289100A30FE000A125C2342
:102B60000A16831689148312601060088316870082
:102B70008312071083168910831289140A30FE000D
:102B80000A125C230A16831689140A30FE000A1200
:102B900083125C230A1683160914831260146008DA
:102BA000831687002C2E83160910831209108316B2
:102BB0008910831289140A30FE000A125C230A1657
:102BC00083168914831260106008831687008312AD
:102BD000071483168910831289100A30FE000A1226
:102BE0005C230A16831689140A30FE000A12831227
:102BF0005C230A1683160914831260146008831676
:102C000087002C2E831609108312091460106008A7
:102C10008316870083120714831689108312891084
:102C20000A30FE000A125C230A16831689140A3041
:102C3000FE000A1283125C230A16831609148312FB
:102C400060146008831687002C2E83120A122C262B
:102C50000A16441183162C2E8312902E4908F00078
:102C60000530F1000A12AC250A167808DB00902E18
:102C70004E08053C031C3E2E4510692E4514831654
:102C8000A3010230A2004930A100F030A000A7014A
:102C9000A601A50183124E088316A4000A1283120E
:102CA000D1250A167708DC00DC097808DD00DD098B
:102CB000DC0A0319DD0A03105C0DE6005D0DE70078
:102CC0005C086607DE006708DF000318DF0A5D089E
:102CD000DF07902EBA014A08B900B908031D732E08
:102CE000BA080319842E3A08FD003908FC0083163F
:102CF000A1010A30A0000A12831215260A167908CB
:102D0000BA007808B900872EBA010130B900902EB8
:102D1000CC0803198D2EC5178E2EC513902E902E1C
:102D20004315C31C9D2EB508031D9D2EC5189D2E51
:102D30000A128A1581280A168A11431DA92EB50880
:102D4000031DA92E0A128A15182B0A168A11FF30A4
:102D5000B500B508031DB32E0A128A15AA2D0A164E
:102D60008A11FF30B500C71C6E2FC41D052F4718F0
:102D7000052FC411B401C61845145008063C0319A8
:102D8000022F50080A12AD200A16F800E200D008FF
:102D9000031DCC2E4208E207620803178D0083163C
:102DA0008C130C1483120C080313E60049305007EF
:102DB0008400000866020319022F4930500784007E
:102DC0000008E600620803178D0003136608031766
:102DD0008C0083168C130C15831203130B08F70059
:102DE0008B138316031755308D00AA308D008C1479
:102DF0008C18F82E0C117708831203138B040A1217
:102E0000A1240A16C31443156C2F3C08103C031D63
:102E1000242F471C102F4416D001C3144315242F10
:102E2000441E1E2FD008031D1B2F451C192FC6142E
:102E30001A2FC61045104412C415232FC31E222F6B
:102E4000C312232FC316C314441A6C2F3C08403CF2
:102E5000031D3B2F471C332F411C302F4110312FB6
:102E60004114C3143B2F431E392F4312B301B20147
:102E70003A2F431643143C08203C031D5B2F471C8C
:102E8000552FC11C4C2F3108AD003008AC002F0865
:102E9000AB002E08AA00542F2D08B1002C08B0005A
:102EA0002B08AF002A08AE005B2FC11C592FC110A0
:102EB0005A2FC11443143C08803C031D6C2F471C3F
:102EC000672F0530D000C415C31443156C2F06308E
:102ED000D000C415C3144315C7104715762A6300E4
:02400E00793FF8
:00000001FF
;PIC16F877