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.

16F690 Program Power Up Issue

Status
Not open for further replies.

jamo13

New Member
Hi there

I'm using MPLAB-X with a PicKit 2 and it's demoboard [04-01831 Rev2] to turn on the first LED (of the four on the demo board) and rotate it left until it rotates off the fourth LED, at which point the First LED gets turned on again. This loops forever. So I end up with a rotating 'on' LED

Rotating the 'on' LED works when the 16F690 gets programed and run (all in one). One thing though, is that the first and second LEDs flicker (I assume this is normal when the program downloads) and the rotating sequence seems to start at the second LED.

If I cycle the power however, the program behaves differently.

After power cycling, LEDs 1 and 2 turn on immediately and then the third and fourth LEDs turn on in succession at the same rate as the good program and none of the LEDs (1-4) ever go off. So I end up with all the LEDs on.

I've read the datasheet and cannot figure out why there is a difference between power up and after programing

Can anyone help?



My code is as follows:


Code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Author :      James Payne
;
; Title:        Stepper 5
;
; Description:
;
;          
;           At the moment it should just move a stepper forward slowly
;
;           
;           Uses Port C to move the motor
;
;           MOTION  bit 0   Do a move = 1
;                   bit 1   Move Forward = 0
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

#include <p16F690.inc>
     __config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF &_MCLRE_OFF & _CP_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF)

;*****Set up the Constants****
    cblock      0x20        ; Dynamically allocated registers
COUNT1                      ; For first delay loop
COUNT2                      ; For second delay loop
MOTION                      ; Motion/direction flag register
    endc

    cblock      0x70        ; Put these up in unbanked RAM
W_Save                      ; For saving the working and status registers during an ISR
STATUS_Save
    endc

            ORG         0x00            ; This is where we come on power up and reset
            goto        Setup           ; After power-up / reset the registers need to be initialised

            ORG         0x04            ; This is where we come on an interupt
            goto        ISR

ISR:
            movwf       W_Save          ; Save the working register
            movf        STATUS,w
            movwf       STATUS_Save     ; Save the Status register

            btfsc       INTCON,T0IF     ; Was it a TMR0 interupt?
            goto        ServiceTMR0     ; yes, do the ISR for TMR0

            goto        ExitISR

ServiceTMR0:
            bcf         INTCON,T0IF     ; Clear the interrupt flag. (must be done in software)

            btfsc       MOTION,0        ; Is a move required?
            call        Do_Motion       ; yes, go to the motion controller

            goto        ExitISR         ; no, return form inerrupt

ExitISR:
            movf        STATUS_Save,w   ; Restore the Status register
            movwf       STATUS
            swapf       W_Save,f        ; Restore the working register
            swapf       W_Save,w

            retfie

;****Set up the port****

Setup       bsf         STATUS,RP0      ;Switch to Bank 1
            bcf         STATUS,RP1      ;

            movlw       b'00000111'     ; Configure Timer0 to have the
            movwf       OPTION_REG      ; Maximum Prescaler

            clrf        TRISC           ; Tristate C port to outputs.

            bcf         STATUS,RP0      ; Switch to Bank 2
            bsf         STATUS,RP1      ;

            clrf        ANSEL           ; Digitl outputs.
            clrf        ANSELH          ; Digitl outputs.

            bcf         STATUS,RP0      ; Switch back to Bank 0
            bcf         STATUS,RP1      ;

            movlw       0x01            ; Set the PORT to '10001000'
            movwf       PORTC           ; ready for stepper control.

            movlw       b'10100000'     ; Enable Timer 0 and global interrupts
            movwf       INTCON          ;

            movlw       0x01            ; Set to Do_Motion and Move Fwd
            movwf       MOTION          ;b

;****Main routine****

Start
            call        Delay

            ; Main program goes here

            goto        Start           ;go back to Start and run the program again

;**** End of the main program loop ********************************************



;**** Program sub-routines listed here ****************************************

;**** Motion sub-routine handles a call for robot movement *****

