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.

PIC 16F84A - Using BSF, having the Bit set as a varible HELP

Status
Not open for further replies.

FusionITR

Member
Hi.

I'm just starting with micro controllers and PICS and I have a question about using varibles in BSF and any instruction that has the format f,b (such as BTFSC).

Here is a part of the code I have right now:

Code:
START
	movlw 0x00
	movwf BITNUM
	movlw 0x08
	movwf BTLOOP
LOOP2
	btfsc CMDOUT,BITNUM
	bsf PORTB,BITNUM
	bcf PORTA,3				; Clock Low
;	call DELAY				; Delay
	bsf PORTA,3				; Clock High
;	call DELAY				; Delay
	incf BITNUM,f
	decfsz BTLOOP
	goto LOOP2

	return

When I use btfsc CMDOUT,BITNUM and bsf PORTB,BITNUM for the value of BITNUM it uses the register location (0x10) instead of register value (which I have increasing each loop). What I am trying to accomplish is to test each bit of a register with a loop.

Am I going about this the wrong way? Is there a way to test the value of the BITNUM register instead of the register location.
 
Would something like this work? The skpz and skpc pseudo opcodes are described in the MPASM help file...

Regards, Mike

Code:
START   movlw   b'00000001'     ;                                |B0
LOOP2   movwf   BITNUM          ;                                |B0
        andwf   CMDOUT,W        ; Is cmdout.bitnum bit set?      |B0
        skpz                    ; no, skip, else                 |B0
        iorwf   PORTB,f         ; set same bit on Port B         |B0
        bcf     PORTA,3         ; Clock Low                      |B0
        bsf     PORTA,3         ; Clock High                     |B0
        bcf     STATUS,C        ; clear Carry                    |B0
        rlf     BITNUM,W        ; all 8 bits tested (Carry=1)?   |B0
        skpc                    ; yes, skip, else                |B0
        goto    LOOP2           ; test next bit                  |B0
        return                  ;                                |B0
 
The Bitnumber in bsf type instructions has to be a constant, it cannot be a variable. To achieve what you want you need to shift and AND the bits.

Code:
START 
           movlw b'1000000' ;  start with bit 7
           movwf BITNUM 
           movlw 0x08 
           movwf BTLOOP 
LOOP2 
           movfw BITNUM 
           andwf PORTB,W
           btfss STATUS,Z;    test the zero flag
etc

           BCF   STATUS,C
           rrf   BITNUM,F
           decfsz
etc

I left out the middle bit because I’m not sure what you are trying to achieve. You test for a bit being set and then set it even though it’s already set. Edit, just read Mike's answer above and realized I misread your code - sorry.

A useful thing about using the shift instructions is you no longer need a loop counter as the carry bit will be set after the 8th rrf instruction.

HTH

Mike.
 
Thanks guys, that worked great!

I have one more problem though.

Is there anyway to write all 8 bits while only one bit being high each clock cycle (with the same kind of look as before).

What I mean is, if I have a input pin (RA0), and I want a all 8 bits variable to be set based on that pin being high or low each close cycle. For example, if RA0 was high all 8 clock cycles, i'd want my variable to be 0xFF.

Something like this

Code:
Clock Cycle 1
PORTA    00000001
DATAIN   00000001

Clock Cycle 2
PORTA    00000001
DATAIN   00000011

Clock Cycle 3
PORTA    00000001
DATAIN   00000111

etc...

I would like to use btfsc PORTA,1 but I dont know how to make it so each clock cycle the bit number it would set high increases. I dont how I can use boolean functions here since the bit set on PORTA is always the 0 bit. and any functions past the 0 bit would be zero.
 
Not sure how to insert the <clock> you mentioned but here's one way of many different ways that you might capture the RA0 bit and move it into your DATAIN variable...

May I ask what exactly you're trying to accomplish? It kinda' looks like bit-banged serial input, and if so, Mike, Nigel, and several other chaps have some decent examples floating around...

Good luck... Regards, Mike

Code:
START   movlw   b'00000001'     ;                                |B0
        movwf   DATAIN          ; initialize DATAIN              |B0
LOOP1   rrf     PORTA,W         ; capture RA0 in Carry           |B0
        rlf     DATAIN,f        ; shift bit into DATAIN          |B0
        btfss   STATUS,C        ; C=1, all 8 bits captured?      |B0
        goto    LOOP1           ; no, branch, capture another    |B0
        return                  ;                                |B0
 
Mike said:
Not sure how to insert the <clock> you mentioned but here's one way of many different ways that you might capture the RA0 bit and move it into your DATAIN variable...

May I ask what exactly you're trying to accomplish? It kinda' looks like bit-banged serial input, and if so, Mike, Nigel, and several other chaps have some decent examples floating around...

Good luck... Regards, Mike

Code:
START   movlw   b'00000001'     ;                                |B0
        movwf   DATAIN          ; initialize DATAIN              |B0
LOOP1   rrf     PORTA,W         ; capture RA0 in Carry           |B0
        rlf     DATAIN,f        ; shift bit into DATAIN          |B0
        btfss   STATUS,C        ; C=1, all 8 bits captured?      |B0
        goto    LOOP1           ; no, branch, capture another    |B0
        return                  ;                                |B0

Thanks! This code works but I dont really know whats going on with this shifting, do you mind explaining?

When you do rrf PORTA,w its shifting 00000001 to the right, and storing it in the W register, which stores 10000000. But after you loop and and do rrf PORTA,w why does it store it as 00000001 next time? And the rlf DATAIN,f line, what value is it using for f?
 
Sorry to run but I'm off to work... I hope someone can take the time to explain the example while I'm gone and if not I will be happy to explain tonight...

Meanwhile, let me recommend a good A-to-Z tutorial at the Elmer 160 Home Page... It's nicely structured, covers the scope of knowledge a newcomer often requires, and suggests good programming practices along the way...

Kind regards, Mike
 
The shift instructions work on nine bits, the 8 data bits PLUS the carry bit, so you're rotating a bit in to the carry, then out of the carry back in to another register.

As suggested, this looks like a bit-banging serial scheme?.
 
FusionITR said:
Thanks! This code works but I dont really know whats going on with this shifting, do you mind explaining?

When you do rrf PORTA,w its shifting 00000001 to the right, and storing it in the W register, which stores 10000000. But after you loop and and do rrf PORTA,w why does it store it as 00000001 next time? And the rlf DATAIN,f line, what value is it using for f?

I'll try and explain.

The 16 series PIC chip instructions RRF and RLF operate on 9 bits. The 8 bits in the file register and the Carry bit in the STATUS register.

Your example above, rrf PORTA,w does indeed shift 00000001 to the right and stores the result in W. The bottom bit gets moved into the carry bit and, at the same time, the carry gets moved into bit 7, and bit 7 into 6 etc.

I'll try and draw it.

>C>7>6>5>4>3>2>1>0v
^<<<<<<<<<<<<<<<<<

So,
rrf PORTA,w
shifts bit 0 of port A into the carry bit.
rlf DATAIN,f
shifts the carry bit into bit 0 of DATAIN.

The result from the rrf or rlf can go either into the W register or back into the file if came from. The F means put it back in the file, a W in the same place would mean put it in W.

Hope that makes sense.

Mike.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top