Yesterday I wrote: > In boolean, we can say that the 4 bit counter is for example: > ABCD. Let's say that I is the input that indicates we want to > increment the counter (when I is high we increment when I is > low the counter remains unchanged). Then the equations can be > written: > > D+ = D ^ I > C+ = C ^ (I&D) > B+ = B ^ (I&C&D) > A+ = A ^ (I&B&C&D) > > Now what's neat about this, is that we can handle all eight > inputs simultaneously. In other words, we can allocate/name > a PIC register 'D' and let it hold all 8 of the LSB's, let > 'C' hold the next LSB etc. I call these vertical counters > (although there may be a more appropriate name) because if > you view the RAM they occupy as a stack, then the counter > bits are grouped vertically instead of the more familiar > horizontal-single-register way. For a slightly less botched > explanation, check out: > > http://www.interstice.com/~sdattalo/technical/software/pic/vertcnt.html > > At any rate, we can write: > > MOVF PORTB, W > > ;debounce .... > > ;with debounced value in W > > XORWF last_value,W ;Get the changes from last time > XORWF last_value,F ;Save this sample for next time > ;note (A^B)^A == B > > MOVWF I > ANDWF B,W > ANDWF C,W > ANDWF D,W > XORWF A,F > > MOVF I,W > ANDWF C,W > ANDWF D,W > XORWF B,F > > MOVF I,W > ANDWF D,W > XORWF C,F > > MOVF I,W > XORWF D,F > > And you can check for rollovers like so with this chunk > just before you increment the counters. > > MOVF I,W > ANDWF A,W > ANDWF B,W > ANDWF C,W > ANDWF D,W > > There's another way to implement this vertical counter > that's slightly less efficient, but handles the rollover > case much better. But damn, I'm way too busy now. > I'm still too busy, but... MOVF PORTB, W ;debounce .... ;with debounced value in W XORWF last_value,W ;Get the changes from last time XORWF last_value,F ;Save this sample for next time ;note (A^B)^A == B ;W contains what we were previously calling 'I'. XORWF D,F ;D+ = D ^ I XORLW 0xff ;W = ~W = ~I IORWF D,W ;W = ~I | D+ = ~I | (D^I) XORLW 0xff ;W = ~(~I | (D^I)) ; = ~(~I | ~D&I | D&~I) ; = ~(~I | ~D) ; = I&D boolean magic! XORWF C,F ;C+ = C ^ (I&D) XORLW 0xff ;W = ~W = ~(I&D) IORWF C,W ;W = ~(I&D) | D+ = ~(I&D) | (C^(I&D)) XORLW 0xff ;W = ~(~(I&D) | (C^(I&D))) ; = ~(~(I&D) | ~C&(I&D) | C&~(I&D)) ; = ~(~(I&D | ~C) ; = I&C&D XORWF B,F ;B+ = B ^ (I&C&D) XORLW 0xff ; IORWF B,W ; XORLW 0xff ;W = I&B&C&D XORWF A,F ;A+ = A ^ (I&B&C&D) Which is the first routine I think I've ever written that contains only XOR's and IOR's. Again, I don't know if this is useful, but it's sort of neat none-the-less. Scott