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).
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.
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.
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
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...
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?.
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?
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.