code [code@mxhub.net] says:
I have written a asm recently for reading temperature with [the Dallas] ds18s20 and putting it out to a LCD. You might find some help in it
LIST P=16F84A ; 16F84A Runs at 10 MHz INCLUDE "p16f84a.inc" __CONFIG _PWRTE_ON & _HS_OSC & _WDT_OFF ; uses 10 MHz crystal ERRORLEVEL -224 ; supress annoying message from tris ERRORLEVEL -302 ; supress message from page change ; Define Information #DEFINE RS PORTA, 0 ; RA0 is RS line of LCD #DEFINE E PORTA, 1 ; RA1 is E line of LCD CONSTANT DATA_PIN=4 CONSTANT BASE_VAR=0C CONSTANT DATA_BUFF=28H CONSTANT BUFF_SIZE=7 N EQU BASE_VAR+0 INDEX EQU BASE_VAR+1 ; these vars used by the O_BYTE EQU BASE_VAR+2 ; common 1-wire routines I_BYTE EQU BASE_VAR+3 TEMP EQU BASE_VAR+4 LOOP1 EQU BASE_VAR+5 ; used for timing TEMP_1 EQU BASE_VAR+6 ; used for calculating CRC DATA_BIT EQU BASE_VAR+7 SHIFT_REG EQU BASE_VAR+8 FB EQU BASE_VAR+9 TEMP_MSB EQU DATA_BUFF+0 ; first location in DATA_BUFF TEMP_LSB EQU DATA_BUFF+1 TH_R EQU DATA_BUFF+2 TL_R EQU DATA_BUFF+3 COUNTREMAIN EQU DATA_BUFF+4 COUNTPERC EQU DATA_BUFF+5 CRC EQU DATA_BUFF+6 ; Macro EStrobe MACRO ; Strobe the "E" Bit bsf E bcf E ENDM CBLOCK 0CH countdown ; Temp ; a temporary variable count ; counter cntmsec ; used in counting milliseconds bin ; binary number to be converted to BCD hundreds ; BCD hundreds result tens_and_ones ; BCD tens and ones result ENDC ORG 0 ; start at location 0 goto MAIN ; jump over to main routine ;----------------------------------------------------------------------; ; Initialize the ports ; ;----------------------------------------------------------------------; Init: clrf PORTA clrf PORTB movlw B'00011100' ; RA4, RA2 input, others outputs tris PORTA movlw B'00110000' ; RB4, RB5 input, others outputs tris PORTB movlw B'00100011' ; pull-ups enabled ; prescaler assigned to RA4 ; prescaler set to 1:16 option return ;----------------------------------------------------------------------; ; Initialize the LCD ; ;----------------------------------------------------------------------; initlcd: movlw D'40' call nmsec ; Wait 40 msecs before Reset bcf RS ; send an 8 bit instruction movlw 0x03 ; Reset Command call NybbleOut ; Send the Nybble call Dlay5 ; Wait 5 msecs before Sending Again EStrobe call Dlay160 ; Wait 160 usecs before Sending 2nd Time EStrobe call Dlay160 ; Wait 160 usecs before Sending 3rd Time bcf RS ; send an 8 bit instruction movlw 0x02 ; Set 4 Bit Mode call NybbleOut call Dlay160 movlw 0x028 ; 4 bit, 2 Line, 5x7 font call SendINS movlw 0x010 ; display shift off call SendINS movlw 0x001 ; Clear the Display RAM call SendINS call Dlay5 ; Note, Can take up to 4.1 msecs movlw 0x006 ; increment cursor call SendINS movlw 0x00C ; display on cursor off call SendINS return ;----------------------------------------------------------------------; ; Send the character in W out to the LCD ; ;----------------------------------------------------------------------; SendASCII addlw '0' ; Send nbr as ASCII character SendCHAR ; Send the Character to the LCD movwf Temp ; Save the Temporary Value swapf Temp, w ; Send the High Nybble bsf RS ; RS = 1 call NybbleOut movf Temp, w ; Send the Low Nybble bsf RS call NybbleOut return ;----------------------------------------------------------------------; ; Send an instruction in W out to the LCD ; ;----------------------------------------------------------------------; SendINS ; Send the Instruction to the LCD movwf Temp ; Save the Temporary Value swapf Temp, w ; Send the High Nybble bcf RS ; RS = 0 call NybbleOut movf Temp, w ; Send the Low Nybble bcf RS call NybbleOut return ;----------------------------------------------------------------------; ; Send the nibble in W out to the LCD ; ;----------------------------------------------------------------------; NybbleOut ; Send a Nybble to the LCD movwf PORTB EStrobe ; Strobe out the LCD Data call Dlay160 ; delay for 160 usec return ;----------------------------------------------------------------------; ; Change binary nbr in bin to BCD ; ;----------------------------------------------------------------------; binary_to_bcd ; by Scott Dattalo clrf hundreds swapf bin, W addwf bin, W andlw B'00001111' skpndc addlw 0x16 skpndc addlw 0x06 addlw 0x06 skpdc addlw -0x06 btfsc bin,4 addlw 0x16 - 1 + 0x6 skpdc addlw -0x06 btfsc bin,5 addlw 0x30 btfsc bin, 6 addlw 0x60 btfsc bin,7 addlw 0x20 addlw 0x60 rlf hundreds, f btfss hundreds, 0 addlw -0x60 movwf tens_and_ones btfsc bin,7 incf hundreds, f return ;----------------------------------------------------------------------; ; time delay routines ; ;----------------------------------------------------------------------; Dlay160: movlw D'40' ; delay about 160 usec,(4/loop ) micro4 addlw H'FF' ; subtract 1 from 'W' nop nop nop nop nop nop btfss STATUS,Z ; skip when you reach zero goto micro4 ; more loops return Dlay5: movlw 5 ; delay for 5 milliseconds goto $ + 2 msec250: movlw D'250' ; delay for 250 milliseconds ;*** N millisecond delay routine *** nmsec: movwf cntmsec ; delay for N (in W) millisec msecloop: movlw D'248' ; 1 usec for load call micro4 ; this instruction takes 995 usec nop ; 1 usec decfsz cntmsec,f ; 1 usec, (2 if skip taken) goto msecloop ; 2 usec here makes 995+5=1 msec return ;----------------------------------------------------------------------; ; Display binary value in W in decimal ; ; ;----------------------------------------------------------------------; DispDec movwf bin call binary_to_bcd movf hundreds, W call SendASCII swapf tens_and_ones, W andlw H'F' call SendASCII movf tens_and_ones, W andlw H'F' call SendASCII return ;----------------------------------------------------------------------; ; The Main routine ; ;----------------------------------------------------------------------; MAIN: call Init ; initialize ports, set up timer call initlcd ; initialize the LCD MAIN1: CALL INITDS1820 ; init DS1820 MOVLW 0CCH ; skip ROM MOVWF O_BYTE CALL OUT_BYTE MOVLW 44H ; perform temperature conversion MOVWF O_BYTE CALL OUT_BYTE CALL WAIT ; wait for conversion to complete ; wait for all ones from 1820 CALL INITDS1820 MOVLW 0CCH ; skip ROM MOVWF O_BYTE CALL OUT_BYTE MOVLW 0BEH ; read scratchpad MOVWF O_BYTE CALL OUT_BYTE CALL IN_BYTE ; get from DS1820 and save movwf TEMP_LSB CALL IN_BYTE movwf TEMP_MSB movlw 0x001 ; Clear the Display RAM call SendINS call Dlay5 ; Note, Can take up to 4.1 msecs movlw 0x006 ; increment cursor call SendINS movlw 0x00C ; display on cursor off call SendINS movlw "A" call SendCHAR movlw "m" call SendCHAR movlw " " call SendCHAR movlw "T" call SendCHAR movlw "e" call SendCHAR movlw "m" call SendCHAR movlw "p" call SendCHAR movlw ":" call SendCHAR movlw " " call SendCHAR rrf TEMP_MSB, f btfsc STATUS, C goto dispnega movlw "+" call SendCHAR goto showlsb dispnega: movlw "-" call SendCHAR goto showlsb showlsb: bcf STATUS, C rrf TEMP_LSB, f btfsc STATUS, C goto got5 movf TEMP_LSB,0 CALL DispDec ; display the value movlw "." call SendCHAR movlw "0" call SendCHAR CALL msec250 GOTO displayrest got5: movf TEMP_LSB,0 CALL DispDec ; display the value movlw "." call SendCHAR movlw "5" call SendCHAR displayrest: movlw "C" call SendCHAR CALL msec250 GOTO MAIN1 ; do it again ; The following are standard 1-Wire routines. INITDS1820: CALL PIN_HI CALL PIN_LO MOVLW 50 ; 500 us delay CALL DELAY_10USEC CALL PIN_HI MOVLW 50 ; 500 usec delay CALL DELAY_10USEC RETURN WAIT: CALL IN_BYTE MOVLW 0FFH SUBWF I_BYTE, W BTFSS STATUS, Z GOTO WAIT RETURN IN_BYTE: ; returns byte in W MOVLW 8 MOVWF INDEX CLRF I_BYTE IN_BYTE_1: CALL PIN_LO ; momentary low on DATA_PIN NOP NOP NOP CALL PIN_HI NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP MOVF PORTA, W ; 7 usecs later, fetch from DATA_PIN MOVWF TEMP BTFSS TEMP, 4 BCF STATUS, C ; its a zero BTFSC TEMP, 4 BSF STATUS, C ; its a one RRF I_BYTE, F MOVLW 6 ; now delay 60 usecs CALL DELAY_10USEC DECFSZ INDEX, F GOTO IN_BYTE_1 MOVFW I_BYTE ; return the result in W RETURN OUT_BYTE: MOVLW 8 MOVWF INDEX OUT_BYTE_1: RRF O_BYTE, F BTFSS STATUS, C GOTO OUT_0 GOTO OUT_1 OUT_BYTE_2: DECFSZ INDEX, F GOTO OUT_BYTE_1 RETURN OUT_0: CALL PIN_LO ; bring DATA_PIN low MOVLW 6 ; for 60 usecs CALL DELAY_10USEC CALL PIN_HI GOTO OUT_BYTE_2 OUT_1: CALL PIN_LO ; momentary low CALL PIN_HI MOVLW 6 CALL DELAY_10USEC GOTO OUT_BYTE_2 ;;;;;; PIN_HI: BSF STATUS, RP0 BSF TRISA, DATA_PIN ; high impedance BCF STATUS, RP0 RETURN PIN_LO: BCF PORTA, DATA_PIN BSF STATUS, RP0 BCF TRISA, DATA_PIN ; low impedance zero BCF STATUS, RP0 RETURN DELAY_10USEC: ; provides a delay equal to W * 10 usecs MOVWF LOOP1 DELAY_10USEC_1: NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP NOP DECFSZ LOOP1, F GOTO DELAY_10USEC_1 RETURN end
Ruben Jönsson [rubenj@pp.sbbs.se] says:
HiI have built an RS485 master/slave networked temperature measurement system were each RS485 node can connect to up to 32 DS18S20 devices on a 1-wire network.
The system is used for measuring temperatures on grain at different heights in a grain bin. The temp sensors are inside a cable that is hanging from the ceiling in the bin. Each cable is connected to one RS485 node.
The network is connected to a PC which displays a physical layout of the site (could be a picture or a scanned blueprint) with temperature values overlayed on the image at different colors depending on alarm and warning levels.
The board for the RS485 node is equiped with 1 SX18 processor at 4MHz, 1 24LC16 EEPROM for storing the 1-wire device addresses of each sensor connected to this node (the addresses are automatically scanned and detected with a ROM search upon power up), the 485 circuitry (2400bps, half duplex), interface circuitry for the 1-wire, 2 BCD switches to set the address of the node and 2 leds for status indication.
I have also done a version of this board that is a stand alone hand held battery operated unit with an LCD and two buttons. This is limited to cables with max 14 1-wire tempsensors.
I have used the EEPROM in the 1820 sensor to store an index number of the physical location of the sensor on the 1-wire network in the cable. When the device address is found during the ROM search I know at which height level this sensor is located in this cable.
==============================
Ruben Jönsson
AB Liros Elektronik
Box 9124, 200 39 Malmö, Sweden
TEL INT +46 40142078
FAX INT +46 40947388
ruben@pp.sbbs.se
==============================
See:
Questions:
HI,James Newton replies: See: PIC LCD routines
I'm facing some problems in programming the LCD with the assemply language.
I need to know how to program the LCD to interface it with the PIC 16F877.
Regards,
Sara K.
Hi,
I am having trouble with my Maxim DS18S20 sensor which I am trying to interface with PIC16F877. To test the sensor, I am trying to transmit the temperature byte by implementing USART. I get some kind of output on the DQ pin, which I see using an oscilloscope. But the output that I get is 8 bits which are all ones, followed by an almost equal interval of the pin driven low and then it is back to its high impedance state. Another question I have is... if I am using a 4 MHz crystal, then one instruction is executed in 1 us or 0.25 us. Any help on this would be appreciated greatly. Thank you very much.