Searching \ for 'PIC Startup Troubles' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/devices.htm?key=pic
Search entire site for: 'PIC Startup Troubles'.

Truncated match.
PICList Thread
'PIC Startup Troubles'
2000\01\27@202901 by Ken S.

flavicon
face
I have a simple 16F84 LED flasher that is starting up weird. It's
running off +5V from my PC, 4MHz resonator and has 8 LEDs via 330 ohm
resistors to +5V (hooked to PortB).

My code increments an 8 bit count every 256 timer interrupts. The main
loop writes it to PORT.
www.telusplanet.net/public/ksidhu/flasher2.asm
The code is rough and has a few bugs (LP O/c instead of XT), div256
instead of div16 like I wanted, but I figured it's hardware acting up.
Here's what happens on applying power:

1. The Leeds show a normal binary countdown (expected as the LED's
invert PORT)
2. The LED's show a normal binary countdown, with random Leeds much
dimmer than the others.
3. The Leeds show a normal binary count UP, with all Leeds quite dim.

__CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _LP_OSC

I replaced the PIC, tried MHz crystal, tried a MC34164 on MCLR, tried
manually pulling MCLR low. There is good decoupling etc. Read AN522
and still puzzled. Help is appreciated.


Ken

2000\01\28@054006 by Jason Harper

picon face
> I have a simple 16F84 LED flasher that is starting up weird.

All your problems seem to be due to register bank confusion.  In
particular, your InitPorts and InitTimers routines both leave bank 1
selected, so your main loop:

MAIN:           NOP
               NOP
               NOP
               NOP
               movf    counter, W      ; Output 'counter' to port B.
               movwf   PORTB
               GOTO    MAIN

is not doing at all what you think it is.  That reference to 'counter' is
picking the right value only by accident (it's at an address that's shared
between the two banks), and you're actually storing it into the TRISB
register (in bank 1 at the same address as PORTB in bank 0).  In other
words, instead of switching between low and high levels at your outputs,
you're switching between the random initial state of the PORTB latch and a
high impedance input state.  You might think that you're clearing PORTB, so
there wouldn't be any randomness to the behavior:

InitPorts:      bsf     STATUS, RP0     ; Select Bank 1.
               clrf    PORTB           ; All outputs low.
               movlw   B'00000000'     ; Set Port B is all outputs.
               movwf   TRISB           ;

but that's not so: the references to PORTB and TRISB (same address,
different banks) are both setting TRISB, since bank 1 is selected during
both references.

It appears that the PIC assembers' handling of register banks simply sucks
- the problems you're having (but not every such problem) could have easily
been detected by a simple data flow analysis pass in the assembler.  Until
such time as somebody writes an assembler that works right, you'll just
have to be more careful about register banks - check EVERY register access,
and make sure that the bank select bits are set appropriately (unless
you're using register that's duplicated across all banks).  This brings up
another problem I think your code has - you need to move the definition of
status_temp up a little bit, so that it's in one of the register addresses
that is duplicated between banks, OR you need to move that "bcf STATUS,RP0"
(4th line of INT_SERV) up one line.  As it is, status_temp may be written
to and read from different places, causing unexpected changes to the STATUS
register in your main program every time an interrupt occurs.
       Jason Harper

2000\01\28@151849 by paulb

flavicon
face
Jason Harper wrote:

> All your problems seem to be due to register bank confusion.  In
> particular, your InitPorts and InitTimers routines both leave bank 1
> selected, so your main loop:
>
> MAIN:           NOP
>                 NOP
>                 NOP
>                 NOP
>                 movf    counter, W      ; Output 'counter' to port B.
>                 movwf   PORTB
>                 GOTO    MAIN
>
> is not doing at all what you think it is.  That reference to 'counter'
> is picking the right value only by accident (it's at an address that's
> shared between the two banks), and you're actually storing it into the
> TRISB register (in bank 1 at the same address as PORTB in bank 0).

 That's it in a nutshell.  May I suggest a little lesson to be learnt
early in the piece?  Though the ability to swap register banks and
access TRIS and OPTION directly is a neat party trick, for the vast
majority of the time, it's an darn nuisance.  The cleanest way to avoid
this problem for the moment in the code given is the following:

 Edit P16F84.INC to include the statement
       ERRORLEVEL  -224
somewhere, say just before the register definitions, after the ENDIF
statement.  This will avoid certain rudeness from the assembler telling
you how to suck eggs.  If you ever use another 14-bit core part, you
will have to edit its include file also.

 Change all

       movwf   TRISA
to
       tris    PORTA

and similarly for PORTB.  Also hange

       movwf   OPTION_REG      ; TMR0 prescale=(Fosc/4)= ???
to
       OPTION                  ; TMR0 prescale=(Fosc/4)= ???

 Remove
       bsf     STATUS, RP0     ; Select Bank 1.

from the two places it *is* in your present code.

 In general, you will find it appropriate to ensure RP0 is zero for
most of your code, setting it briefly where you *really* need to to
access bank 1, and clearing it immediately afterward.  But to access the
TRIS and OPTION registers, a far better method has been provided to
cover 99.8% of circumstances, and that's the one you should use.

 Finally, though this is a nice exercise in interrupt coding, and I
should point out that the more common part of your interrupt routine can
be executed much faster, entirely without context saving (if you don't
see how, ask!), I do believe that many if not most applications can be
more easily implemented using code without interrupts and that
interrupts are more appropriately used for unpredictable events than
timer overflow.
--
 Cheers,
       Paul B.

More... (looser matching)
- Last day of these posts
- In 2000 , 2001 only
- Today
- New search...