; LM75.ASM ; ; Written by Aaron Hickman ; Added to PIC archive: 21/May/1998 LIST p=16c84 #include __CONFIG 11h CONSTANT VARS=0CH CONSTANT SCL=7 CONSTANT SDA=6 ; bits on Portb defined CONSTANT TX=5 DEVICE_ADR EQU VARS+0 ; A2 A1 A0 address O_BYTE EQU VARS+1 ; byte sent on I2C bus I_BYTE EQU VARS+2 ; byte received on I2C bus _N EQU VARS+3 ; index _25US_LOOP EQU VARS+4 ; timing IN_BYTE_MSB EQU VARS+5 IN_BYTE_LSB EQU VARS+6 BCD_0 EQU VARS+7 BCD_1 EQU VARS+8 BCD_2 EQU VARS+9 COUNT EQU VARS+10 TEMP EQU VARS+11 DATA_BYTE EQU VARS+12 SEROUT_LP EQU VARS+13 BAUD_RATE EQU VARS+14 DELAY_A EQU VARS+15 DELAY_B EQU VARS+16 DELAY_LP1 EQU VARS+17 DELAY_LP2 EQU VARS+18 FRACTION EQU VARS+19 ORG 000H MOVLW 90H MOVWF DEVICE_ADR MOVLW 0EH MOVWF BAUD_RATE CONFIG_PORTS: BSF STATUS, RP0 ; select Bank 1 MOVLW 1FH ; PORTB bits 7,6 & 4 = outputs and 4-0 & 5 = inputs MOVWF TRISB BCF STATUS, RP0 ; select Bank 0 READ_LM75: CALL START MOVF DEVICE_ADR, W IORLW 01H MOVWF O_BYTE CALL OUT_BYTE CALL NACK CALL IN_BYTE CALL ACK MOVF I_BYTE, W MOVWF IN_BYTE_LSB CALL IN_BYTE CALL NACK CALL STOP MOVF I_BYTE, W MOVWF FRACTION CLRF IN_BYTE_MSB MOVLW 0CH CALL DISPLAY BTFSS IN_BYTE_LSB, 7 GOTO POSITIVE MOVLW '-' CALL DISPLAY COMF IN_BYTE_LSB, W MOVWF IN_BYTE_LSB GOTO FINISHUP POSITIVE: MOVLW '+' CALL DISPLAY FINISHUP: CALL BIN_BCD MOVF BCD_1, W CALL ASCII_LOW CALL DISPLAY MOVF BCD_2, W CALL ASCII_HIGH CALL DISPLAY MOVF BCD_2, W CALL ASCII_LOW CALL DISPLAY MOVLW '.' CALL DISPLAY BTFSC FRACTION, 7 MOVLW '5' BTFSS FRACTION, 7 MOVLW '0' CALL DISPLAY MOVLW 0xDF CALL DISPLAY MOVLW 'C' CALL DISPLAY CALL DELAY CALL DELAY GOTO READ_LM75 DISPLAY: CALL OUT_SER_CHAR CALL DELAY_100US RETURN ;************************************************************************ ; The BCD values resulting from the CONVERT subroutine * ; are transmited via RS-232 protocol to a PC using the * ; following subroutine. The 8-bit values are sent using * ; the 8,N,1 format at 9600 baud (assuming a 2MHz ceramic * ; clock). * ;************************************************************************ OUT_SER_CHAR: MOVWF DATA_BYTE MOVLW .9 MOVWF SEROUT_LP BCF STATUS, C SEROUT1: BTFSC STATUS, C BCF PORTB, TX BTFSS STATUS, C BSF PORTB, TX MOVFW BAUD_RATE MOVWF DELAY_A MOVFW BAUD_RATE MOVWF DELAY_B SEROUT2: DECFSZ DELAY_A, F GOTO SEROUT2 RRF DATA_BYTE, F DECFSZ SEROUT_LP, F GOTO SEROUT1 BCF PORTB, TX NOP NOP SEROUT3: DECFSZ DELAY_B, F GOTO SEROUT3 NOP RETURN ;********************************************************************** ; Unpack the BCD values stored in R1 and R2, ignoring R0. * ;********************************************************************** ASCII_HIGH: ANDLW 0xF0 MOVWF DATA_BYTE SWAPF DATA_BYTE, W ADDLW 30H RETURN ASCII_LOW: ANDLW 0x0F ADDLW 30H RETURN ;************************************************************ ; Delay subroutine for general use. * ;************************************************************ DELAY: MOVLW 0xFF MOVWF DELAY_LP1 DELAY_1: MOVLW 0xFF MOVWF DELAY_LP2 DELAY_2: NOP DECFSZ DELAY_LP2, F GOTO DELAY_2 DECFSZ DELAY_LP1, F GOTO DELAY_1 RETURN DELAY_100US: MOVLW .20 MOVWF DELAY_LP1 DELAY_100US_1: NOP NOP DECFSZ DELAY_LP1, F GOTO DELAY_100US_1 RETURN ;**************************************************************** ; This routine converts a 16 bit binary number * ; to a 5 digit BCD number. The 16 bit binary * ; input locations are IN_BYTE_MSB and IN_BYTE_LSB. * ; The 5 digit BCD number is returned in BCD_0, * ; BCD_1 and BCD_2 with BCD_0 containing the most * ; significant digit in the low order nibble. * ;**************************************************************** BIN_BCD: BCF STATUS, 0 MOVLW 10H MOVWF COUNT CLRF BCD_0 CLRF BCD_1 CLRF BCD_2 LOOP16: RLF IN_BYTE_LSB, F RLF IN_BYTE_MSB, F RLF BCD_2, F RLF BCD_1, F RLF BCD_0, F DECFSZ COUNT, F GOTO ADJ_DEC RETLW 0 ADJ_DEC: MOVLW BCD_2 MOVWF FSR CALL ADJ_BCD MOVLW BCD_1 MOVWF FSR CALL ADJ_BCD MOVLW BCD_0 MOVWF FSR CALL ADJ_BCD GOTO LOOP16 ADJ_BCD: MOVLW 3 ADDWF 0, W MOVWF TEMP BTFSC TEMP, 3 MOVWF 0 MOVLW 30 ADDWF 0, W MOVWF TEMP BTFSC TEMP, 7 MOVWF 0 RETLW 0 ; The following routines are low level I2C routines applicable to most ; interfaces with I2C devices. IN_BYTE ; read byte on i2c bus CLRF I_BYTE MOVLW .8 MOVWF _N ; set index to 8 CALL HIGH_SDA ; be sure SDA is configured as input IN_BIT CALL HIGH_SCL ; clock high BTFSS PORTB, SDA ; test SDA bit GOTO IN_ZERO GOTO IN_ONE IN_ZERO BCF STATUS, C ; clear any carry RLF I_BYTE, F ; i_byte = i_byte