Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

PIC code Error checking help (DS1820 temp sensor)

Status
Not open for further replies.

NewGeek

New Member
When I try to compile my code I get a bunch of errors, but that's not the problem. Using MPLAB IDE 6.6
The problem is my code is only 105 lines long. The error messages say that I have errors on lines 137, 145, 160 etc. This makes debugging rather difficult as these lines dont exist.
Here is another possible clue: On some of these non-existant lines, the error is #116: "Address label duplicated or different in second pass"

This makes me think it is looping and adding line numbers somehow?

Can anyone explain this?
BTW, this code is the 1-wire protocol for Dallas DS1820 temp sensor downloaded from the Dallas website.
 
Try posting the code, I presume you're actually doing something really silly?, and hopefully it will be easy to spot?.

Make sure you surround the code with '
Code:
' and '
', selected from the buttons on the 'post a reply' page - this keeps the formatting correct - which is important!.
 
I've written C for the DS18S20. The thing to watch out for is how long interrupts might take, since the slave only holds the 0 low for so long AND if the master holds it low for long enough, the slave will interpret it as a reset. It's often hard to definitively predict how long interrupts can take if your system has any kind of complexity, so it's best to disable them for the time-critical parts of the protocol.
 
Here it is, straight from the Dallas website. The only changes Ive made are to make it PORTA, Bit 7 instead of PORTB.
I agree, its probably something really simple that Ive overlooked.
Ive actually saved this code as an "include" file that I call at the top of my LCD code file.
Im listing it separately here because the following code wont even compile on its own.
This is the first time Ive used an "include" file, other than the ones specific for the processor. Can someone explain this to me? is this any different than calling a macro?
You will also see in the code below that the variable TIME is undefined. This is how they wrote it, I havent figured that out yet either.

There are some additional notes explaining the code here:
**broken link removed**


Thanks for all the help!
Code:
; *******************************************************
;
; Dallas 1-Wire Support for PIC16F628
;
; Processor has 4MHz clock and 1µs per instruction cycle.
;
; *******************************************************


; *******************************************************
; Dallas Semiconductor 1-Wire MACROS
; *******************************************************
OW_HIZ:MACRO
      BSF           STATUS,RP0                  ; Select Bank 1 of data memory
      BSF           TRISA, 7                   ; Make DQ pin High Z
      BCF           STATUS,RP0                  ; Select Bank 0 of data memory
      ENDM
; --------------------------------------------------------
OW_LO:MACRO
      BCF           STATUS,RP0                  ; Select Bank 0 of data memory
      BCF           PORTA, 7                  ; Clear the DQ bit
      BSF           STATUS,RP0                  ; Select Bank 1 of data memory
      BCF           TRISA, 7                   ; Make DQ pin an output
      BCF           STATUS,RP0                  ; Select Bank 0 of data memory
      ENDM
; --------------------------------------------------------
WAIT:MACRO TIME
;Delay for TIME µs.
;Variable time must be in multiples of 5µs.
      MOVLW         (TIME/5)-1                  ;1µs
      MOVWF         TMP0                        ;1µs
      CALL          WAIT5U                      ;2µs
      ENDM

; *******************************************************
;       Dallas Semiconductor 1-Wire ROUTINES
; *******************************************************
WAIT5U:
;This takes 5uS to complete
      NOP                                       ;1µs
      NOP                                       ;1µs
      DECFSZ        TMP0,F                      ;1µs or 2µs
      GOTO          WAIT5U                      ;2µs
      RETLW 0                                   ;2µs
; --------------------------------------------------------
OW_RESET:
      OW_HIZ                                    ; Start with the line high
      CLRF PDBYTE                               ; Clear the PD byte
      OW_LO
      WAIT          .500                        ; Drive Low for 500µs
      OW_HIZ
      WAIT          .70                         ; Release line and wait 70µs for PD Pulse
      BTFSS         PORTA,7                    ; Read for a PD Pulse
      INCF          PDBYTE,F                    ; Set PDBYTE to 1 if get a PD Pulse
      WAIT          .400                        ; Wait 400µs after PD Pulse
      RETLW 0
; --------------------------------------------------------
DSRXBYTE: ; Byte read is stored in IOBYTE
      MOVLW         .8
      MOVWF         COUNT                       ; Set COUNT equal to 8 to count the bits
