Rev Author Line No. Line
125 kaklik 1 /************************************************************************/
2 /* */
3 /* Program PCPORTA.C for reading of pressure, temperature and */
4 /* calibration data of MS5534. Displays compensated Temperature and */
5 /* Pressure + Altitude using approximation of standard atmosphere */
6 /* */
7 /* Date: 18.12.97 This version includes the quadratic Term */
8 /* for the temperature calculation */
9 /* */
10 /* Last update: 18.05.00 (added comments) */
11 /************************************************************************/
12  
13 /*
14  
15 This program runs under MSDOS or Windows NT4.0 (in MSDOS Window)
16 The frequency at SCLK is defined to approx 1ms in the subroutine
17 del(int time). To have it faster delete the line delay(1) and
18 use the for(..) loop. Adjust with the constants del_hi and del_lo.
19  
20 Basic routines are in the beginning, top level routines at the
21 end of the Source Code.
22 Therefore when reading the program please begin at the end
23 of the source code.
24  
25 */
26  
27  
28 #include <stdio.h>
29 #include <dos.h>
30 #include <conio.h>
31 #include <stdlib.h>
32  
33 #define L 1500
34  
35 typedef unsigned int WORD;
36 int base = 956;
37 int datin[L];
38 int sclk = 0;
39 int sdi = 0;
40 int rest = 0xfc;
41 long dut,c1,c2,c3,c4,c5,c6;
42  
43  
44 const del_hi = 120/30;
45 const del_lo = 320/30;
46  
47 del(int time);
48 oport(void);
49 int iport(void);
50 sclklo(void);
51 sclkhi(void);
52 sdilo(void);
53 sdihi(void);
54 send_hi(void);
55 send_lo(void);
56 reset(void);
57 calib_req(long word);
58 d1_req(void);
59 d2_req(void);
60 long adc_read(void);
61 long d1_read(void);
62 long d2_read(void);
63 long cali_read(long word);
64 coeff(void);
65 long press(void);
66 long temp(void);
67 float alti_calc(float pres);
68  
69  
70 /********************* Subroutines ***************************/
71  
72 /*************** Delay Time **********************************/
73  
74 del(int time)
75 {
76 int i;
77 delay(1);
78 /*
79 for (i = 0; i < (time << 5); i++)
80 i = i;
81 */
82 };
83  
84 /********** Output State of sdi and sclk to Port *************/
85  
86 oport()
87 {
88 int outb;
89 outb = sclk + (sdi << 1) + rest;
90 outportb(base, outb);
91 };
92  
93 /***************** Read State of DIN from Port ***************/
94  
95 int iport()
96 {
97 return((inportb(base + 1) & 32) >> 5);
98 };
99  
100  
101 sdihi()
102 {
103 sdi = 1; oport(); del(del_hi);
104 }
105  
106 sdilo()
107 {
108 sdi = 0; oport(); del(del_lo);
109 }
110 sclkhi()
111 {
112 sclk = 1; oport(); del(del_hi);
113 }
114  
115 sclklo()
116 {
117 sclk = 0; oport(); del(del_lo);
118 }
119  
120 send_hi()
121 {
122 sdihi(); /* Set DIN to High */
123 sclkhi(); /* Clock-In DIN with the rising edge */
124 sdilo(); /* Set DIN back to Low */
125 sclklo(); /* take clock back to Low */
126 };
127  
128 send_lo()
129 {
130 sdilo(); /* Set DIN to Low */
131 sclkhi(); /* Clock-In DIN with the rising edge */
132 sclklo(); /* take clock back to Low */
133 };
134  
135 /******* Sends the Reset Sequence to the MS5534 ******/
136  
137 reset()
138 {
139 int i = 0;
140 for(i = 0; i < 9; i++)
141 {
142 send_hi();
143 send_lo();
144 };
145 for(i = 0; i < 3; i++)
146 {
147 send_lo();
148 };
149 };
150  
151  
152 /**** Trigger Calibration Data Readout Sequence ******/
153  
154 calib_req(long word)
155 {
156 int i;
157 for(i = 0; i < 3; i++) send_hi();
158 send_lo(); send_hi();
159 if (word == 1)
160 {
161 send_lo(); send_hi(); send_lo(); send_hi();
162 }
163 if (word == 2)
164 {
165 send_lo(); send_hi(); send_hi(); send_lo();
166 }
167 if (word == 3)
168 {
169 send_hi(); send_lo(); send_lo(); send_hi();
170 }
171 if (word == 4)
172 {
173 send_hi(); send_lo(); send_hi(); send_lo();
174 }
175  
176 for(i = 0; i < 4; i++) send_lo();
177  
178 };
179  
180 /*************** Trigger Readout of D1 ***************/
181  
182 d1_req()
183 {
184 int i;
185 for(i = 0; i < 3; i++) send_hi();
186 send_hi(); send_lo();
187 send_hi(); send_lo();
188 for(i = 0; i < 5; i++) send_lo();
189 };
190  
191 /*************** Trigger Readout of D2 ***************/
192  
193 d2_req()
194 {
195 int i;
196 for(i = 0; i < 3; i++) send_hi();
197 send_hi(); send_lo();
198 send_lo(); send_hi();
199 for(i = 0; i < 5; i++) send_lo();
200 };
201  
202 /*************** Readout of 16 Bit Result ************/
203  
204 long adc_read()
205 {
206 int i = 0;
207 long di = 0;
208 long adc_val = 0;
209  
210 send_lo();
211 delay(1);
212 for(i = 0; i < 16; i++)
213 {
214 di = (long) iport();
215 di = di << (15 - i);
216 adc_val += di;
217 send_lo();
218 delay(1);
219 };
220 return(adc_val);
221 };
222  
223 /**********************************************************/
224 /* The following 3 routines read D1,D2 or Word1...Word4 */
225 /**********************************************************/
226  
227 long d1_read()
228 {
229 d1_req(); /* Start D1 conversion */
230 delay(1);
231 do
232 if(kbhit()) break;
233 while ( iport() != 0); /* Wait until DOUT = 0 */
234  
235 return(adc_read()); /* Read 16 Bit Result */
236 };
237  
238 long d2_read()
239 {
240 d2_req(); /* Start D2 conversion */
241 delay(1);
242 do /* Wait until DOUT=0 */
243 if(kbhit()) break;
244 while ( iport() != 0);
245  
246 return(adc_read()); /* Read 16 Bit Result */
247 };
248  
249 long cali_read(long word)
250 {
251 calib_req(word); /* Instruction for reading*/
252 delay(1); /* Calibration Words */
253 return(adc_read()); /* Read 16 Bit Result */
254 };
255  
256 /**********************************************************/
257 /* Calculation of Calibration coefficients C1..C6 */
258 /* out of calibration words 1..4 */
259 /* required once at program start */
260 /**********************************************************/
261  
262  
263 coeff()
264 {
265 long word1,word2,word3,word4;
266  
267 word1=cali_read(1);
268 word2=cali_read(2);
269 word3=cali_read(3);
270 word4=cali_read(4);
271  
272 word1=0xac10;
273 word2=0xa123;
274 word3=0x9d1f;
275 word4=0xc080;
276  
277 c1 = word1>>1;
278 c2 = word3 & 0x3f;
279 c2 <<= 6;
280 c2 |= (word4 & 0x3f);
281 c3 = word4>>6;
282 c4 = word3>>6;
283 c5 = word1<<10;
284 c5 &= 0x400;
285 c5 += word2>>6;
286 c6 = word2&0x3f;
287 }
288  
289  
290 /**********************************************************/
291 /* Calculation of pressure <p> out of D1,D2 and */
292 /* calibration coefficients C1...C5 */
293 /**********************************************************/
294  
295  
296 long press()
297 {
298 long d1,d2,ut1,off,sens,x,p;
299  
300 d1 = d1_read(); /* read pressure value */
301 d2 = d2_read(); /* read temperature value */
302  
303 d1=0x4689;
304 d2=0x6160;
305  
306 ut1 = 8*c5+20224;
307 dut = d2-ut1; /* dut=0 for T=20 degrC */
308 /* can be positive or neg */
309  
310 /* if negative then use quadratic term for better */
311 /* accuracy for temperatures below 20degr C */
312  
313 if (dut<0) dut -= (dut/128*dut/128)/4;
314 off = (c2+((c4-512)*dut/16384))*4;
315 sens = c1+(c3*dut)/1024+24576;
316 x = (sens*(d1-7168))/16384-off;
317  
318 p = x*100/32+250*100; /* pressure in 0.01 mbar */
319  
320  
321 return(p);
322 }
323  
324 /**********************************************************/
325 /* Calculation of Temperature in degr Celsius */
326 /* Input variable is <dut> and the coefficient C6 */
327 /* Output variable is <temp> in the 1/10 of degr Celsius */
328 /**********************************************************/
329  
330 long temp()
331 {
332 long temp;
333  
334 temp = 200+(dut*(c6+50))/1024;
335 return(temp);
336 }
337  
338 /**********************************************************/
339 /* Approximation of 1976 US Standard Atmosphere */
340 /* piecewise linear approximation in the form of */
341 /* alti = 10*j-pres*i */
342 /* Input variable is <pres> which is the pressure in mbar */
343 /* Output variable is <alti> which is the altitude in m */
344 /**********************************************************/
345  
346 float alti_calc(float pres)
347 {
348 long i,j;
349 float alti;
350  
351 if(pres<349)
352 {
353 i=210;
354 j=15464;
355 }
356 else if(pres<400.5)
357 {
358 i=186;
359 j=14626;
360 }
361 else if(pres<450)
362 {
363 i=168;
364 j=13905;
365 }
366 else if(pres<499)
367 {
368 i=154;
369 j=13275;
370 }
371 else if(pres<549)
372 {
373 i=142;
374 j=12676;
375 }
376 else if(pres<600)
377 {
378 i=132;
379 j=12127;
380 }
381 else if(pres<650)
382 {
383 i=123;
384 j=11587;
385 }
386 else if(pres<700)
387 {
388 i=116;
389 j=11132;
390 }
391 else if(pres<748)
392 {
393 i=109;
394 j=10642;
395 }
396 else if(pres<800)
397 {
398 i=104;
399 j=10268;
400 }
401 else if(pres<850)
402 {
403 i=98;
404 j=9788;
405 }
406 else if(pres<897.5)
407 {
408 i=94;
409 j=9448;
410 }
411 else if(pres<947.5)
412 {
413 i=90;
414 j=9089;
415 }
416 else if(pres<1006)
417 {
418 i=86;
419 j=8710;
420 }
421 else if(pres<1100)
422 {
423 i=81;
424 j=8207;
425 }
426 alti = 10*j-pres*i;
427 return(alti/10);
428 }
429  
430 /************************************************************************/
431 /* (Pins Configuration on LPT1 port) */
432 /* Pin 1 - ws open */
433 /* Pin 2 - gb - SCLK data 1 */
434 /* Pin 3 - org - SDI data 2 */
435 /* Pin 4 - gn - VDD data 4 */
436 /* Pin 10 - rt - open data 64 */
437 /* Pin 11 - br - open data x128 */
438 /* Pin 12 - bl - SDO data 32 */
439 /* Pin 25 - sw - GND */
440 /************************************************************************/
441  
442 main()
443 {
444  
445 /*********************** Variables und Constants ***********************/
446  
447 int i, j, k;
448 long p,t;
449 float p_fil,t_fil,alti;
450 FILE *dat_pointer;
451  
452 base = *(WORD far *) MK_FP(0x0040, 8);
453  
454 /************************ Main Program **********************************/
455  
456 reset(); /* Send Reset sequence to MS5534 */
457 coeff(); /* Read and calculate C1...C6 */
458 clrscr();
459  
460 p = press();
461 t = temp();
462 p_fil = p; /* Preset filtered Pressure value */
463  
464 gotoxy(10,8);
465 printf("---------------------------------------------------------");
466 gotoxy(10,14);
467 printf("---------------------------------------------------------");
468  
469 for(;;)
470 {
471  
472 p = press();
473 t = temp();
474  
475 if ((p>30000) && (p<110000)) /* Pressure 300...1100mb ? */
476 {
477 p_fil = (32*p_fil+(p-p_fil))/32; /* Simple Low Pass Filter */
478 t_fil = t; /* no filter for Temp */
479 alti = alti_calc(p_fil/100); /* mbar -> altitude conv. */
480 }
481 gotoxy(12,10);
482 printf("Temperature %.2f øC Pressure %.2f mbar\n", t_fil/10,p_fil/100);
483 printf("\n");
484 printf(" Altitude %.1f m \n",alti);
485 if (kbhit()) break;
486 };
487 }
488