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.

Sim disagrees with actual prg.

Status
Not open for further replies.

Mosaic

Well-Known Member
MPLAB SIM issues- PIC Hardware INIT solved.

Hi all:
Below is a commented, working proggie that counts the # of debounced switch clicks in the Pic Kit 2 LPC board.
Odd thing is, the LEds Start displaying the count as 1, when it should be zero.
The simulation says it IS zero.
If I Change the start value of the variable 'Clicks' from 0 to 255, it seems to work fine.
BUT I CAN"T SEE WHY that is necessary.

Thanks for any help. You can setup watch variables and see if you can shed any light on this one.



list p=16f690 ; list directive to define processor
#include <P16F690.inc> ; processor specific variable definitions


__config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF) ; allows PortA as dig. input..


;***** VARIABLE DEFINITIONS



VARIABLES UDATA_SHR
Delay1 RES 1
Delay2 RES 1
Switch RES 1
Latch RES 1
Clicks RES 1
;**********************************************************************
ORG 0x000 ; processor reset vector
goto Main ; go to beginning of program



Main

;Switch input setup (RA3)
Banksel TRISA
BSF TRISA,3 ; Set RA3 as an input
BANKSel ANSEL;
BCF ANSEL,3 ; RA3 is digital.
Banksel Switch
CLRF Switch
CLRF Latch
CLRF Clicks ; set switch clicks to 0


; PORTC setup
BankSel TRISC
movlw b'11110000'
movwf TRISC ; MAKE I/O PIN C0,c1,c2,c3 AN OUTPUT, BY SETTING PINS 0,1,2,3 LOW.
BankSel Delay1


Longloop
CLRF Delay1
CLRF Delay2

LOOP
DECFSZ Delay1,F ; 1 inst cycle, when delay1=0 => test = true skip next line.
GOTO LOOP ; 2 inst cycles, this is looped 256 times before skipping to next line => 768 microsec at 1 MIP
CALL GETSWITCH ; this is the core loop, use to monitor switch.
DECFSZ Delay2,F ; 1 inst cycle
GOTO LOOP ; 2 inst cyles, by adding the loops = 256 * 768 + (256*3) = 257* 768 = 197376 microsec = .2 sec.
MOVF Clicks,w ; prepare to display clicks on LEDs
MOVWF PORTC ;OUTPUT TO C.
GOTO Longloop ; CONTINUE


GETSWITCH ;debounce routine of Switch on RA3
BTFSS PORTA,3 ; test RA3, skip if HI (SW is OPEN)
CALL CLOSED
BTFSC PORTA,3 ; test RA3, skip if lo (SW is CLOSED)
CALL OPEN
RETURN

OPEN ; When Switch is Open
DECFSZ Switch,F; Debounce Countdown if switch is open.
Return ; return if switch value is non zero
Incf Switch ; make switch minimum 1
BCF Latch,0 ; clear onlatch as Switch has reached lowest count.
RETURN

CLOSED: ; When switch is closed
INCF Switch,F ; Debounce count up if switch is on/closed
BTFSC Switch,5
BSF Latch,1 ; set onlatch,1 to 1 if Switch =32
BTFSC Switch,5
CALL CLIK
BTFSC Switch,5
DECF Switch,F ; keep Switch from rising past 32.
RETURN

CLIK ; Track number of switch clicks
BTFSS Latch,0 ;skip next inst. if latch,0 is set.
INCF Clicks ; If Latch,0 is clear,then this is a state change from switch open => increment clicks
BCF STATUS,C ; clear the carry
RRF Latch,f ; make bit 1 into bit 0 to update Latch status for switch open/closed testing.
RETURN



END ; directive 'end of program'
 
Last edited:
That code won't even assemble!! You can't have org in a relocatable file OR you cant have udata_shr in an absolute file.

Here's the relocatable version,
Code:
		list	p=16f690	; list directive to define processor
#include	<P16F690.inc> 		; processor specific variable definitions

		__config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF)  ; allows PortA as dig. input..


;***** VARIABLE DEFINITIONS  
VARIABLES	 udata_shr 
Delay1		res	1
Delay2		res	1
Switch		res	1
Latch		res	1
Clicks		res	1

		code	0x000		; processor reset vector
		goto	Main		; go to beginning of program
Main
;Switch input setup (RA3)  
		banksel	TRISA
		bsf	TRISA,3		; Set RA3 as an input
		banksel	ANSEL		;
		bcf	ANSEL,3		; RA3 is digital.
		banksel	Switch
		clrf	Switch
		clrf	Latch
		clrf	Clicks		; set switch clicks to 0