DSRXLP:
      OW_LO
      NOP
      NOP
      NOP
      NOP
      NOP
      NOP                                       ; Bring DQ low for 6µs
      OW_HIZ
      NOP
      NOP
      NOP
      NOP                                       ; Change to HiZ and Wait 4µs
      MOVF          PORTA,W                     ; Read DQ
      ANDLW         1<<DQ                       ; Mask off the DQ bit
      ADDLW         .255                        ; C=1 if DQ=1: C=0 if DQ=0
      RRF           IOBYTE,F                    ; Shift C into IOBYTE
      WAIT          .50                         ; Wait 50µs to end of time slot
      DECFSZ        COUNT,F                     ; Decrement the bit counter
      GOTO          DSRXLP
      RETLW         0
; --------------------------------------------------------
DSTXBYTE:                                       ; Byte to send starts in W
      MOVWF         IOBYTE                      ; We send it from IOBYTE
      MOVLW         .8
      MOVWF         COUNT                       ; Set COUNT equal to 8 to count the bits
DSTXLP:
      OW_LO
      NOP
      NOP
      NOP
      NOP
      NOP                                       ; Drive the line low for 5µs
      RRF           IOBYTE,F                    ; The data byte
      BTFSC         STATUS,C                    ; Check the LSB of IOBYTE for 1 or 0
      BSF           PORTA,7                    ; Drive the line high if LSB is 1
      WAIT          .60                         ; Continue driving line for 60µs
      OW_HIZ                                    ; Release the line for pullup
      NOP
      NOP                                       ; Recovery time of 2µs
      DECFSZ        COUNT,F                     ; Decrement the bit counter
      GOTO          DSTXLP
      RETLW         0
; --------------------------------------------------------
 
When a compiler give an impossible error it could be because of a bad configuration check the MPLAB prefs or configurations for your project device etc etc it could be something wrong since the compiler also gives more errors !! :lol: remember that this code is for PIC 16F628 :lol: i guess that you allready have this checked the code seems ok for me but i don't program in assembler.
It's most likelly an bad project configuration for the compiler !
 
This is the main program file witch include "#INCLUDE 1w_16f6x.inc "
The file you posted is only a macro file, you need to save that as 1w_16fx.inc and call it from your main ASM codes !...?!!!
Macro is save time but doesn't have to be saving space.
Macro can contain definitions constant and function you are intend to use repeatedly in you program, using the macro you don't need to create the code 10 times, you just call it from your main program with the fuc or var you need to use.
Try to compile only the Dallas asm and inc file first, once you get those running ad your on lines "inc" files.

I hope this helps.

STEVE


Code:
'
; *******************************************
;
; Dallas Semiconductor PIC code
;
; This code will interface a PIC16F628 microcontroller to
; a DS2761 High-Precision Li+ Battery Monitor
;
; *******************************************;
;
;                   VCC
;                     ^
;                    |
;                    |
;                    /
;                    \ Rpup
;                    /
;                    \
;                    |
; 16F628             |                   DS2761
; RB1 (pin 7) ------------------------------ DQ (pin 7)
;
; *******************************************;

;---------------------------------------------------------
; List your processor here.

      list p=16F628

; Include the processor header file here.

      #include <p16F628.inc>
;---------------------------------------------------------
; Assign the PORTB with Constants

      constant DQ=1                             ; Use RB1 (pin7) for 1-Wire
;--------------------------------------------------------
; These constants are standard 1-Wire ROM commands

      constant SRCHROM=0xF0
      constant RDROM=0x33
      constant MTCHROM=0x55
      constant SKPROM=0xCC
;---------------------------------------------------------
; These constants are used throughout the code

      cblock        0x20
             IOBYTE
             TMP0                               ; Address 0x23
             COUNT                              ; Keep track of bits
             PICMSB                             ; Store the MSB
             PICLSB                             ; Store the LSB
             PDBYTE                             ; Presence Detect Pulse
      endc
;---------------------------------------------------------
; Setup your configuration word by using __config.

; For the 16F628, the bits are:
; CP1,CP0,CP1,CP0,N/A, CPD, LVP, BODEN, MCLRE, FOSC2, PWRTE, WDTE, FOSC1, FOSC0
; CP1 and CP0 are the Code Protection bits
; CPD: is the Data Code Protection Bit
; LVP is the Low Voltage Programming Enable bit
; PWRTE is the power-up Timer enable bit
; WDTE is the Watchdog timer enable bit
; FOSC2, FOSC1 and FOSC0 are the oscillator selection bits.

; CP disabled, LVP disabled, BOD disabled, MCLR enabled, PWRT disabled, WDT disabled, INTRC I/O oscillator
; 11111100111000

      __config 0x3F38
;---------------------------------------------------------
; Set the program origin for subsequent code.

      org 0x00
      GOTO          SETUP
      NOP
      NOP
      NOP
      GOTO          INTERRUPT                   ; PC 0x04...INTERRUPT VECTOR!
;---------------------------------------------------------
INTERRUPT:
      SLEEP