Do_Motion
            btfss       MOTION,1            ; Move Fwd?
            call        Step_Fwd            ; Fwd = 0

            btfsc       MOTION,1            ; Move Rev?
            call        Step_Rev            ; Rev = 1

            return

;**** Move the robot forward one step *****

Step_Fwd
            rlf         PORTC,f         ; Move motor to next winding (step once)

            btfsc       PORTC,4
            bsf         PORTC,0

            call        Delay           ; Slow things down to see easier
            call        Delay           ; (No particular time period)
            call        Delay
            call        Delay
            call        Delay
            call        Delay
            call        Delay
            call        Delay

            return

;**** Move the robot forward one step *****

Step_Rev                                ; Never gets here at present
            rrf         PORTC,f         ; Move motor to next winding (step once)

            btfsc       PORTC,3
            bsf         PORTC,7

            return

;**** Delays the program manually *****

Delay
            movlw           0xff        ; Setup delay times each call of delay
            movwf           COUNT1
            movlw           0xff
            movwf           COUNT2

Loop1       decfsz          COUNT1,f    ;This second loop keeps the LED
            goto            Loop1       ;turned off long enough for us to

            movlw           0xff
            movwf           COUNT1

            decfsz          COUNT2,f    ;see it turned off
            goto            Loop1       ;

            return

;**** End of the program *****************************************************

            end             ;Needed by some compilers, and also
                            ;just in case we miss the goto instruction.
 
Last edited:
First I would try the power up timer.. Secondly program--run is a soft reset whereas powering up is a hard reset.. Table 2.4 of the datasheet ( last two columns ) give the differences... However! you are resetting the registers used anyway. I would need to SEE this problem.
 
Last edited:
Hi,

You are Calling to routines outside your ISR and then performing 9 further Calls before returning to the ISR.

I believe that chip only has an 8 deep stack so it may be getting lost, though I would have thought the compiler would have warned you ?
 
Wp is correct

2 x pc (interrupt)
1 x pc ( do motion )
1 x pc (step_rev / fwd )
1 x pc (delay )

Is only 5 level deep....But if the timer overruns whilst in the delay you're stuck.

As your code works ok from a soft start I wouldn't think this was happening... also your prescalar is at maximum.

To be on the safe side... How long is the delay...
 
Last edited:
movlw 0x01 ; Set the PORT to '10001000' ,,,,is this an error in the beginning? when you rlf, you lose bit 7, but was never there to begin with.
 
Last edited:
Thanks for the advice.
I'll definitely read Table 2.4 of the datasheet etc and I wasn't aware of the call limits so will read up on those too.

I'll try and get a vid of whats going on as it's a probably bit hard to understand from my description.
The total delay (LED on to the next LED on) is roughly 1 sec.

Joe, you're right, at present the bit 7 '1' rotates off the edge and is lost. I put it there so that eventually I can rotate in the reverse direction as well.

Anyway, you've given me a lot to go on so thanks. I'll see what I can work out.

Oh yeah the only warnings I get are 4 of the following:
Message[302] P:\ROBOTICS\MICROCHIP\PROJECTS\MOTION_CONTROLLER_5.X\STEPPER5.ASM 80 : Register in operand not in bank 0. Ensure that bank bits are correct.

But I've read this is ok.
 
Last edited:
I have solved this issue - but thanks again as I've learned new stuff.

The problem seemed to be the carry of PORTC.
Once that was cleared things were working well.

I'm not exactly sure why the carry bit was being set on each rotate, does anyone know why?

Here is the code I got working:
Code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Author :      James Payne
;
; Title:        Stepper 5
;
; Description:
;
;
;           At the moment it should just move s stepper forward slowly
;
;
;           Uses Port C to move the motor
;
;           MOTION  bit 0   Do a move = 1
;                   bit 1   Move Forward = 0
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

#include <p16F690.inc>
     __config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_ON &_MCLRE_OFF & _CP_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF)