; PORTC setup
		banksel	TRISC 
		movlw	b'11110000'
		movwf	TRISC		; MAKE I/O PIN C0,c1,c2,c3 AN OUTPUT, BY SETTING PINS 0,1,2,3 LOW.
		banksel	Delay1 
Longloop
		clrf	Delay1
		clrf	Delay2 
LOOP			 
		decfsz	Delay1,F	; 1 inst cycle, when delay1=0 => test = true skip next line.
		goto	LOOP		; 2 inst cycles, this is looped 256 times before skipping to next line => 768 microsec at 1 MIP
		call	GETSWITCH	; this is the core loop, use to monitor switch.
		decfsz	Delay2,F	; 1 inst cycle
		goto	LOOP		; 2 inst cyles, by adding the loops = 256 * 768 + (256*3) = 257* 768 = 197376 microsec = .2 sec.
		movf	Clicks,w	; prepare to display clicks on LEDs
		movwf	PORTC		;OUTPUT TO C.
		goto	Longloop	; CONTINUE
GETSWITCH				;debounce routine of Switch on RA3 
		btfss	PORTA,3		; test RA3, skip if HI (SW is OPEN)
		call	CLOSED
		btfsc	PORTA,3		; test RA3, skip if lo (SW is CLOSED)
		call	OPEN
		return
OPEN					; When Switch is Open 
		decfsz	Switch,F	; Debounce Countdown if switch is open.
		return			; return if switch value is non zero
		incf	Switch		; make switch minimum 1
		bcf	Latch,0		; clear onlatch as Switch has reached lowest count.
		return
CLOSED:					; When switch is closed 
		incf	Switch,F	; Debounce count up if switch is on/closed
		btfsc	Switch,5
		bsf	Latch,1		; set onlatch,1 to 1 if Switch =32
		btfsc	Switch,5
		call	CLIK 
		btfsc	Switch,5
		decf	Switch,F	; keep Switch from rising past 32.
		return
CLIK					; Track number of switch clicks 
		btfss	Latch,0		;skip next inst. if latch,0 is set.
		incf	Clicks		; If Latch,0 is clear,then this is a state change from switch open => increment clicks
		bcf	STATUS,C	; clear the carry
		rrf	Latch,f		; make bit 1 into bit 0 to update Latch status for switch open/closed testing.
		return
		end			; directive 'end of program'

Mike.
 
That's odd

MPLAB Assembles it just fine and programs the PIC via the Pic Kit 2 just fine as well.

So I can say that it does assemble. It's running on the PIC now.

But what about the question at hand?

How come the sim says a variable is 1 and the PIC says its 2?
 
MPLAB does not assemble that code. You must have files open that are not part of the project or something. Start a new project, add a clean file and cut/paste the above code into it.

Mike.
 
If the code in the first post assembles for you then you are doing something wrong. You cannot have VARIABLES udata_shr and org in the same file. Zip up the whole folder and post it and I'll try and work out what is wrong.

Mike.
 
I'll try to strip it down to the bare minimum with the prob.
My digging has shown sumthin very odd.
If I place a Goto $ cmd to prevent access to the main loop, upon programming the chip , somehow the prg STILL executes the main loop upon init.
Mebbe sumthing with the fuses?
 
As I said in post 4, "You must have files open that are not part of the project or something. Start a new project, add a clean file and cut/paste the above code into it."

MPLAB is very happy to let you edit one file but assemble a completely different file and I suspect that this is what is happening here.

Mike.
 
Pommie: I solved it - HARDWARE problem due to voltage irregularities upon programming.

It's not the programming, but the PIC hardware INPUT fluctuations that occurs as it is programmed. I had to place 2 layers of defense to manage it. First it needs about a 20 millisecond delay to stabilize the RA input from doing the rapid hi/lo dance AND then it needs a bit of code to WAIT until the voltage pull up carries the RA3 high before releasing the PIC to run the main operating loop which counts switch presses via RA3 and displays them in binary on the 4 LEDS on the starter2 LPC kit.

Here is the fully commented and functional code.



list p=16f690 ; list directive to define processor
#include <P16F690.inc> ; processor specific variable definitions


__config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOR_ON & _IESO_OFF & _FCMEN_OFF) ; allows PortA as dig. input..


;***** VARIABLE DEFINITIONS



VARIABLES UDATA_SHR
Delay1 RES 1
Delay2 RES 1
Switch RES 1
Latch RES 1
Clicks RES 1
;**********************************************************************
Code 0x000 ; processor reset vector
goto Main ; go to beginning of program


Main