;---------------------------------------------------------
; Option Register bits
; ____
; RBPU,INTEDG,TOCS,TOSE,PSA,PS2,PS1,PS0
; 7=PORTB Pullup Enable, 6=Interrupt Edge Select, 5=TMR0 Source,
; 4=TMR0 Source Edge, 3=Prescaler Assign, 2-0=Prescaler Rate Select

; 11010111
; PORTB pullups disabled,rising edge,internal,hightolow,TMR0,1:256

SETUP:
      BCF           STATUS,RP1
      BSF           STATUS,RP0                  ; Select Bank 1 of data memory
      MOVLW         0xD7
      MOVWF         OPTION_REG
      BCF           STATUS,RP0                  ; Select Bank 0 of data memory
;---------------------------------------------------------

      BCF           INTCON,7                    ; Disable all interrupts.

;---------------------------------------------------------
      GOTO          START
;---------------------------------------------------------
; Include the 1-Wire communication routines and macros

      #INCLUDE 1w_16f6x.inc
;---------------------------------------------------------
START:
;---------------------------------------------------------
GET_TEMP:
      CALL          OW_RESET                    ; Send Reset Pulse and read for Presence Detect Pulse
      BTFSS         PDBYTE,0                    ; 1 = Presence Detect Detected
      GOTO          NOPDPULSE
      MOVLW         SKPROM
      CALL          DSTXBYTE                    ; Send Skip ROM Command (0xCC)
      MOVLW         0x69
      CALL          DSTXBYTE                    ; Send Read Data Command (0x69)
      MOVLW         0x0E
      CALL          DSTXBYTE                    ; Send the DS2761 Current Register MSB address (0x0E)
      CALL          DSRXBYTE                    ; Read the DS2761 Current Register MSB
      MOVF          IOBYTE,W
      MOVWF         PICMSB                      ; Put the Current MSB into file PICMSB
      CALL          DSRXBYTE                    ; Read the DS2761 Current Register LSB
      MOVF          IOBYTE,W
      MOVWF         PICLSB                      ; Put the Current LSB into file PICLSB
      CALL          OW_RESET

NOPDPULSE:                                      ; Add some error processing here!
      SLEEP                                     ; Put PIC to sleep
;---------------------------------------------------------
      end
'
 
For the 1-wire protocol, use the RA4 pin on the 16F628 unless you need it for a second clock source. RA4 is physically limited to being an open drain pin, which is perfect for the 1-wire and you won't have to write code to keep setting and clearing the TRIS bits back and forth.

It also frees up another full complimentary pin for more useful things.
 
There ya go !
Simple wasn't it :D.
But remember that 1-Wire is fun, it takes less i/o pins but it takes much program execution time making the signal modulation !!! Since it doesn't have the data being clocked and it has a very specific time intervals for the 1's and 0's, majorly it delays the other code ! But it also has the overdrive mode i guess but even so the software must make too many NOP to make the right timings !
Take care !
 
Csaba911:

I did save that code as an include file and was calling it from my main program! (read my post above).

I will look it over again tonight and make sure, but I think there is another problem.
 
NewGeek said:
You will also see in the code below that the variable TIME is undefined. This is how they wrote it, I havent figured that out yet either.

I think you just don't know what you doing !!

The code posted by Dallas is compile under MPLAB IDE v6.60, no errors !

You called the macros from your ASM codes !?
Code:
'
; These constants are used throughout the code

      cblock        0x20
             IOBYTE
             TMP0                               ; Address 0x23
             COUNT                              ; Keep track of bits
             PICMSB                             ; Store the MSB
             PICLSB                             ; Store the LSB
             PDBYTE                             ; Presence Detect Pulse
      endc
'

**broken link removed**

Sorry I tried !

STEVE
 
Well two things i'm sure, Microchip hasn't anounced any problem with the compiler, and Dallas Semi. whould not loose costumers with wrong codes in their page :lol: so the problem must be there, wy guilt the code ?? the problem must be in the project creation or MPLAB prefs if not then maybe someone has casted a spell on your computer ! :lol:
 
Geez, just write your own. It's not that big. Also, there are better implementations. As I mentioned, the best solution is to disable interrupts but only during time-critical periods.

It's also rather slow, so if your chip is slow or you've got a particularly "busy" system, it's good to break down the 1-wire transaction over iterations of a main code loop. i.e. you do critical update tasks once, send out the timed pulse to initiate a read bit to the DS18S20, read the result, then loop back and do the critical stuff again.

At minimum, you probably want to let other things go on between initiating a DS18S20 conversion and waiting for the conversion result to become available. It's a pretty long wait.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top