Digital barometerจาก
http://mcs.uwsuper.edu/sb/Electronics/Baro/

PIC source code
TITLE "baro.asm" ; atmospheric pressure
List P=PIC16F684, R=DEC
INCLUDE "p16f684.inc"
SCL EQU 2 ; Clock line setup
SDA EQU 1 ; Data line setup
CORR EQU 6832 + 186
; data segment
CBLOCK 0x20
del, cnt, temp ; local variables
bar:2 ; storage for pressure
bcd:2
i, dataIO
ENDC
; code segment
__CONFIG _FCMEN_OFF & _IESO_OFF & _BOD_OFF & _CPD_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
ORG 0
bcf STATUS, RP0 ; switch to BANK 0
clrf PORTA ; initialize PORT A
clrf PORTC ; initialize PORT C
movlw 0x07
movwf CMCON0 ; comparators OFF
bsf STATUS, RP0 ; switch to BANK 1
; ADC and ports configuration
clrf TRISA ^ 0x80 ; configure PORTA for output
movlw b'011100'
movwf TRISC ^ 0x80
movlw b'10000000'
movwf ANSEL ^ 0x80 ; configure RC3 as analog input
movlw b'01110000' ; set ADC Frc clock
movwf ADCON1 ^ 0x80
bcf STATUS, RP0 ; back to BANK 0
movlw b'00011101'
movwf ADCON0 ; left justify, Vdd Vref, AN7, On
loop
movlw 250
movwf del
call delay ; 250 msec delay
movlw 250
movwf del
call delay ; 250 msec delay
bsf ADCON0, GO ; start ADC operation
btfsc ADCON0, GO ; and wait for its completion
goto $-1
movf ADRESH, w ; get high 8 bits of ADC
; movlw 250
; compute bar*6 + CORR
movwf bar ; multiply bar by 6
clrf bar+1
rlf bar, f ; bar *= 2
rlf bar+1, f
bcf bar, 0
addwf bar, f ; bar *= 3
btfsc STATUS, C
incf bar+1, f
rlf bar, f ; bar *= 6
rlf bar+1, f
bcf bar, 0
movlw low CORR ; add corr constant
addwf bar, f
btfsc STATUS, C
incf bar+1, f
movlw high CORR ; bar = pressure*10
addwf bar+1, f ; (max 4 decimal digits)
call baro2BCD
; movlw 5
; addwf bcd+1, f
call writeMSG
goto loop ; endless loop
; procedures
baro2BCD
movlw 16 ; 16-bits
movwf temp ; make cycle counter
clrf bcd ; clear result area
clrf bcd+1
b2bcd2
movlw bcd ; make pointer
movwf FSR
movlw 4
movwf cnt
; Mike's routine:
b2bcd3
movlw 0x33
addwf INDF, f ; add to both nybbles
btfsc INDF, 3 ; test if low result > 7
andlw 0xF0 ; low result >7 so take the 3 out
btfsc INDF, 7 ; test if high result > 7
andlw 0x0F ; high result > 7 so ok
subwf INDF, f ; any results <= 7, subtract back
incf FSR, f ; point to next
decfsz cnt, f
goto b2bcd3
rlf bar+0, f ; get another bit
rlf bar+1, f
rlf bcd+1, f ; put it into bcd
rlf bcd+0, f
decfsz temp, f ; all done?
goto b2bcd2 ; no, loop
return ; yes
msg1 ; first message to display
addwf PCL, f
dt " Pressure:", 0
msg2 ; second message to display
addwf PCL, f
dt " mmHg", 0
;*******************LCD interface
writeMSG
; output of the top row (msg1)
movlw b'10000001' ; clear display
call writeLCD
clrf i
L1 movf i, w
call msg1 ; get the next char
iorlw 0 ; end of string?
btfsc STATUS, Z
goto L2 ; YES - jump out of the loop
call writeLCD ; NO - send it to LCD
incf i, f ; update the char index
goto L1
L2 movlw 0xC0
call writeLCD ; move the cursor to the second line
clrf i ; clear the index of the second string
; output the bottom row
swapf bcd, w
andlw 0x0F
addlw 48 ; ASCII conversion
call writeLCD
movf bcd, w
andlw 0x0F
addlw 48
call writeLCD
swapf bcd+1, w
andlw 0x0F
addlw 48
call writeLCD
movlw 46 ; decimal point
movwf dataIO
call writeLCD
movf bcd+1, w
andlw 0x0F
addlw 48
call writeLCD
; output msg2
L3 movf i, w
call msg2 ; get the next char
iorlw 0 ; end of string?
btfsc STATUS, Z
goto L4 ; YES - jump out of the loop
call writeLCD ; NO - send it to LCD
incf i, f ; update the char index
goto L3
L4 return
writeLCD ; write byte in W to the LCD line
movwf dataIO
movlw b'111001'
andwf PORTC, f
movlw 0x87 ; setup FSR to point to TRISC
movwf FSR
bsf INDF, SCL ; make sure that clock is high
movlw 8
movwf cnt ; bits counter
w_loop
btfss PORTC, SCL ; wait for release of the clock line
goto $-1
bcf INDF, SCL ; set clock low
rlf dataIO, f ; get the rightmost data bit
btfss STATUS, C
bcf INDF, SDA
btfsc STATUS, C
bsf INDF, SDA ; now the data bit is on the line
goto $+1 ; short delay
bsf INDF, SCL ; raise clock up
movlw 6 ; a 20 usec delay
addlw -1
btfss STATUS, Z
goto $-2
decfsz cnt, f
goto w_loop ; repeat this 8 times
return
delay ; a delay for del milliseconds
movlw 200
sublw 1 ; this loop takes 5us*200 = 1ms
sublw 0 ; for PIC @ 4 Mhz
btfss STATUS, Z
goto $-3
decfsz del, f
goto delay
return
end