1 ;; pm.asm 2 ;; 3 4 list p=16c84 5 6include "p16c84.inc" 7 8 cblock 0x0c 9 10 lo,hi,_upper,kz 11 endc 12 13ioport equ portb 14iobit equ 0 15 16 17 org 0 18 19start: 20 clrf lo 21 clrf hi 22 clrf _upper ;Used as a known zero in 23 ;the loop 24 call cnt16bit 25 26 27 goto start 28 29measure: 30;----------------------------------------------- 31;pulse width measurements with 3 Tcyc resolution 32; 33;The purpose of this routine is to accurately measure 34;the width of a pulse. The resolution is 3 instruction 35;cycles and the dynamic range is 19 bits or 3*2^19 cycles. 36;(That's 1,572,864 cycles which is approximately pi/10 37;seconds on a 20Mhz pic.) 38; 39; 40 41 btfsc ioport,iobit 42 goto $-1 43 44loop 45 btfsc ioport,iobit ;If the pulse is over 46 goto high0 ;then adjust the count 47 ; 48 movlw 1 ;Otherwise, intertwine the counter 49 ;incrementing with the pulse checking 50 btfsc ioport,iobit ; 51 goto high1 ; 52 ; 53 addwf lo,f ;Increment the lo byte 54 ; 55 btfsc ioport,iobit ; 56 goto high2 ; 57 ; 58 rlf _upper,w ;Pick up the carry (if lo byte 59 ;overflowed) 60 btfsc ioport,iobit ; 61 goto high3 ; 62 ; 63 addwf hi,f ;Increment the high byte 64 ; 65 btfsc ioport,iobit ; 66 goto high4 ; 67 ; 68 skpc ;If the high byte rolls over 69 btfsc ioport,iobit ;or the pulse is over 70 goto high5_or_done ;then get out of the loop 71 ; 72 clrwdt ;Could be a nop or some inst. 73 ; 74 btfsc ioport,iobit ; 75 goto high6 ; 76 ; 77 nop ; 78 ; 79 btfss ioport,iobit ;Note that we check the opp. level 80 goto loop ; 81 82 ;fall through... Add 7 to the total count 83 84 incf _upper,f 85 86high6: 87 incf _upper,f 88 89high5_or_done: 90 skpnc ;If c=1 then we have an 91 goto overflow ;overflow 92 93 incf _upper,f 94 95high4: 96 incf _upper,f 97 98high3: 99 incf _upper,f 100 101high2: 102 decf lo,f ;Get rid of the extra 103 ;increment of the lo byte 104 incf _upper,f 105 106high1: 107 incf _upper,f 108 109high0: 110 111 112 rlf _upper,f 113 114 rlf lo,f 115 rlf hi,f 116 rlf _upper,f 117 118 rlf lo,f 119 rlf hi,f 120 rlf _upper,f 121 122 rlf lo,f 123 rlf hi,f 124 rlf _upper,f 125 126 swapf _upper,w 127 andlw 7 128 iorwf lo,f 129 130 movlw 7 131 andwf _upper,f 132 133 retlw 0 134 135overflow 136 ;If we get here, then there was an overflow. 137 ;it turns out that all three bytes of the 138 ;counter are zero. Decrementing all three 139 ;will set them to 0xff. 140 141 decf _upper,f 142 decf hi,f 143 decf lo,f 144 145 retlw 0xff 146 147 148CONST EQU 0 149CNT_PER_LOOP EQU 7 150 151cnt16bit: 152 clrf kz 153 clrf lo 154 clrf hi 155 156 157 movlw CNT_PER_LOOP ;preset counts 158 159 btfsc ioport,iobit 160 goto $-1 161 162loop1 btfsc ioport,iobit 163 goto quit1 ;1 164 165 addwf lo,f ;inc lo cnt 166 btfsc ioport,iobit 167 goto quit2 ;2 168 169 rlf kz,w ;get carry 170 btfsc ioport,iobit 171 goto quit3 ;3-2 172 173 addwf hi,f ;hi incremented depends on carry 174 btfsc ioport,iobit 175 goto quit4 ;4-2 176 177 skpc ;check if already finished 178 btfsc ioport,iobit 179 goto quit5 ;5-2 180 181 movlw CNT_PER_LOOP ;add uncounted tests 182 btfsc ioport,iobit 183 goto quit6 ;6-2 184 185 btfss ioport,iobit 186 goto loop1 187 ;7-2 188 189quit7 incf kz,f ;add uncounted tests 190quit6 incf kz,f 191 192 193quit5 skpnc 194 goto overflow1 195 196 movlw -CNT_PER_LOOP + 4 ; 197 addwf kz,w 198 addwf lo,f 199 skpc 200 decf hi,f 201 clrf kz 202 return 203 204quit4 incf kz,f 205 subwf hi,f ;counter-act the addwf 206 207quit3 incf kz,f 208quit2 209 ;subtract the 7 added in above - the incf's 210 ;will keep track of how much needs to be added 211 ;back. ignore the C, since the loop didn't get 212 ;a chance to handle it. 213 214 movlw -CNT_PER_LOOP + 1 ;+1 in lieu of incf kz,f 215 addwf lo,f 216 217quit1 incf kz,w 218 219 addlw CONST ;take into account 220 ;initial latency 221 addwf lo,f 222 skpnc 223 incf hi,f 224 225 clrf kz 226 227 return 228 229overflow1 230 movlw 0xff 231 movwf lo 232 movwf hi 233 clrf kz 234 return 235 236 237 end 238