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