;*****Set up the Constants****
    cblock      0x20        ; Dynamically allocated registers
COUNT1                      ; For first delay loop
COUNT2                      ; For second delay loop
MOTION                      ; Motion/direction flag register
    endc

    cblock      0x70        ; Put these up in unbanked RAM
W_TEMP                      ; For saving the working and status registers during an ISR
STATUS_TEMP
    endc

            ORG         0x00            ; This is where we come on power up and reset
            goto        Setup           ; After power-up / reset the registers need to be initialised

            ORG         0x04            ; This is where we come on an interupt
            goto        ISR

ISR:                                    ; The saving and restoring is copied from the datasheet
            movwf       W_TEMP          ; Copy W to TEMP register
            swapf       STATUS,W        ; Swap status to be saved into W
            clrf        STATUS          ; bank 0, regardless of current bank, Clears IRP,RP1,RP0
            movwf       STATUS_TEMP     ; Save status to bank zero STATUS_TEMP register

            btfsc       INTCON,T0IF     ; Was it a TMR0 interupt?
            goto        ServiceTMR0     ; yes, do the ISR for TMR0

            goto        ExitISR

ServiceTMR0:
            bcf         INTCON,T0IF     ; Clear the interrupt flag. (must be done in software)

            bcf         STATUS,C     ;THIS SOLVED EVERYTHING
            rlf         PORTC,f         ; Move motor to next winding (step once)

            btfsc       PORTC,4         ; If the last LED rotates out of view
            bsf         PORTC,0         ; Turn on the first one

            goto        ExitISR         ; no, return form interrupt

ExitISR:
            swapf       STATUS_TEMP,W   ; Swap STATUS_TEMP register into W
                                        ;(sets bank to original state)
            movwf       STATUS          ; Move W into STATUS register
            swapf       W_TEMP,F        ; Swap W_TEMP
            swapf       W_TEMP,W        ; Swap W_TEMP into W

            retfie

;****Set up the port****

Setup       bsf         STATUS,RP0      ;Switch to Bank 1
            bcf         STATUS,RP1      ;

            movlw       b'00000111'     ; Configure Timer0 to have the
            movwf       OPTION_REG      ; Maximum Prescaler

            clrf        TRISC           ; Tristate C port to outputs.

            bcf         STATUS,RP0      ; Switch to Bank 2
            bsf         STATUS,RP1      ;

            clrf        ANSEL           ; Digitl outputs.
            clrf        ANSELH          ; Digitl outputs.

            bcf         STATUS,RP0      ; Switch back to Bank 0
            bcf         STATUS,RP1      ;

            movlw       0x01            ; Set the PORT to '10001000'
            movwf       PORTC           ; ready for stepper control.

            clrf        TMR0            ; Make sure theres nothing is Timer 0

            movlw       b'10100000'     ; Enable Timer 0 and global interrupts
            movwf       INTCON          ;


;****Main routine****

Start
            nop
            nop
            nop

            ; Main program goes here

            goto        Start           ;go back to Start and run the program again


;**** End of the program *****************************************************

            end             ;Needed by some compilers, and also
 
Last edited:
When you rlf portc and check only the forth bit if clear, you are then resetting bit 0, after 4 more rlf's , bit seven, which is still set gets rotated into the carry bit. If only using the first 4 bits, clear the port before resetting bit 0.
 
I understand what you a saying, and you make sense.

The thing I don't understand is that the first led gets turned on with every rotate.
I would expect the first lead only turns on when the bit 7 eventually rotates into the carry as you rightly point out. But it doesn't.

I tried putting nothing (0x00) into PORTC during setup and not clearing the ports carry bit each rotate. That also turns on the first LED each rotate and eventually they all end up on.
 
Last edited:
It's working fine, it's just the carry needs to be cleared each rotate or the PORTC will fill with 'ON's'
I have it driving a stepper with no issues.

I was just wanting to know why the carry is needing to be cleared so often. It's not a major.
 
Status
Not open for further replies.

Latest threads

Back
Top