Searching \ for 'SANITY CHECK -- Bit Manipulation of a 12C50x' in subject line. ()
Help us get a faster server
FAQ page: techref.massmind.org/techref/index.htm?key=sanity+check+bit
Search entire site for: 'SANITY CHECK -- Bit Manipulation of a 12C50x'.

Truncated match.
'SANITY CHECK -- Bit Manipulation of a 12C50x'
1999\01\11@043801 by

I am using a 12C509 to read four switches.  I have /MCLR enabled so that GP3 is
not
an input.  I also have GP0 as an output and I am running off of the internal R/C
oscillator (freeing up GP4,5).

Thus I have GP1,2,4,5 as inputs reading the switches.  I want to take the four
inputs and place them in the high nybble of W so that:
GP1 = Bit4 = Switch A
GP2 = Bit5 = Switch B
GP4 = Bit6 = Switch C
GP5 = Bit7 = Switch D

Here's what I wrote:

MOVF    GPIO,W  ; W = 00DC0BA0
;
; SHIFT BITS TO ALIGN WITH THE HIGH NYBBLE
BTFSC   W,5     ; is GP5 (pin 2) HI?
BSF     W,7     ; if it is, then Bit7=HI
BTFSC   W,4     ; is GP4 (pin 3) HI?
BSF     W,6     ; if it is, then Bit6=HI
ANDLW   0x0C6   ; W = DC000BA0
BTFSC   W,2     ; is GP2 (pin 5) HI?
BSF     W,5     ; if it is, then Bit5=HI
BTFSC   W,1     ; is GP1 (pin 6) HI?
BSF     W,4     ; if it is, then Bit4=HI
; W = DCBA0BA0
;
ANDLW   0x0F0   ; W = DCBA0000

It looks right to me but I am getting flakey results and I am suspicious of the
bit
manipulation.  It is late Sunday night in California and of course I have a demo
in
twelve hours...

Can anyone see a flaw here?  Is there a better way of shifting the bits?

My read of the datasheet says that bits 0,3,6,7 of GPIO (all non-inputs) should
read as 0's right?  I mean I don't need an ANDLW 0x036 after the read of GPIO or
something?

Any help appreciated,

Michael

**********************************************
Outside of a dog, a book is man's best friend.
Inside of a dog, it's too hard to read anyway!
Groucho Marx
**********************************************

> If you can spare a RAM location then try:
>
> (assume SWITCH has been equated to a spare ram address)
>
>       movf    GPIO,w          ; get switch values
>       movwf   SWITCH  ; store in ram location
>       rlf     SWITCH,f        ; rotate left to put in bits 0 - 3
movlw   0xf0            ; clear top nibble (may not need this)
andwf   SWITCH,f        ;
>       swapf   SWITCH,w        ; swap upper and lower nibbles and put back
> in w
>
>
>
Doubtless the asm gurus will scorn this and show an obvious way that dosen't
use w :o)

{Quote hidden}

MRJONES@NT.COM wrote:

> > (assume SWITCH has been equated to a spare ram address)
> >
> >       movf    GPIO,w          ; get switch valuesI'll try to follow you on t
his...
W = 00DC0BA0
> >       movwf   SWITCH  ; store in ram locationSWITCH = 00DC0BA0
> >       rlf     SWITCH,f        ; rotate left to put in bits 0 - 3SWITCH = 0DC
0BA0x   where x = CARRY
>         movlw   0xf0            ; clear top nibble (may not need this)W = 1111
0000
>         andwf   SWITCH,f        ;SWITCH = 0DC00000
> >       swapf   SWITCH,w        ; swap upper and lower nibbles and put back in
wW = 00000DC0
Hmmmm, I need W = DCBA0000

Did I miss something?  I have been up all night and it is now 5:20AM so anything
is
possible.

Does my BSF idea have any holes that you see?

Michael

**********************************************
Outside of a dog, a book is man's best friend.
Inside of a dog, it's too hard to read anyway!
Groucho Marx
**********************************************

Michael J. Ghormley wrote:

>         ; SHIFT BITS TO ALIGN WITH THE HIGH NYBBLE
>         BTFSC   W,5     ; is GP5 (pin 2) HI?
>         BSF     W,7     ; if it is, then Bit7=HI
>         BTFSC   W,4     ; is GP4 (pin 3) HI?
>         BSF     W,6     ; if it is, then Bit6=HI
>         ANDLW   0x0C6   ; W = DC000BA0
>         BTFSC   W,2     ; is GP2 (pin 5) HI?
>         BSF     W,5     ; if it is, then Bit5=HI
>         BTFSC   W,1     ; is GP1 (pin 6) HI?
>         BSF     W,4     ; if it is, then Bit4=HI
>                         ; W = DCBA0BA0
> ;
>         ; MASK OFF LOW NYBBLE
>         ANDLW   0x0F0   ; W = DCBA0000

> It looks right to me but I am getting flakey results and I am
> suspicious of the bit manipulation.  It is late Sunday night in
> California and of course I have a demo in twelve hours...

The "flakiest" thing here I can see is that you can't do bit
manipulation on the W register.  "W" as a symbol translates to zero,
and is a synonym for the INDF register.  Which register you are actually
manipulating therefore depends on the present setting of the FSR, which
is?...
--
Cheers,
Paul B.

At 17:26 11/01/99 -0800, you wrote:
>Did I miss something?  I have been up all night and it is now 5:20AM so
anything is
>possible.
>
>Does my BSF idea have any holes that you see?