;Input PORTA setup (RA3)
Banksel TRISA
BSF TRISA,3 ; Set RA3 as an input


;PORTC setup
BankSel TRISC
movlw b'11110000'
movwf TRISC ; MAKE I/O PIN C0,c1,c2,c3 AN OUTPUT, BY SETTING PINS 0,1,2,3 LOW.
CLRF PORTC; init PORTC
BankSel Clicks ; back to general variable bank

; give PIC time to stabilise @ 4MHZ and verify RA input level hi before proceeding
CALL InitWait

;init variables
CLRF Switch
CLRF Latch
CLRF Clicks

; Main operating loop
Longloop
CLRF Delay1
CLRF Delay2

LOOP

DECFSZ Delay1,F ; 1 inst cycle, when delay1=0 => test = true skip next line.
GOTO LOOP ; 2 inst cycles, this is looped 256 times before skipping to next line => 768 microsec at 1 MIP
CALL GETSWITCH ; this is the core loop, use to monitor switch.
DECFSZ Delay2,F ; 1 inst cycle
GOTO LOOP ; 2 inst cyles, by adding the loops = 256 * 768 + (256*3) = 257* 768 = 197376 microsec = .2 sec.
MOVF Clicks,w ; prepare to display clicks on LEDs
MOVWF PORTC ;OUTPUT TO C.
Goto Longloop ; CONTINUE


GETSWITCH ;debounce routine of Switch on RA3
BTFSS PORTA,3 ; test RA3, skip if HI (SW is OPEN)
CALL CLOSED
BTFSC PORTA,3 ; test RA3, skip if lo (SW is CLOSED)
CALL OPEN
RETURN

OPEN ; When Switch is Open
DECFSZ Switch,F; Debounce Countdown if switch is open.
Return ; return if switch value is non zero
Incf Switch ; make switch minimum 1
CLRF Latch ; clear onlatch as Switch has reached lowest count.
RETURN

CLOSED: ; When switch is closed
INCF Switch,F ; Debounce count up if switch is on/closed
MOVF Switch,w
SUBLW .32 ; 32-w
BC RET ; branch on carry set (w<32) =>return as count not high enough.
BSF Latch,1 ; set onlatch,1 to 1 if Switch =33
CALL CLIK
DECF Switch,F ; keep Switch from rising past 33.
RET RETURN

CLIK ; Track number of switch clicks
BTFSS Latch,0 ;skip next inst. if latch,0 is set. (if latch is 1)
INCF Clicks ; If Latch,0 is clear,then this is a state change from switch open => increment clicks
BCF STATUS,C ; clear the carry
RRF Latch,f ; make bit 1 into bit 0 to update Latch status for switch open/closed testing.
RETURN


InitWait ; this loop adds a delay to handle fluctuating inputs upon programming the PIC.
CLRF Delay1
MOVLW .25 ; This value is the smallest delay @4MHz that allows proper init. Bigger is ok.
MOVWF Delay2

Wait
DECFSZ Delay1,F ; 1 inst cycle, when delay1=0 => test = true skip next line.
GOTO Wait ; 2 inst cycles, this is looped 256 times before skipping to next line => 768 microsec at 1 MIP
DECFSZ Delay2,F ; +1 inst cycle (1 usec/cycle) at 1 MIP
GOTO Wait ; +2 inst cyles, by adding the loops = (25 * 768) + (25*3) = 19.2 millisec delay
BTFSS PORTA,3 ; test RA3, skip if HI (SW is OPEN)
GOTO $-1 ; wait for RA3 input to go high (voltage pull up) otherwise init not complete.
RETURN

END ; directive 'end of program'
 
Last edited:
Hi Mosaic,

Can you place your program between <code> tags so that it will retain some formatting and be easier to read, please?

Also, is it my imagination or did you replace that errant 'org' statement in your original listing with a 'code' statement as Pommie suggested?

Regards, Mike

<added>

This could be a problem. You're still in Bank 1 when you attempt to clear the PORTC output latches;

Code:
; PORTC setup
        BankSel TRISC
        movlw   b'11110000'
        movwf   TRISC           ; MAKE I/O PIN C0,c1,c2,c3 AN OUTPUT, BY SETTING PINS 0,1,2,3 LOW.
        CLRF    PORTC           ; init PORTC
        BankSel Clicks          ; back to general variable bank
 
Last edited:
The PORTS access exist across the banks AFAIK. And it does clr.

I did try the Code to see if it would do anything, seems perfectly interchangeable with Org.

The InitWait loop at the end of the prg is the solution to the PIC not working as expected.
 
Status
Not open for further replies.

Latest threads

Back
Top