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.

DS18B20 Digital Thermometer + PIC + Assembly display flicker issue

Status
Not open for further replies.
Pommie, I'm running your edited code in the ISR and it has been running for 25 minutes now no problem.
I've had it up to 127.9 degrees with the heat gun and down to -14.5 in the freezer

I've read over and over your explanation;
When you switch to bank 1 to change the tris the bcf PIR1,TMR2IF will clear the PIE1 register instead of the PIR1 register.
But cannot grasp what your getting at.
Could you re-word it, I want to understand what was and is now happening.

:D and thankyou thankyou thankyou haha
 
If the interrupt happens during the red bit of this code,
Code:
DQ_HIZ					; This routine forces the DQ Line to an Input / High Impedance state 
		bsf	STATUS,RP0	; Bank 1
[COLOR="red"]		bsf	TRISA,4		; Make Pin 3 an input, Pullup resistor forces line to logic 1, unless DS18B20 pulls it low[/COLOR]
		[COLOR="red"]bcf	STATUS,RP0	; Bank 0[/COLOR]
		return
			 
DQ_LL					; This routine forces the DQ Line to Logic Low 
		bcf	PORTA,4		; Clear output latch
		bsf	STATUS,RP0	; Bank 1
[COLOR="red"]		bcf	TRISA,4		; Make Pin 3 an output
		bcf	STATUS,RP0	; Bank 0[/COLOR]
		return
the interrupt will restore the STATUS register back to bank 1 and therefore write to the wrong register.
Code:
		swapf	S_ISR,W		; Undo previous SWAPF, place result in W
		movwf	STATUS		; Restore STATUS
  [COLOR="red"];will be in bank 1 here.[/COLOR]
		swapf	W_ISR,F		; Use SWAPF instruction so status bits don't change
		swapf	W_ISR,W		; Undo previous SWAPF and restore W register
  [COLOR="red"];next line will write to PIE1[/COLOR]
		bcf	PIR1,TMR2IF	; Clear TMR2 interrupt flag        
		bsf	FLAGS,0		; Set ISR Complete Flag to indicate ISR has just been executed
		retfie			; Return From Interrupt

That is why it was so intermittent and hard to find.

Mike.
 
Pommie,
You are my hero.
Haha thanks a lot for all your help.
You and Mike(K8LH) have been as awesome help.
Its been running now for more than an hour so it must have interrupted everywhere possible by now so I think thats it.
 
Oh my! I wonder how long that instruction has been there right in the middle of the context restore block? Yep, that's the problem.

You may be in the wrong bank when you attempt to set that "flags" variable bit too. Probably should get that out of the context restore block...
 
Last edited:
Oh my! I wonder how long that instruction has been there right in the middle of the context restore block?
Probably 5 months.
.. How long i've been trying to getthis thing working lol

You may be in the wrong bank when you attempt to set that "flags" variable bit too. Probably should get that out of the context restore block...
And yeah not using that anymore.
There is no need to now.
That was purely to work around this banking issue.
Now i can simply use just BCF & BSF INTCON,GIE for the time crutial routines, and its all good.
Noooooo problem.
 
So I understand what was happening and the basics of why it was happening.
But I'm not happy with not fully understanding. I want to know or be sure so I'm aware next time.

So I understand if the interrupt occurs while the PIC is in bank 1, the interrupt routine restores the the status register before clearing the TIMER2 flag.
Which explains why it was only happening in the RESET routine; this is because in the other routines that use DQ_HIZ & DQ_LOW, they have interrupt disable instructions before they are called. (Due to timing sensitivity)

What I am a little hazy on is why (although in bank 1) the instruction; BCF PIR1, TMR2IF was clearing TMR2IE of the PIE register.
I notice the PIR1 (0Ch) and PIE1 (8Ch) are directly opposite each other in the memory map.
a BCF PIR1, TMR2IFeffectivly loads BCF 0x0C, 0x02, So what i am curious about is how does that instruction effectivly become BCF 0x8C, 0x02 just by being in bank 1
 
All (register) instructions on the 16 series only have room for a 7 bit address within the actual opcode. The other two bits of the address are RP0 and RP1. So setting RP0 turns BCF 0x0C,0x02 into BCF 0x8C,0x02.

Edit, another common error with interrupts is to put a goto instruction at 0x0004 and put the actual routine somewhere else. This can cause a similar crash if PCLATH is not pointing at the right bank.

Mike.
 
Last edited:
Very nice Jake.

I did notice 1 itsy bitsy teeny weeny mistake,
Code:
 ; RESTORE
        BCF     PIR1, TMR2IF            ; Clear TMR2 interrupt flag while still in Bank 1        
        MOVF    F_ISR, W                ; MOVE F_ISR to W
        MOVWF   FSR                     ; Restore FSR
        MOVF    P_ISR, W                ; MOVE P_ISR to W
        MOVWF   PCLATH                  ; Restore PCLATH
        SWAPF   S_ISR, W                ; Undo previous SWAPF, place result in W
        MOVWF   STATUS                  ; Restore STATUS
        SWAPF   W_ISR, F                ; Use SWAPF instruction so status bits don't change
        SWAPF   W_ISR, W                ; Undo previous SWAPF and restore W register
        RETFIE                          ; Return From Interrupt
Should be,
Code:
 ; RESTORE
        BCF     PIR1, TMR2IF            ; Clear TMR2 interrupt flag while still in Bank [COLOR="red"]0[/COLOR]        
        MOVF    F_ISR, W                ; MOVE F_ISR to W
        MOVWF   FSR                     ; Restore FSR
        MOVF    P_ISR, W                ; MOVE P_ISR to W
        MOVWF   PCLATH                  ; Restore PCLATH
        SWAPF   S_ISR, W                ; Undo previous SWAPF, place result in W
        MOVWF   STATUS                  ; Restore STATUS
        SWAPF   W_ISR, F                ; Use SWAPF instruction so status bits don't change
        SWAPF   W_ISR, W                ; Undo previous SWAPF and restore W register
        RETFIE                          ; Return From Interrupt
Told you it was small. But in this case very relevant.

Oh and, the video is the wrong one.

Mike.
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top