Yes!  I'm guessing you're seeing false '1's in the result for D and C?

>         MOVF    GPIO,W  ; W = 00DC0BA0

At this point, what if W contains 11DC1BA1?  You assume it's zero- is that
_definitely_ correct?  ie are all the unused pins set as outputs and set to
zero, and the pin is not being driven?  Even so, it would be better to
andlw b'00110110'       ;Set unwanted inputs to zero

>         ; SHIFT BITS TO ALIGN WITH THE HIGH NYBBLE
>         BTFSC   W,5     ; is GP5 (pin 2) HI?
>         BSF     W,7     ; if it is, then Bit7=HI

w,7 could still be set at that point if it was '1' before, unless you make
the change suggested above.

>         BTFSC   W,4     ; is GP4 (pin 3) HI?
>         BSF     W,6     ; if it is, then Bit6=HI

w,6 could still be set at that point if it was '1' before, unless you make
the change suggested above.

>         ANDLW   0x0C6   ; W = DC000BA0

That will stop further problems.

Nigel
--
Nigel Orr                  Research Associate   O   ______
Underwater Acoustics Group,              o / o    \_/(
Dept of Electrical and Electronic Engineering     (_   <   _ (
University of Newcastle Upon Tyne             \______/ \(

It is not good practice to manipulate bits in W (don't ask me why, it
just is :)).
You can test bits on GPIO direct with out loading it in W first (ex:
BTFSC GPIO,5), so here goes:

CLRF    TEMP    ;TEMP IS ANY RAM
BTFSC   GPIO,1
BSF     TEMP,4  ;A
BTFSC   GPIO,2
BSF     TEMP,5  ;B
BTFSC   GPIO,4
BSF     TEMP,6  ;C
BTFSC   GPIO,5
BSF     TEMP,7  ;D
MOVF    TEMP,W  ;DONE! W=DCBA0000

Hope this helps
Quentin

rlf     GPIO,w          ;      W = 0DC0BAxc   x = old GP0,
movwf   SWITCH          ; SWITCH = 0DC0BAxc   c = old carry
rlf     SWITCH,f        ; SWITCH = DC0BAxc0
movlw   0x18            ;      W = 00011000
andwf   SWITCH,w        ;      W = 000BA000
addwf   SWITCH,f        ; SWITCH = DCBA0xc0

Obviously, two more instructions can "clean" the spurious bits out.
--
Cheers,
Paul B.

Hmm...maybe I should actually *read* stuff a bit more thoroughly before
diving in with both feet....
I kinda missed the bit about the bit positions you were using, I assumed you
were reading bits 1 -4 for the port.

Yep, total b*ll*cks I'm afraid, my only defence being that I got up at 5:30
this morning.

Having looked at your code properly now (i.e after 4 cups of coffee) the
problem seems to be that you can't do bit sets or clears on W, it isn't
addressable as a normal file register.  You'll have to do the bit operation
on a defined variable and copy it back to W.

Regards

Mike Rigby-Jones
mrjonesnortelnetworks.com

{Quote hidden}

At 16:14 1999-01-11 +0200, you wrote:
>It is not good practice to manipulate bits in W (don't ask me why, it
>just is :)).

There_is_no_machine_instruction_for_it!

BxF / BTFSx only works on file registers.

/Morgan
Morgan Olsson                   ph  +46(0)414 70741
MORGANS REGLERTEKNIK            fax +46(0)414 70331
H€LLEKS           (in A-Z letters: "HALLEKAS")
SE-277 35 KIVIK, SWEDEN               mrtiname.com
___________________________________________________________

Might as well do it straight to W though, no need for
temp..

clrw
btfsc gpio,1
iorlw 0x08h
etc..

Quentin wrote:
{Quote hidden}

My sanity has been checked and found lacking!  :^(
Many thanks for all the help.

It was an all-nighter and I didn't make the demo.  As a sign of my plight, you
might have noticed that my system clock was 12 hours ahead.  At least I was up
front about not having the demo ready.  The client reponded well to my
honesty.

I have the code working fine right now -- I think.  Tomorrow will be another
day.  *sigh*

MICHAEL -- I truly thank you for the prompt response.  We all get tripped up
now and again.  It is evedent that I certainly did!  It takes some nerve to
respond to this list, as one or two of the regulars seem to have a lot of
bones in front of their cave!

NIGEL -- Yes, the non-input pins are read as zeroes per the datasheet:

"GPIO is an 8-bit I/O register. Only the low order 6 bits
are used (GP5:GP0). Bits 7 and 6 are unimplemented
and read as '0's. Please note that GP3 is an input only
pin. The configuration word can set several I/Oâs to
alternate functions. When acting as alternate functions

QUENTIN -- You hit upon the correct scheme.  This works a treat.  Many thanks.
I had actually used this scheme on my calibration routine for the `50x/JW
parts but had forgotten my previous lesson.

PAUL --  Yes, BSF W,7 compiled (without warning) to 0x05E0 which sets bit
seven in the INDF register.  No wonder I had flakey results!  BTW, your AND
shift at the end is cute.

MORGAN -- You are right, there is no such op-code.  However, MPLAB compiles
the assembly code without complaint.  As stated above, I was toggling bits in
the INDF!

Thank you one and all.  I was in a spot and my brain had shut down.  I am
going home for some sleep!  38 hours is enough!

Michael