View previous topic :: View next topic |
Author |
Message |
aaronik19
Joined: 25 Apr 2011 Posts: 297
|
ignore bits |
Posted: Mon Dec 19, 2011 2:43 pm |
|
|
Do you know with the procedure to map the new byte onto output port, but some bits must be ignored? For example currently I have the following byte on portB 00101110 and I sent the new byte 001000XX where I need XX to be ignored (so that keep the previous state). Do you have any idea how I can ignore these bits? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19544
|
|
Posted: Mon Dec 19, 2011 3:07 pm |
|
|
Basically, you can't.
However you can get the effect in software, by reading the bits you want unchanged, and then combining these with the outgoing value.
You don't say whether this is a PIC16 or a PIC18?.
On the latter, there is a separate latch, so you can read this.
Best Wishes |
|
|
aaronik19
Joined: 25 Apr 2011 Posts: 297
|
|
Posted: Mon Dec 19, 2011 3:33 pm |
|
|
thanks for the reply. actually I am using the PIC16F687 for this project. What kind of latch you are refering for? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19544
|
|
Posted: Mon Dec 19, 2011 3:45 pm |
|
|
On the PIC18, the output latch, is separate from the actual port. So you can at any time you want, read what bit value was sent to a port, _without_ affecting the port itself.
On a PIC 16, you would have to do it yourself.
Code: |
int8 opval;
//Use this instead of output_b
void outputb_latched(int8 val) {
opval=val;
output_b(val);
}
//Use this to output the masked value
void outputb_masked(int8 val) {
val&=0b11111100; //get top six bits of value to output
opval&=0b00000011; //get two bits to save;
output_b(opval | val);
}
|
Whenever you use output_b and want to write the whole port, use 'outputb_latched', and when you want to output just the top six bits leaving the two bits unchaged, use 'outputb_masked'.
Best Wishes |
|
|
aaronik19
Joined: 25 Apr 2011 Posts: 297
|
|
Posted: Mon Dec 19, 2011 4:23 pm |
|
|
Ttelmah, thanks for your reply. But acccording to my knowledge, since you are OR gate the val an Opval, the output will be always 11111111 most of the time. I do not know why you used that working. Can you please explain more if you can?
Thanks |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Mon Dec 19, 2011 8:01 pm |
|
|
Code: |
// per your example -to preserve the low order 2 bits :
// NEW bits is expected to contain the hi order 6 bits you want
// and we mask out the low order bits in case they were not 0
void changebits ( byte newbits ){
output_b( (input_b()&3) | (newbits&0b11111100) );
}
// any easier to understand ??
|
the only thing you want to be careful of is the few ns of glitching that can occur during the port update on some pic parts --
the 18f4520 comes to mind in that context |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19544
|
|
Posted: Tue Dec 20, 2011 2:44 am |
|
|
aaronik19 wrote: | Ttelmah, thanks for your reply. But acccording to my knowledge, since you are OR gate the val an Opval, the output will be always 11111111 most of the time. I do not know why you used that working. Can you please explain more if you can?
Thanks |
Be careful of asmboy's suggestion. What happens here is that the port is changed to be an _input_, the value on it is read, then the low two bits of this are combined with the bits you want to send, and the port then changed to an output, and the whole result sent.
Unfortunately also, if the output loads are high a port pin that has had a '1' written to it, may not always read as a '1' back, and in which case the bit gets lost.
It _may_ work, but depends on the loads on the pins, capacitances, etc. etc., but may also cause problems....
On my code, OR does not work the way you think. You may be confusing the effect of a logical OR '||' from a bitwise OR '|'.
Imagine you have:
0b01010101 sent out on the port using 'output_latched', and therefore stored in 'opval'. Then you send 0b10101010 using 'outputb_masked'.
The incoming 10101010 gets changed to 10101000 by the '&'.
Then the opval value gets changed to 0b00000001 by it's '&'.
10101000
00000001
or them together
10101001
OR gives a '1' wherever there is a '1' in either source byte, and nowhere else. So the top six bits of your value get output, combined with the low two bits of what has previously been sent.
On the PIC 18, the value previously sent, is available in the 'LATB' register, so asmboy's suggestion, can be made to work perfectly (without any glitches), using:
Code: |
#byte LATB=getenv("SFR:LATB")
// per your example -to preserve the low order 2 bits :
// NEW bits is expected to contain the hi order 6 bits you want
// and we mask out the low order bits in case they were not 0
void changebits ( byte newbits ){
output_b( (LATB&3) | (newbits&0b11111100) );
}
// any easier to understand ??
|
This uses the hardware latch so that the byte is output without having to change the port direction for a few cycles, and gets rid of the potential glitch, and any potential problems if the port loading is high. However doesn't work on the PIC16 chips.
Best Wishes |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Tue Dec 20, 2011 6:42 am |
|
|
Quote: |
port is changed to be an _input_, the value on
|
I think that is NOT for sure true, you see -
IF you use fast_IO() and declare portb tris as all 0
as i ALWAYS DO for output - i simply don't want the compiler involved in
port I/O direction - as i don't trust compiler generated TRIS in a program i am going to sell - i am willing and even eager to be in charge of I/o direction ;-))
Anyway - with fast_io(b) - you get this on an 18F part :
Code: |
.................... void changebits ( byte newbits ){
.................... output_b( (input_b()&3) | (newbits&0b11111100) );
0004: MOVF F81,W
0006: ANDLW 03
0008: MOVWF 0E
000A: MOVF 0C,W
000C: ANDLW FC
000E: IORWF 0E,W
0010: MOVWF F8A
.................... }
|
but if you are STILL anxious - you can always ( memory permitting)
maintain a phantom portb var byte --
and operate on IT - then output the phantom variable. |
|
|
aaronik19
Joined: 25 Apr 2011 Posts: 297
|
|
Posted: Wed Dec 21, 2011 7:28 am |
|
|
thanks to all. Both methods worked fine great help thanks guy and best wishes |
|
|
|