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 |
|