pic16f628a & DS1820 @ 48kHz , 3.3V

Status
Not open for further replies.

mabauti

Member
Hi everybody:

I'm having troubles trying to communicate a f628a and a DS1820 using the internal pic oscillator @ 48kHz, 3.3V. Communication between them @ 4MHz is successful , but @ 48kHz is not.

My question is : is this possible (communication @ 48kHz)?, or am I doing something wrong?

this is the modificated part (taken from the very usual code)

Code:
        ;******************************************************************
;*                                                                *
;*  Dallas/Maxim DS18B20 Temperature Sensor Routines              *
;*                                                                *
;******************************************************************

OW_HIZ:MACRO
        bsf     STATUS,RP0      ; bank 1                          
        bsf     TRISA,DQ       ; set DQ pin as HiZ input         
        bcf     STATUS,RP0      ; bank 0                          
        ENDM                    ;                                 

OW_LO:MACRO 
      bcf    STATUS,RP0  ; Select Bank 0 of data memory 
      bcf    PORTA,  DQ  ; Clear the DQ bit 
      bsf    STATUS,RP0  ; Select Bank 1 of data memory 
      bcf    TRISA, DQ  ; Make DQ pin an output  
      bcf    STATUS,RP0  ; Select Bank 0 of data memory 
     ENDM 
                  ;                                 

WAIT:MACRO   TIME            ;                                 
        movlw   (TIME/5)-1      ; 1 µsec
        call    WAIT5U          ; 2 µsec                          
        ENDM

WAIT5U  nop                     ; 1 µsec 
       addlw -1                ; 1 µsec                                            
        bnz  WAIT5U             ; 3µsec or 2µsec             
        return                  ; 2 µsec                          

OW_RESET
        OW_HIZ                                                   
        clrf    PDByte                                           
        OW_LO                                                   
        ;WAIT    .500                                             
        nop
        nop
        nop
        nop
        nop
        nop
        OW_HIZ                  ;                                 
        ;WAIT    .70             ;                                 
        nop
        btfss   PORTA,DQ         ;                                 
        incf    PDByte,F        ;                                 
        ;WAIT    .430            ;                                 
        nop
        nop
        nop
        nop
        nop
        return                  ;                                 
;
;  RX byte
;
DSRXBYTE
        movlw   .8              ;                                 
        movwf   Count           ; set bit counter                 
DSRXLP  
        OW_LO                   ; bring DQ low for 6 usecs        
        nop                                                      
        ;nop                                                     
        ;nop                                                      
        ;nop                                                     
        ;nop                                                      
        ;nop                                                     
        OW_HIZ                  ; change to HiZ and wait 4 usecs  
        nop                                                    
        ;nop                                                     
        ;nop                                                     
        ;nop                                                     
        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   
        nop
        decfsz  Count,F         ; Decrement the bit counter       
        goto    DSRXLP          ;                                 
        movf    IOByte,W        ;                                 
        return                  ;                                 
;
;  TX byte
;
DSTXBYTE
        movwf   IOByte          ; we send it from IOBYTE          
        movlw   .8              ;                                 
        movwf   Count           ; set bit counter                 
DSTXLP  OW_LO                   ; drive the line low for 3us      
        nop                                                     
        ;nop                                                      
        ;nop                                                     
        rrf     IOByte,F                                         
        bsf     STATUS,RP0      ; bank 1                          
        btfsc   STATUS,C        ; test LSB of IOBYTE for 1 or 0   
        bsf     PORTA,DQ       ; HiZ the line if bit is 1        
        bcf     STATUS,RP0      ; bank 0                          
        ;WAIT    .60             ; continue driving line for 60µs  
        nop
        OW_HIZ                  ; release the line for pullup     
        nop                                                      
        ;nop                     ; recovery time of 2µs            
        decfsz  Count,F         ; decrement the bit counter       
        goto    DSTXLP                                           
        return                  ;                                 

;******************************************************************
;
;  get temperature reading
;
GetTemp
        call    OW_RESET        ; send reset signal               
        btfss   PDByte,0        ; DS18B20 found?                  
        return                  ; no, return, else                
        movlw   h'CC'                                           
        call    DSTXBYTE        ; send 'skip rom' command         
        movlw   h'44'                                            
        call    DSTXBYTE        ; start temperature conversion    
ReadSlot
        ;WAIT    .60             ; wait 60-usecs                   
        nop
        OW_LO                   ; start new read slot             
        OW_HIZ                                                   
        nop                     
        ;nop                     
        ;nop                     
        ;nop                     
        ;nop
        btfss   PORTA,DQ        ; conversion complete '1'?        
        goto    ReadSlot        ; no, do another slot, else       
        ;WAIT    .60             ; finish read slot period         
        nop
GetResult
        call    OW_RESET        ; send reset signal               
        movlw   h'CC'                                            
        call    DSTXBYTE        ; send 'skip rom' command         
        movlw   h'BE'                                            
        call    DSTXBYTE        ; send 'read scratchpad' command  
        call    DSRXBYTE                                         
        movwf   TempL           ; save temperature lo             
        call    DSRXBYTE

                                         
        movwf   TempH           ; save temperature hi
        bcf   STATUS,C        
        rrf     TempL,f            ; eliminate "decimal" place
        return


Thanks in advace for your comments
 
I'm not sure you could implement the correct one-wire timing sequences for reading and writing bits with a Tcy (cycle time) of 20.8 usecs when using a 48 KHz clock...
 
Last edited:
Like Mike says it just not possible, because you need 1us resolution. If you were into experimentation, a 10us time cycle might work? That would require a 400kHZ clock, really don't see much gain there, must be a battery operation.
 
I think what Bill meant to say was that the 16f628a does not have a 48kHz internal clock. It is always 4MHz.

Mike.
 
There's an OSCF bit in the PCON register that selects the 4 MHz or the 48 KHz INTOSC frequency...

Perhaps you could switch to 4 MHz to communicate with the DS18B20 devices then switch back to 48 KHz...
 
Last edited:
That 48khz internal osc has got to take the cake, never noticed that before.

If the O.P. is serious about saving power then put the PIC to sleep while it waits for 1-wire temp to calculate a new value.

That looks like a bare glass LCD, how are you driving that with a 16f628a?
 
Perhaps you could switch to 4 MHz to communicate with the DS18B20 devices then switch back to 48 KHz...
I want to avoid that =[ . Actually I tried , but it didn't work;

That looks like a bare glass LCD, how are you driving that with a 16f628a?
using an icm7211
 
Have you tried putting the PIC to sleep?
1) Assign the Timer0 prescaler to the watchdog (OPTION_REG,PSA) and Initialize watchdog timer prescale bits (OPTION_REG, PS bits). Then set the (WDTCON,WDTPS bits) for approx 100ms.
2) After issuing a convert T command you have 100ms
before you get the 9bit reading back so:
3) Set WDTCON,SWDTEN bit on
4) sleep
5) nop
6) Set WDTCON, SWDTEN off
7) check your conversion bit, etc.
 
Why not use synchronous serial? The USART supports a synchronous mode and it works in sleep with any FOSC on either PIC.
Too bad the 18F1320 doesn't have a MSSP like the 16F628A does or I'd suggest I2C or SPI
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…