| Line No. | Rev | Author | Line |
|---|---|---|---|
| 1 | 3 | kaklik | // HFV - High Frequency Voltmeter - Firmware |
| 2 | // (c)miho 2002 |
||
| 3 | // |
||
| 4 | // Historie: |
||
| 5 | // |
||
| 6 | // 0.00 Uvodni verze |
||
| 7 | |||
| 8 | #define VERSION "0.00" |
||
| 9 | |||
| 10 | |||
| 11 | // Zakladni nastaveni prekladace |
||
| 12 | // |
||
| 13 | #include <16F876.h> |
||
| 14 | #device ADC=10 |
||
| 15 | #use delay(clock=4000000) |
||
| 16 | #fuses XT,NOWDT,NOBROWNOUT,NOLVP |
||
| 17 | #case |
||
| 18 | |||
| 19 | |||
| 20 | // Matematicka knihovna |
||
| 21 | // |
||
| 22 | #include "MATHA.C" |
||
| 23 | |||
| 24 | |||
| 25 | // Knihovna pro LCD display |
||
| 26 | // |
||
| 27 | #define LCD_RS PIN_B2 // rizeni registru LCD displeje |
||
| 28 | #define LCD_E PIN_B1 // enable LCD displeje |
||
| 29 | #define LCD_DATA_LSB PIN_C2 // pripojeni LSB bitu datoveho portu LCD displeje (celkem 4 bity vzestupne za sebou) |
||
| 30 | #include "LCD.C" |
||
| 31 | |||
| 32 | |||
| 33 | // Knihovna pro obsluhu tlacitek |
||
| 34 | // |
||
| 35 | #include "KBD_B4.C" |
||
| 36 | |||
| 37 | |||
| 38 | // Knihovna pro pristup do pameti EEPROM |
||
| 39 | // |
||
| 40 | #include <EEPROM.C> |
||
| 41 | |||
| 42 | |||
| 43 | // Casova smycka pro zakladni cyklus obsluhy |
||
| 44 | // |
||
| 45 | // Predpoklada pripojeni krystalu 32768Hz na TIMER1, slouzi pro definovani delky intervalu |
||
| 46 | // spanku. |
||
| 47 | // |
||
| 48 | |||
| 49 | #define IPS 64 // pocet preruseni za sekundu od casovace 1 |
||
| 50 | #define TIMERXTAL 32768 // frekvence krystalu casovace 1 |
||
| 51 | |||
| 52 | BOOLEAN Timer1; // semafor nastavovany pri vstupu do preruseni od casovace 1 |
||
| 53 | |||
| 54 | long int TimerCounter; // pomocna promenna pro odmerovani spozdeni |
||
| 55 | |||
| 56 | #int_timer1 |
||
| 57 | void IntTimer1() |
||
| 58 | { |
||
| 59 | Timer1=TRUE; // bylo peruseni od timeru 1 |
||
| 60 | |||
| 61 | if (TimerCounter>0) TimerCounter--; // zmensi pomocny citac |
||
| 62 | |||
| 63 | set_timer1(-TIMERXTAL/IPS); // znovu natahni Timer 1 |
||
| 64 | |||
| 65 | if (kbd_timer!=0 && kbd_state==0) // kbd_k4.c |
||
| 66 | { // kbd_k4.c |
||
| 67 | kbd_timer--; // kbd_k4.c |
||
| 68 | } // kbd_k4.c |
||
| 69 | } |
||
| 70 | |||
| 71 | |||
| 72 | // Kalibracni konstanty (nactene z EEPROM) |
||
| 73 | // |
||
| 74 | long int VREF; |
||
| 75 | float K1, K2; |
||
| 76 | #define EE_SUMA 0 // int8 kontrolni suma |
||
| 77 | #define EE_VREF 1 // int16 napeti reference v mV |
||
| 78 | #define EE_K1 3 // float kalibracni konstanta K1 |
||
| 79 | #define EE_K2 7 // float kalibracni konstanta K2 |
||
| 80 | #define EE_MEMORY 11 // int16 zde zacinaji pametove bunky |
||
| 81 | |||
| 82 | #define VREF_LOW 2000 // spodni mez platneho VREF |
||
| 83 | #define VREF_HIGH 6000 // horni mez platneho VREF |
||
| 84 | #define VREF_DEFAULT 3735 // defaultni hodnota napeti reference |
||
| 85 | #define VREF_STEP 5 // krok pro nastavovani hodnoty VREF pri kalibraci |
||
| 86 | |||
| 87 | |||
| 88 | // Mereni napeti baterie |
||
| 89 | // |
||
| 90 | |||
| 91 | #define HFV_ENABLE PIN_A5 // zapinani detekcni sondy |
||
| 92 | |||
| 93 | float Read_Vdd() |
||
| 94 | { |
||
| 95 | long int Vdd; |
||
| 96 | |||
| 97 | setup_adc(ADC_CLOCK_INTERNAL); // zapni prevodnik |
||
| 98 | setup_adc_ports(RA0_RA1_RA3_ANALOG); // reference je Vdd |
||
| 99 | set_adc_channel(3); // nastav mereni RA3 - reference |
||
| 100 | delay_us(20); // pockej na ustaleni |
||
| 101 | Vdd=read_adc(); // precti hodnotu |
||
| 102 | setup_adc(ADC_OFF); // vypni prevodnik |
||
| 103 | return ((float)VREF*1.023)/Vdd; // prepocti hodnotu na volty |
||
| 104 | } |
||
| 105 | |||
| 106 | |||
| 107 | // Mereni napeti na vystupu sondy (napeti umerne logaritmu amplitudy signalu) |
||
| 108 | // Pozor mereni se musi provadet pravidelne a dosatatecne casto (asi 50x za sekundu) |
||
| 109 | // aby se v pauzach nevybily kondenzatory |
||
| 110 | // |
||
| 111 | |||
| 112 | #DEFINE MULT_FACTOR 10 |
||
| 113 | |||
| 114 | signed long int read_hfv() |
||
| 115 | { |
||
| 116 | int i; // pocitadlo opakovani mereni |
||
| 117 | signed long int Hfv; // vysledek |
||
| 118 | |||
| 119 | Hfv=0; // nuluj stradac |
||
| 120 | for (i=MULT_FACTOR;i!=0;i--) // oapkovani |
||
| 121 | { |
||
| 122 | output_high(HFV_ENABLE); // zapni sondu |
||
| 123 | delay_us(400); // pockej na jeji aktivaci |
||
| 124 | setup_adc(ADC_CLOCK_INTERNAL); // nastav prevodnik |
||
| 125 | setup_adc_ports(RA0_RA1_ANALOG_RA3_REF); |
||
| 126 | set_adc_channel(0); // vyber kanal |
||
| 127 | delay_us(20); // pockej na ustaleni |
||
| 128 | Hfv+=read_adc(); // precti hodnotu |
||
| 129 | output_low(HFV_ENABLE); // odpoj sondu |
||
| 130 | setup_adc(ADC_OFF); // vypni prevodnik |
||
| 131 | sleep(); // prodleva |
||
| 132 | } |
||
| 133 | return Hfv; |
||
| 134 | } |
||
| 135 | |||
| 136 | |||
| 137 | // Spocitej kontrolni soucet EEPROM, casti s kalibracnimi konstantami |
||
| 138 | // |
||
| 139 | int Suma() |
||
| 140 | { |
||
| 141 | unsigned int Adr; |
||
| 142 | int Sum; |
||
| 143 | |||
| 144 | Sum=0; |
||
| 145 | for (Adr=0; Adr<EE_MEMORY; Adr++) |
||
| 146 | { |
||
| 147 | Sum += read_eeprom(Adr); |
||
| 148 | } |
||
| 149 | return Sum; |
||
| 150 | } |
||
| 151 | |||
| 152 | #define KLEVEL_HIGH_MAX 20 |
||
| 153 | #define KLEVEL_HIGH_MIN -50 |
||
| 154 | #define KLEVEL_HIGH_START 0 |
||
| 155 | |||
| 156 | #define KLEVEL_LOW_MAX -30 |
||
| 157 | #define KLEVEL_LOW_MIN -90 |
||
| 158 | #define KLEVEL_LOW_START -60 |
||
| 159 | |||
| 160 | #define KLEVEL_STEP 10 |
||
| 161 | |||
| 162 | |||
| 163 | // Proved kalibraci |
||
| 164 | // |
||
| 165 | void Callibrate(BOOLEAN Requested) |
||
| 166 | { |
||
| 167 | |||
| 168 | char c; |
||
| 169 | signed int L1,L2; |
||
| 170 | signed int16 A1,A2; |
||
| 171 | |||
| 172 | printf(lcd_putc,"\f\nESC \20 \21 OK"); |
||
| 173 | |||
| 174 | // kalibrace VREF |
||
| 175 | // |
||
| 176 | do |
||
| 177 | { |
||
| 178 | printf(lcd_putc,"\rCAL Vref: %4ldmV",VREF); |
||
| 179 | c=kbd_waitc(); |
||
| 180 | if (c==KBD_K1) |
||
| 181 | { |
||
| 182 | reset_cpu(); |
||
| 183 | } |
||
| 184 | if (c==KBD_K2) |
||
| 185 | { |
||
| 186 | if (VREF<=VREF_HIGH-VREF_STEP) VREF += VREF_STEP; |
||
| 187 | } |
||
| 188 | if (c==KBD_K3) |
||
| 189 | { |
||
| 190 | if (VREF>=VREF_LOW+VREF_STEP) VREF -= VREF_STEP; |
||
| 191 | } |
||
| 192 | } |
||
| 193 | while (c!=KBD_K4); |
||
| 194 | EE_WR(EE_VREF, VREF); |
||
| 195 | if (!Requested) |
||
| 196 | { |
||
| 197 | write_eeprom(EE_SUMA,read_eeprom(EE_SUMA)-Suma()); // dopocti kontrolni soucet a uloz ho |
||
| 198 | } |
||
| 199 | |||
| 200 | // Kalibrace High urovne |
||
| 201 | // |
||
| 202 | L1=KLEVEL_HIGH_START; |
||
| 203 | do |
||
| 204 | { |
||
| 205 | printf(lcd_putc,"\rCAL High: %3ddBV",L1); |
||
| 206 | c=kbd_waitc(); |
||
| 207 | if (c==KBD_K1) |
||
| 208 | { |
||
| 209 | reset_cpu(); |
||
| 210 | } |
||
| 211 | if (c==KBD_K2) |
||
| 212 | { |
||
| 213 | if (L1<=KLEVEL_HIGH_MAX-KLEVEL_STEP) L1 += KLEVEL_STEP; |
||
| 214 | } |
||
| 215 | if (c==KBD_K3) |
||
| 216 | { |
||
| 217 | if (L1>=KLEVEL_HIGH_MIN+KLEVEL_STEP) L1 -= KLEVEL_STEP; |
||
| 218 | } |
||
| 219 | } |
||
| 220 | while (c!=KBD_K4); |
||
| 221 | for (c=10;c>0;c--) A1 = read_hfv(); |
||
| 222 | |||
| 223 | // Kalibrace Low urovne |
||
| 224 | // |
||
| 225 | L2=L1-60; |
||
| 226 | do |
||
| 227 | { |
||
| 228 | printf(lcd_putc,"\rCAL Low: %3ddBV",L2); |
||
| 229 | c=kbd_waitc(); |
||
| 230 | if (c==KBD_K1) |
||
| 231 | { |
||
| 232 | reset_cpu(); |
||
| 233 | } |
||
| 234 | if (c==KBD_K2) |
||
| 235 | { |
||
| 236 | if (L2<=L1-2*KLEVEL_STEP) L2 += KLEVEL_STEP; |
||
| 237 | } |
||
| 238 | if (c==KBD_K3) |
||
| 239 | { |
||
| 240 | if (L2>=KLEVEL_LOW_MIN+KLEVEL_STEP) L2 -= KLEVEL_STEP; |
||
| 241 | } |
||
| 242 | } |
||
| 243 | while (c!=KBD_K4); |
||
| 244 | for (c=10;c>0;c--) A2 = read_hfv(); |
||
| 245 | |||
| 246 | // Vypocti kalibracni konstanty a uloz je do EEPROM |
||
| 247 | // |
||
| 248 | K1 = (float)(L2-L1) / (float)(A2-A1); // vypocti K1 (strmost) |
||
| 249 | K2 = ((float)L1*A2 - (float)L2*A1) / (float)(A2-A1); // vypocti K2 (posunuti) |
||
| 250 | EE_WR(EE_K1, K1); // uloz K1 do EEPROM |
||
| 251 | EE_WR(EE_K2, K2); // uloz K2 do EEPROM |
||
| 252 | write_eeprom(EE_SUMA,read_eeprom(EE_SUMA)-Suma()); // dopocti kontrolni soucet a uloz ho |
||
| 253 | //printf(lcd_putc,"\fL1 %d L2 %d\nA1 %ld A2 %ld",L1,L2,A1,A2); |
||
| 254 | //kbd_waitc(); |
||
| 255 | //printf(lcd_putc,"\fK1 %f\nK2 %f",K1,K2); |
||
| 256 | //kbd_waitc(); |
||
| 257 | } |
||
| 258 | |||
| 259 | #include "knob.c" |
||
| 260 | |||
| 261 | #define WARNINGVOLTAGE 4.75 // hranice pro varovani vybite baterie |
||
| 262 | |||
| 263 | void main() |
||
| 264 | { |
||
| 265 | int c; |
||
| 266 | int i; |
||
| 267 | |||
| 268 | int Mode; |
||
| 269 | |||
| 270 | // Inicializace nevyuzitych pinu |
||
| 271 | // |
||
| 272 | |||
| 273 | //output_low(PIN_A0); // zde je analogovy vstup |
||
| 274 | // output_low(PIN_A1); // zde je otocny knoflik |
||
| 275 | // output_low(PIN_A2); // zde je otocny knoflik |
||
| 276 | //output_low(PIN_A3); // zde je napetova refence |
||
| 277 | output_low(PIN_A4); |
||
| 278 | output_low(PIN_A5); // zde je rizeni |
||
| 279 | |||
| 280 | // output_low(PIN_B0); // zde je RTS# |
||
| 281 | //output_low(PIN_B1); // LCD_E |
||
| 282 | //output_low(PIN_B2); // LCD_RS |
||
| 283 | // output_low(PIN_B3); // zde je CTS# |
||
| 284 | //output_low(PIN_B4); // tlaciko 1 |
||
| 285 | //output_low(PIN_B5); // tlaciko 2 |
||
| 286 | //output_low(PIN_B6); // tlaciko 3 |
||
| 287 | //output_low(PIN_B7); // tlaciko 4 |
||
| 288 | |||
| 289 | //output_low(PIN_C0); // xtal 32768Hz |
||
| 290 | //output_low(PIN_C1); // xtal 32768Hz |
||
| 291 | //output_low(PIN_C2); // LCD D4 (LSB) |
||
| 292 | //output_low(PIN_C3); // LCD D5 |
||
| 293 | //output_low(PIN_C4); // LCD D6 |
||
| 294 | //output_low(PIN_C5); // LCD D7 |
||
| 295 | output_low(PIN_C6); // RS232 TX |
||
| 296 | output_low(PIN_C7); // RS232 RX |
||
| 297 | |||
| 298 | |||
| 299 | // Zakladni vypis |
||
| 300 | // |
||
| 301 | lcd_init(); |
||
| 302 | printf(lcd_putc,"\fHF Vmeter " VERSION); |
||
| 303 | delay_ms(100); // cas pro ustaleni napajeni |
||
| 304 | lcd_define_char(0,LCD_CHAR_UP LCD_CHAR_DOWN); // Znaky sipka nahoru a sipka dolu od pozice 0 |
||
| 305 | |||
| 306 | |||
| 307 | // Inicializace zakladni casovaci smycky casovane pomoci preruseni od casovace 1 |
||
| 308 | // |
||
| 309 | Timer1=FALSE; // inicializuj pocitadla |
||
| 310 | TimerCounter=0; |
||
| 311 | |||
| 312 | setup_timer_1(T1_EXTERNAL | T1_CLK_OUT | T1_DIV_BY_1); // nastav TIMER1 jako 32768Hz oscilator |
||
| 313 | set_timer1(-TIMERXTAL/IPS); // definuj casovy interval tak, aby bylo IPS opakovani za sekundu |
||
| 314 | enable_interrupts(INT_TIMER1); // povol preruseni |
||
| 315 | enable_interrupts(GLOBAL); // povol globalni preruseni |
||
| 316 | |||
| 317 | |||
| 318 | // Inicializace obsluhy klavesnice |
||
| 319 | // |
||
| 320 | kbd_init(); // inicializuj klavesnici |
||
| 321 | |||
| 322 | knob(); |
||
| 323 | |||
| 324 | // Nacteni kalibracnich hodnod z EEPROM |
||
| 325 | // |
||
| 326 | EE_RD(EE_VREF, VREF); |
||
| 327 | EE_RD(EE_K1, K1); |
||
| 328 | EE_RD(EE_K2, K2); |
||
| 329 | |||
| 330 | if (VREF<VREF_LOW || VREF>VREF_HIGH) |
||
| 331 | { |
||
| 332 | VREF = VREF_DEFAULT; |
||
| 333 | } |
||
| 334 | |||
| 335 | |||
| 336 | // Kontrola kontrolniho souctu EEPROM |
||
| 337 | // |
||
| 338 | if (Suma()) // spocitej kontrolni soucet EEPROM (jen kalibracni konstanty) |
||
| 339 | { |
||
| 340 | printf(lcd_putc,"\nERR: Bad EEPROM"); // chyba EEPROM |
||
| 341 | kbd_waitc(); // uzivatel potvrdi |
||
| 342 | Callibrate(TRUE); // spust kalibraci s priznakem vnucene kalibrace |
||
| 343 | } |
||
| 344 | |||
| 345 | |||
| 346 | // Mereni napajeciho napeti |
||
| 347 | // |
||
| 348 | { |
||
| 349 | BOOLEAN Wait; |
||
| 350 | float Vdd; |
||
| 351 | |||
| 352 | TimerCounter=3*IPS; // timeout 3 sekundy |
||
| 353 | Wait=FALSE; // Priznak, ze se ma cekat na klavesu |
||
| 354 | |||
| 355 | do |
||
| 356 | { |
||
| 357 | Vdd=Read_Vdd(); // precti hodnotu |
||
| 358 | if (Vdd>=WARNINGVOLTAGE) // otestuj zda je dostatecne napajeni |
||
| 359 | { |
||
| 360 | printf(lcd_putc,"\nVdd: %1.2fV",Read_Vdd()); // je O.K. |
||
| 361 | } |
||
| 362 | else |
||
| 363 | { |
||
| 364 | printf(lcd_putc,"\fBattery Low\nVdd: %1.2fV",Read_Vdd()); // baterie je slaba |
||
| 365 | Wait=TRUE; // a budeme cekat na reakci uzivatele |
||
| 366 | } |
||
| 367 | sleep(); // usni |
||
| 368 | if (!Wait && kbd_getc()) Wait=TRUE; // pokud nebyla podminka wait a byla klavesa budeme cekat |
||
| 369 | if (Wait && kbd_getc()) break; // pokud jiz cekame cekani ukoncime pri stisku klavesy |
||
| 370 | } |
||
| 371 | while (TimerCounter || Wait); // mer dokud neni zmacknuta klavesa nebo dokud nevyprsi timeout |
||
| 372 | } |
||
| 373 | |||
| 374 | |||
| 375 | |||
| 376 | // Hlavni smycka zpracovani |
||
| 377 | // |
||
| 378 | |||
| 379 | #define MODE_MIN 0 |
||
| 380 | #define MODE_MAX 2 |
||
| 381 | |||
| 382 | Mode=MODE_MIN; |
||
| 383 | |||
| 384 | for (;;) |
||
| 385 | { |
||
| 386 | printf(lcd_putc,"\f\nMW \20MODE\21 CFG"); // smaz displej a definuj stavovou radku |
||
| 387 | do |
||
| 388 | { |
||
| 389 | float RES; |
||
| 390 | long int HFV; |
||
| 391 | HFV = read_hfv(); |
||
| 392 | RES = K1*HFV+K2; |
||
| 393 | if (Mode==0) printf(lcd_putc,"\rLEVEL: %3.1f dB",RES); // mer a zobrazuj dBV |
||
| 394 | if (Mode==1) printf(lcd_putc,"\rLEVEL: %03.3e V",expdb(RES)); // mer a zobrazuj V |
||
| 395 | if (Mode==2) printf(lcd_putc,"\rLEVEL: %ld RAW",HFV); // mer a zobrazuj primo vystup prevodniku |
||
| 396 | } |
||
| 397 | while (!kbd_key); // dokud uzivatel neco nezmackne |
||
| 398 | |||
| 399 | i=kbd_getc(); |
||
| 400 | if (i==KBD_K1) {}; |
||
| 401 | if (i==KBD_K2) { if (Mode<MODE_MAX) Mode++; }; |
||
| 402 | if (i==KBD_K3) { if (Mode>MODE_MIN) Mode--; }; |
||
| 403 | if (i==KBD_K4) { }; |
||
| 404 | } |
||
| 405 | } |
||
| 406 | |||
| 407 | //Callibrate(FALSE); |
||
| 408 | |||
| 409 | //Spravny postup co nejkratsi smycky (vede na instrukci DECFSZ) |
||
| 410 | // |
||
| 411 | // i=12; |
||
| 412 | // do |
||
| 413 | // lcd_putc(i); |
||
| 414 | // while (--i); |
||
| 415 | //#ifdef SHRT |
||
| 416 | //#rom 0x2100={0x36, 0x97, 0x0E, 0x78, 0x78, 0x2E, 0x04, 0x85, 0xD3, 0x76, 0x35} |
||
| 417 | //#endif |
||
| 418 | |||
| 419 | // If you need to use any pin on any port use: |
||
| 420 | // *(pin_to_use/8|0x80) &= ~(1<<(pin_to_use&7)); // ** |
||
| 421 | // *(pin_to_use/8) |= (1<<(pin_to_use&7)); |
||
| 422 | // In all cases pin_to_use is the normal PIN_A0... defines. |
Powered by WebSVN v2.8.3