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.

what works in the simulator does not work on hardware???

Status
Not open for further replies.

spyghost

New Member
hi,

i have been experimenting on pic over a few days already. everthing works 100% over the mplab simulator (6.5). i am burning the chip using jdm programmer and ic-prog version 1.05. btw, my chip is 16f84a.

everthing works 100% in the simulator, however, things don't go well in hardware.

i am trying to spin 2 stepper motors using port b (one nibble each). the stepping works perfectly in rb0, rb1, rb2, and rb3. while there is absolutely no stepping action in rb4, rb5, rb6, and rb67. :shock:
the logic probe pulses on the low nibble, while it stays high on the high nibble.

i made another program to test if portb is damaged. unfortunately, every pin of portb is fully functional.

i don't know what on earth is wrong with the program i made because it works the way i wanted it to be in the simulator, but it never works on hardware.... :evil:
 
:cry:

Calm down!! They are designed by mchip to make you pull your hair out!! :wink: Ok, make sure that the TRIS registers are correct i.e. B'00000000' not B'11110000' also pics can "lock up" if you give them too much abuse, is the pic directly conected to the stepper motor?

What is the load on the pins....

Like Dave said, show us the code, we can help (no warrenty implied etc :roll: )
 
ok... here is the code:


Code:
list		p=16f84a
#include	<P16F84A.INC>
__CONFIG	_WDT_OFF & _PWRTE_OFF & _CP_OFF & _XT_OSC

; *** Setup the constants ***
ISR_ADDR	equ		0004h						; ISR address
TMR0_RELOAD equ		b'00000000'					; Reload value of Timer 0
LEFT_MOTOR	equ		0Fh							; Location of current step of left motor
RIGHT_MOTOR	equ		10h							; Location of current step of right motor
COUNTER1	equ		11h							; First counter for delay
COUNTER2	equ		12h							; Second counter for delay
			
; *** Macros ***
bank0		macro								; Select memory Bank 0
			bcf		STATUS, RP0
			endm

bank1		macro								; Select memory Bank 1
			bsf		STATUS, RP0
			endm

; *** Begin program execution
			org		0000h
			goto	Main
			
; *** Interrupt Service Routine
			org		ISR_ADDR
			bcf		INTCON, T0IF				; Clear Timer 0 overflow flag
			decfsz	COUNTER1, 1
			goto	End_ISR
			call	Forward						; Call subroutine to go forward
End_ISR		call	Reset_TMR0					; Reset Timer 0
			call	Move_Motors
			retfie

; *** Subroutines
Reset_TMR0	movlw	TMR0_RELOAD
			movwf	TMR0
			return

Turn_Right	bcf		STATUS, C					; Clear Carry flag
			rrf		LEFT_MOTOR, 1				; Create a single step for left motor
			btfsc	STATUS, C					; Is C set?
			bsf		LEFT_MOTOR, 3				; Yes, set bit 3 of LEFT_MOTOR
			bcf		STATUS, C					; Clear Carry flag
			return

Turn_Left	bcf		STATUS, C					; Clear Carry flag
			rlf		RIGHT_MOTOR, 1				; Create a single step for right motor
			btfsc	STATUS, C					; Is C set?
			bsf		RIGHT_MOTOR, 4				; Yes, set bit 4 of RIGHT_MOTOR
			bcf		STATUS, C					; Clear Carry flag			
			return

Forward		call	Turn_Right
			call	Turn_Left
			return

Move_Motors	movf	RIGHT_MOTOR, 0				; Place current step of left motor in W
			iorwf	LEFT_MOTOR, 0				; OR W with the current step of right motor
			movwf	PORTB						; Move the current step to Port B
			return

; *** Main Program ***
Main		call	Reset_TMR0
			; Setup stepper motor movements
			bsf		LEFT_MOTOR, 3				; Set initial step for left motor
			bsf		RIGHT_MOTOR, 4				; Set intitial step for right motor
			; Setup I/O ports
			bank1
			movlw	00h							; Set W register to zero
			movwf	TRISB						; and Port B to be an output port
			bank0
			; Setup interrupts
			bsf		INTCON, T0IE				; Setup Timer 0 overflow interrupt
			bsf		INTCON, GIE					; Enable occurrence of interrupts
			; Setup Timer 0 interrupt to respond to internal clock
			bank1
			bcf		OPTION_REG, T0CS			; Timer 0 Clock source is internal clock
			bank0
This		goto	This
			
			end

what happens is that only the low nibble changes (shifts) while the high nibble of port b stays lit all the time
 
The simulator defaults by initializing all file registers to zero. In reality, the file registers can assume a random value on power-up.

Your software assumes that the values of LEFT_MOTOR and RIGHT_MOTOR are initially zero. If they are intialized to a non-zero value, that value will recirculate and you will get odd signals out of portb.

For example, let's assume LEFT_MOTOR were initialized to 0xFF. As soon as the ff instruction are executed, the succeeding bit3 will be set.

Code:
         btfsc   STATUS, C               ; Is C set? 
         bsf      LEFT_MOTOR, 3            ; Yes, set bit 3 of LEFT_MOTOR

You should insert the ff. code to solve this problem:

Code:
Main      call   Reset_TMR0 
         ; Setup stepper motor movements 
         clrf      LEFT_MOTOR
         clrf      RIGHT_MOTOR
;
         bsf      LEFT_MOTOR, 3            ; Set initial step for left motor 
         bsf      RIGHT_MOTOR, 4            ; Set intitial step for right motor
 
great! that did the trick... 8)

so this means that the gpr does not have a reset state of all 0's... am i right?
 
spyghost said:
great! that did the trick... 8)

so this means that the gpr does not have a reset state of all 0's... am i right?

You shouldn't assume any default values for anything, on any processor - you should always initialise variables and registers. Sometimes PIC registers keep the value that was stored in them last, but you obviously can't guarantee it.
 
spyghost said:
great! that did the trick... 8)

so this means that the gpr does not have a reset state of all 0's... am i right?

That is correct. I generally have code to clear the GPR area during initializiation to avoid these kinds of bugs. The old versions of MPLAB (pre-6.0) have the option of initializing the file register memory to random values to test this scenario.

As a follow-up, I would recommend to change your code as follows:

Code:
Turn_Right   bcf      STATUS, C               ; Clear Carry flag 
         rrf      LEFT_MOTOR, 1            ; Create a single step for left motor 
         btfsc   STATUS, Z               ; Test for zero 
         bsf      LEFT_MOTOR, 3            ; Yes, set bit 3 of LEFT_MOTOR 
         return 

Turn_Left   bcf      STATUS, C               ; Clear Carry flag 
         rlf      RIGHT_MOTOR, 1            ; Create a single step for right motor 
         btfsc   STATUS, Z               ; Test for zero 
         bsf      RIGHT_MOTOR, 4            ; Yes, set bit 4 of RIGHT_MOTOR 
         return

This will guarrantee that one and only one bit in the file register is set under all conditions.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top