Mercurial > public > mk2
comparison code_part1/OSTC_code_asm_part1/ms5535.asm @ 161:8d6aca08f66b
Use signed arithmetic for pressure/temperature compensation.
author | JeanDo |
---|---|
date | Tue, 18 Jan 2011 23:57:33 +0100 |
parents | 3e351e25f5d1 |
children | e26f49674956 |
comparison
equal
deleted
inserted
replaced
160:0ee809806454 | 161:8d6aca08f66b |
---|---|
14 ; You should have received a copy of the GNU General Public License | 14 ; You should have received a copy of the GNU General Public License |
15 ; along with this program. If not, see <http://www.gnu.org/licenses/>. | 15 ; along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 |
17 | 17 |
18 ; routines for Intersema MS5535A, MS5541B and MS5541C | 18 ; routines for Intersema MS5535A, MS5541B and MS5541C |
19 ; written by: Matthias Heinrichs, info@heinrichsweikamp.com | 19 ; history: |
20 ; written: 9/26/05 | 20 ; 2005-09-26: Written by Matthias Heinrichs, info@heinrichsweikamp.com |
21 ; last updated: 08/08/31 | 21 ; 2008-08-21: MH last updated |
22 ; 2011-01-19: jDG Clean up using true signed arithmetics. | |
22 ; known bugs: | 23 ; known bugs: |
23 ; ToDo: | 24 ; ToDo: |
24 | 25 |
25 ; with second order temperature compensation | 26 ; with second order temperature compensation |
26 | 27 |
27 calculate_compensation: | 28 calculate_compensation: |
28 ; calculate xdT | 29 ; calculate UT1 = 8*C5 + 10000 (u16 range 10.000 .. +42.760) |
29 clrf isr_xA+1 | 30 clrf isr_xA+1 |
30 movlw d'8' | 31 movlw d'8' |
31 movwf isr_xA+0 | 32 movwf isr_xA+0 |
32 movff C5+0,isr_xB+0 | 33 movff C5+0,isr_xB+0 |
33 movff C5+1,isr_xB+1 | 34 movff C5+1,isr_xB+1 |
34 call isr_mult16x16 ;isr_xA*isr_xB=isr_xC | 35 call isr_unsigned_mult16x16 ;isr_xA*isr_xB=isr_xC |
35 movlw LOW d'10000' | 36 movlw LOW d'10000' |
36 addwf isr_xC+0, f | 37 addwf isr_xC+0, f |
37 movlw HIGH d'10000' | 38 movlw HIGH d'10000' |
38 addwfc isr_xC+1, f ;isr_xC= 8*C5 + 10000 | 39 addwfc isr_xC+1, f ;isr_xC= 8*C5 + 10000 |
39 movff D2+0,isr_sub_a+0 | 40 |
40 movff D2+1,isr_sub_a+1 | 41 ; xdT = D2 - UT1 (s16 range -11.400 .. +12.350) |
41 movff isr_xC+0,isr_sub_b+0 | 42 movf isr_xC+0,W ; Get Value to be subtracted |
42 movff isr_xC+1,isr_sub_b+1 | 43 subwf D2+0,W ; Do the Low Byte |
43 call isr_sub16 ; isr_sub_c = isr_sub_a - isr_sub_b | 44 movwf xdT+0 |
44 movff isr_sub_c+0,xdT+0 | 45 movf isr_xC+1,W ; Then the high byte. |
45 movff isr_sub_c+1,xdT+1 | 46 subwfb D2+1,W |
46 | 47 movwf xdT+1 |
47 ; Second order temperature calculation | 48 |
48 btfsc neg_flag_isr | 49 ; Second order temperature calculation |
49 bra dTzero_yes | 50 ; xdT/128 is in range -89..+96, hence signed 8bit. dT/128 = (2*dT)/256 |
50 ; dT>0 | 51 rlcf xdT+0,W ; put hit bit in carry. |
51 bcf neg_flag_xdT | 52 rlcf xdT+1,W ; inject in high byte. |
52 movff xdT+0,isr_xA+0 | 53 movwf isr_xA+0 ; and put result in low byte. |
53 movff xdT+1,isr_xA+1 | 54 clrf isr_xA+1 |
54 movff xdT+0,isr_xB+0 | 55 btfsc xdT+1,7 ; If dT < 0 |
55 movff xdT+1,isr_xB+1 | 56 setf isr_xA+1 ; then signextend to -1 |
56 call isr_mult16x16 ;isr_xA*isr_xB=isr_xC | 57 movff isr_xA+0,isr_xB+0 ; copy A to B |
57 movlw d'17' ; 2^17=(128*128)*8 | 58 movff isr_xA+1,isr_xB+1 |
58 movwf isr_divB | 59 call isr_signed_mult16x16 ; dT*dT --> xC (32 bits) |
59 call isr_div32 ; isr_xC=isr_xC(32Bit)/2^isr_divB (isr_divB: 8Bit only!) | 60 |
60 movff xdT+0,isr_sub_a+0 | 61 ; dT >= 0: divide by 8, ie. 3 shifts rights. |
61 movff xdT+1,isr_sub_a+1 | 62 ; dT < 0: divide by 2, ie. 1 shifts rights. |
62 movff isr_xC+0,isr_sub_b+0 | 63 movlw .3 |
63 movff isr_xC+1,isr_sub_b+1 | 64 btfss xdT+1,7 ; Was dT negatif ? |
64 call isr_sub16 ; isr_sub_c = isr_sub_a - isr_sub_b | 65 movlw .1 |
65 movff isr_sub_c+0,xdT2+0 | 66 calc_loop_1: |
66 movff isr_sub_c+1,xdT2+1 | 67 bcf STATUS,C ;dT^2 is positiv, so injected zeros. |
67 bra OFF_calc ; Done | 68 rrcf isr_xC+1,F |
68 | 69 rrcf isr_xC+0,F |
69 dTzero_yes: | 70 decfsz WREG |
70 ; dT<0 | 71 bra calc_loop_1 |
71 bsf neg_flag_xdT | 72 |
72 movff xdT+0,isr_xA+0 | 73 movf isr_xC+0,W ; dT2 = dT - (dT/128)*(dT/128)/(2 ...or... 8) |
73 movff xdT+1,isr_xA+1 | 74 subwf xdT+0,W |
74 movff xdT+0,isr_xB+0 | 75 movwf xdT2+0 |
75 movff xdT+1,isr_xB+1 | 76 movf isr_xC+1,W |
76 call isr_mult16x16 ;isr_xA*isr_xB=isr_xC | 77 subwfb xdT+1,W |
77 movlw d'15' ; 2^15=(128*128)*2 | 78 movwf xdT2+1 |
78 movwf isr_divB | 79 |
79 call isr_div32 ; isr_xC=isr_xC(32Bit)/2^isr_divB (isr_divB: 8Bit only!) | 80 ; Calculate OFF = C2 + ((C4-250)*dT2)/2^12 + 10000 |
80 | 81 ; (range +9.246 .. +18.887) |
81 movf xdT+0,W | 82 movlw LOW(-.250) ; C4 - 250 --> A |
82 addwf isr_xC+0,F | 83 addwf C4+0,W |
83 movf xdT+1,W | 84 movwf isr_xA+0 |
84 addwfc isr_xC+1,F | 85 movlw -1 ; HIGH(- .250) is not hunderstood... |
85 movff isr_xC+0,xdT2+0 | 86 addwfc C4+1,W |
86 movff isr_xC+1,xdT2+1 | 87 movwf isr_xA+1 |
87 | 88 |
88 OFF_calc: | 89 movff xdT2+0,isr_xB+0 ; dT2 --> B |
89 ; calculate OFF | 90 movff xdT2+1,isr_xB+1 |
90 movff C4+0,isr_sub_a | 91 call isr_signed_mult16x16 |
91 movff C4+1,isr_sub_a+1 | 92 movlw .12-.8 ; A 12bit shift = 1 byte + 4 bits. |
92 movlw d'250' | 93 call isr_shift_C31 |
93 movwf isr_sub_b | 94 |
94 clrf isr_sub_b+1 | 95 movlw LOW(.10000) ; Add 10000 |
95 call isr_sub16 ; (C4-250) - Sets neg_flag_isr! | 96 addwf isr_xC+1,F |
96 movff isr_sub_c,isr_xA | 97 movlw HIGH(.10000) |
97 movff isr_sub_c+1,isr_xA+1 | 98 addwfc isr_xC+2,F |
98 movff xdT+0,isr_xB | 99 |
99 movff xdT+0+1,isr_xB+1 | 100 movf C2+0,W ; Add C2, and save into OFF |
100 call isr_mult16x16 ; (C4-250)*dT | 101 addwf isr_xC+1,W |
101 movff isr_xC+0,isr_divA | 102 movwf OFF+0 |
102 movff isr_xC+1,isr_divA+1 | |
103 movlw d'12' | |
104 movwf isr_divB | |
105 call isr_div16 ; [(C4-250)*dT]/2^12 | |
106 movff isr_divA+0,isr_xC+0 | |
107 movff isr_divA+1,isr_xC+1 ; isr_xC= {[(C4-250)*dT]/2^12} | |
108 btfss neg_flag_isr ; neg_flag_isr=1? | |
109 bra OFF_calc2 ; Yes, do C2 - isr_xC | |
110 ; no, so do C2 + isr_xC | |
111 movf C2+0,W | |
112 addwf isr_xC+0, f | |
113 movf C2+1,W | 103 movf C2+1,W |
114 addwfc isr_xC+1, f ; isr_xC= C2 + {[(C4-250)*dT/2^12]} | 104 addwfc isr_xC+2,W |
115 OFF_calc3: | 105 movwf OFF+1 |
116 movlw LOW d'10000' | 106 |
117 addwf isr_xC+0, f | 107 ; Calculate SENS = C1/2 + ((C3+200)*dT)/2^13 + 3000 |
118 movlw HIGH d'10000' | 108 movlw LOW(.200) ; C3+200 --> A |
119 addwfc isr_xC+1, f ; isr_xC=[(C4-250)*dT/2^12] + 10000 | 109 addwf C3+0,W |
120 movff isr_xC+0,OFF+0 | 110 movwf isr_xA+0 |
121 movff isr_xC+1,OFF+1 | 111 movlw HIGH(.200) |
122 bra calculate_SENS ; Done with OFF | 112 addwfc C3+1,W |
123 | 113 movwf isr_xA+1 |
124 OFF_calc2: | 114 ; B still contains dT2 |
125 movff C2+0,isr_sub_a+0 | 115 call isr_signed_mult16x16 ; A*B --> C |
126 movff C2+1,isr_sub_a+1 | 116 movlw .13-.8 ; A 13bit shift = 1 byte + 5 bits. |
127 movff isr_xC+0,isr_sub_b+0 | 117 call isr_shift_C31 |
128 movff isr_xC+1,isr_sub_b+1 | 118 |
129 call isr_sub16 ; isr_sub_c = isr_sub_a - isr_sub_b | 119 bcf STATUS,C ; SENS = C1 / 2 |
130 ; isr_xC= C2 - {[(C4-250)*dT/2^12]} | 120 rrcf C1+1,W |
131 movff isr_sub_c+0,isr_xC+0 | 121 movwf SENS+1 |
132 movff isr_sub_c+1,isr_xC+1 ; Done with OFF | 122 rrcf C1+0,W |
133 bra OFF_calc3 | 123 movwf SENS+0 |
134 | 124 |
135 calculate_SENS: | 125 movlw LOW(.3000) ; Add 3000 |
136 movff C3+0, C3_temp+0 | 126 addwf isr_xC+1,F |
137 movff C3+1, C3_temp+1 | 127 movlw HIGH(.3000) |
138 movlw d'200' | 128 addwfc isr_xC+2,F |
139 addwf C3_temp+0, f | 129 |
140 movlw d'0' | 130 movf isr_xC+1,W ; And sum into SENS |
141 addwfc C3_temp+1, f ; C3 no longer valid! | 131 addwf SENS+0,F |
142 movff C3_temp+0, isr_xA | 132 movf isr_xC+2,W |
143 movff C3_temp+1, isr_xA+1 | 133 addwfc SENS+1,F |
144 movff xdT+0, isr_xB | 134 |
145 movff xdT+1, isr_xB+1 | 135 ; calculate amb_pressure = (sens * (d1-off))/2^12 + 1000 |
146 call isr_mult16x16 | 136 movf OFF+0,W ; d1-off --> a |
147 movff isr_xC+0,isr_divA | 137 subwf D1+0,W |
148 movff isr_xC+1,isr_divA+1 | 138 movwf isr_xA+0 |
149 movlw d'13' | 139 movf OFF+1,W |
150 movwf isr_divB | 140 subwfb D1+1,W |
151 call isr_div16 | 141 movwf isr_xA+1 |
152 movff isr_divA,SENS+0 | 142 |
153 movff isr_divA+1,SENS+1 | 143 movff SENS+0,isr_xB+0 ; sens --> b |
154 movff C1+0,isr_divA | 144 movff SENS+1,isr_xB+1 |
155 movff C1+1,isr_divA+1 | 145 call isr_signed_mult16x16 |
156 movlw d'1' | 146 movlw .12-.8 ; a 12bit shift = 1 byte + 4 bits. |
157 movwf isr_divB | 147 call isr_shift_C31 |
158 call isr_div16 | 148 |
159 movf isr_divA,W | 149 movlw LOW(.1000) ; add 1000, and save into amb_pressure |
160 addwf SENS+0, f | 150 addwf isr_xC+1,W |
161 movf isr_divA+1,W | 151 movwf amb_pressure+0 |
162 addwfc SENS+1, f | 152 movlw HIGH(.1000) |
163 movlw d'184' | 153 addwfc isr_xC+2,W |
164 addwf SENS+0, f | 154 movwf amb_pressure+1 |
165 movlw d'11' | |
166 addwfc SENS+1, f | |
167 | |
168 ; calculate amb_pressure | |
169 movff D1+0,isr_sub_a | |
170 movff D1+1,isr_sub_a+1 | |
171 movff OFF+0,isr_sub_b | |
172 movff OFF+1,isr_sub_b+1 | |
173 call isr_sub16 | |
174 movff isr_sub_c,isr_xA | |
175 movff isr_sub_c+1,isr_xA+1 | |
176 movff SENS+0,isr_xB | |
177 movff SENS+1,isr_xB+1 | |
178 call isr_mult16x16 | |
179 movlw d'12' | |
180 movwf isr_divB | |
181 call isr_div32 | |
182 btfsc neg_flag_isr ; invert isr_xC+0 and isr_xC+1 | |
183 call isr_invert_xC | |
184 movlw LOW d'1000' | |
185 addwf isr_xC+0, f | |
186 movlw HIGH d'1000' | |
187 addwfc isr_xC+1, f | |
188 movff isr_xC+0,amb_pressure+0 | |
189 movff isr_xC+1,amb_pressure+1 | |
190 | 155 |
191 btfss simulatormode_active ; are we in simulator mode? | 156 btfss simulatormode_active ; are we in simulator mode? |
192 bra calc_pressure_done ; no | 157 bra calc_pressure_done ; no |
193 | 158 |
194 movff sim_pressure+0,amb_pressure+0 ; override readings with simulator values | 159 movff sim_pressure+0,amb_pressure+0 ; override readings with simulator values |
195 movff sim_pressure+1,amb_pressure+1 | 160 movff sim_pressure+1,amb_pressure+1 |
196 | 161 |
197 calc_pressure_done: | 162 calc_pressure_done: |
198 | 163 ; calculate temp = 200 + dT*(C6+100)/2^11 |
199 ; calculate temp | 164 movlw LOW(.100) ; C6 + 100 --> A |
200 movff C6+0, C3_temp+0 | 165 addwf C6+0,W |
201 movff C6+1, C3_temp+1 | 166 movwf isr_xA+0 |
202 movlw d'100' | 167 movlw HIGH(.100) |
203 addwf C3_temp+0, f | 168 addwfc C6+1,W |
204 movlw d'0' | 169 movwf isr_xA+1 |
205 addwfc C3_temp+1, f | 170 |
206 movff C3_temp+0,isr_xA+0 | 171 movff xdT2+0,isr_xB+0 ; dT2 --> B |
207 movff C3_temp+1,isr_xA+1 | 172 movff xdT2+1,isr_xB+1 |
208 movff xdT2+0,isr_xB+0 | 173 call isr_signed_mult16x16 ; A*B |
209 movff xdT2+1,isr_xB+1 | 174 movlw .11-.8 ; A 12bit shift = 1 byte + 3 bits. |
210 call isr_mult16x16 | 175 call isr_shift_C31 |
211 movlw d'11' | 176 |
212 movwf isr_divB | 177 movlw LOW(.200) ; Add 200, and save into temperature |
213 call isr_div32 | 178 addwf isr_xC+1,W |
214 bcf neg_temp ; Temperatur positive | 179 movwf temperature+0 |
215 | 180 movlw HIGH(.200) |
216 btfsc neg_flag_xdT ; was xdT negative? | 181 addwfc isr_xC+2,W |
217 bra neg_sub_temp ; yes, 200 - dT*(.... | 182 movwf temperature+1 |
218 ; No, 200 + dT*(.... | 183 |
219 ; movf temperature_correction,W | 184 bcf neg_temp |
220 ; addlw d'200' | 185 bnn calc_pos_temp ; Is Temp° negativ ? |
221 ; btfsc STATUS,C | 186 |
222 ; incf isr_xC+1,F | 187 bsf neg_temp ; Yes: set flag and store -temp |
223 | 188 comf temperature+1 |
224 movlw d'200' | 189 negf temperature+0 |
225 addwf isr_xC+0, f | 190 btfsc STATUS,C |
226 movlw d'0' | 191 incf temperature+1 |
227 addwfc isr_xC+1, f | 192 |
228 movff isr_xC+0,temperature+0 | 193 calc_pos_temp: |
229 movff isr_xC+1,temperature+1 | 194 return ; Fertig mit allem |
230 return ; done | |
231 | |
232 neg_sub_temp: ; 200 - dT*(.... | |
233 ; movf temperature_correction,W | |
234 ; addlw d'200' | |
235 ; btfsc STATUS,C | |
236 ; decf isr_xC+1,F | |
237 | |
238 movlw d'200' | |
239 neg_sub_temp3: | |
240 movwf isr_sub_a+0 | |
241 clrf isr_sub_a+1 | |
242 movff isr_xC+0, isr_sub_b+0 | |
243 movff isr_xC+1, isr_sub_b+1 | |
244 call isr_sub16 ; isr_sub_c = isr_sub_a - isr_sub_b | |
245 btfsc neg_flag_isr ; below zero? | |
246 bsf neg_temp ; temperature negative! | |
247 | |
248 movff isr_sub_c+0,temperature+0 | |
249 movff isr_sub_c+1,temperature+1 | |
250 return ; Fertig mit allem | |
251 | |
252 | 195 |
253 get_pressure_start: | 196 get_pressure_start: |
254 rcall reset_MS5535A | 197 rcall reset_MS5535A |
255 movlw b'10100000' ;+3*high as start and 1+low as stop! | 198 movlw b'10100000' ;+3*high as start and 1+low as stop! |
256 get_pressure_start2: | 199 get_pressure_start2: |