CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

ignore bits

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
aaronik19



Joined: 25 Apr 2011
Posts: 297

View user's profile Send private message

ignore bits
PostPosted: Mon Dec 19, 2011 2:43 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Dec 19, 2011 3:07 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Dec 19, 2011 3:33 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Dec 19, 2011 3:45 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Dec 19, 2011 4:23 pm     Reply with quote

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

View user's profile Send private message AIM Address

PostPosted: Mon Dec 19, 2011 8:01 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Dec 20, 2011 2:44 am     Reply with quote

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

View user's profile Send private message AIM Address

PostPosted: Tue Dec 20, 2011 6:42 am     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Dec 21, 2011 7:28 am     Reply with quote

thanks to all. Both methods worked fine Smile great help thanks guy and best wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group