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

shift right and left
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
georgei
Guest







shift right and left
PostPosted: Mon Aug 17, 2009 11:54 pm     Reply with quote

hello.

I am trying to shift a byte right and left.
I know 2 commands for that:
1. a<<2
2. shift_left(a,1,0)

The final bit is lost in both of them, but I need a function that move right and left in cycle-which mean that the msb is coming back to the right, and I am not losing any bit. Someone know a function for that?

Anyway, why this code is not working?
Code:

a=0b00000101;

WHILE(1)
{
output_c(a);

delay_ms(2000);
a<<1;

}

I get the word in port C, but it doesn't move right\left.
How can I move it without losing the msb\lsb ?

thanks.
Ttelmah
Guest







PostPosted: Tue Aug 18, 2009 2:15 am     Reply with quote

What you want is to use the _rotate_ function.

It is fairly obvious if you think about it.

01000111

Shift it left

10001110

and again

00011100

Shift, is like a 'slider', moving the byte. Anything going out the 'top' os lost, and you get new '0' values (or optionally '1'), introduced at the bottom. So on the last shift, you lose the top '1'.

Now, start with the same byte

Rotate it left

10001110

and again

00011101

With rotate, the bits are treated like a 'wheel', with the stuff going off one end, and arriving back at the other. So on the last rotation, the MSb, gets rotated back to the start.

If you look at rotate_right, and rotate_left n the manual, you should find what you want.

Best Wishes
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Tue Aug 18, 2009 2:18 am     Reply with quote

You mean rotate.

It strange realy because the assembler has rotate instructions but C (as far as I know) doesn't have a direct map to an operator.

One way to do it in C is
Code:

// Rotate right by 1
int rotateRight(int val)
{
  int flag;

  flag = (val & 0x01) << 8;
  val = (val >> 1) | flag;
  return(val);
}

// Rotate left by 1
int rotateLeft(int val)
{
  int flag;

  flag = (val & 0x80) >> 8;
  val = (val << 1) | flag;
  return(val);
}


This can be done better and quicker using a bit of asm

#asm
RLFC val, F
RRCF val, F
#endasm

Or using CCS code

rotate_left(&val, 1);
rotate_right(&val, 1);
Ttelmah
Guest







PostPosted: Tue Aug 18, 2009 2:49 am     Reply with quote

Er. Wayne, look at 'rotate_right', and 'rotate_left' in the manual....

Best Wishes
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Tue Aug 18, 2009 4:11 am     Reply with quote

Ttelmah wrote:
Er. Wayne, look at 'rotate_right', and 'rotate_left' in the manual....

Best Wishes


Er. look at the end of my post Smile

I posted all 3 methods Smile
Ttelmah
Guest







PostPosted: Tue Aug 18, 2009 8:13 am     Reply with quote

What I don't understand, is why you think 'C' (as opposed to CCS C), should have a function....

You say 'assembler' has this function, but this is simply not true, for quite a few processors. If you look at some of the mini computers dating from the date when C was written, a lot don't have rotate functions in their assembler. It had to be done by masking off the extra bit, shifting, then masking the bit back in. You can write this quite easily in C, using something like (for a byte, shifting left):

(val & 0x80)?(val<<1)+1:(val<<1);

Or test the bottom bit when going the other way.

Because the PIC, does have an assembler instruction for this, CCS have added the directives to access this.

Rotate functions are actually quite rare in early assembler, and weren't considered that useful. What is annoying in the CCS _shift_ functions, is that they don't allow direct access to the bit shifted out.

Best Wishes
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Tue Aug 18, 2009 8:44 am     Reply with quote

First of all this is very off topic.

Secondly I never said C should have a function I said it is strange that it didn't when many, I never said ALL, processors have a built in function, in fact I only specified that the PIC did.
I know many that do, I don't personally know of any that don't without looking but I am sure there are some, and i have programmed a few processors in my time as I am sure you have.

It would have been very easy to map a C function to a rotation function in asm even if the processor didn't have one! I just stated that it was strange that it was left out when they developed C.

Yes you can easily write code in C to do the job as I posted, so why did you have to go and show an obfuscated version, and before you say it, it is only obfuscated if you don't understand it! Smile

So, CCS have decided to include a function to do rotation, I assume that this is directly mapped to the pic opcode ?

Sorry if I sound a bit off it just seems like you are arguing for the sake of arguing!

All I did was correct you for missing off the fact that I DID read the CCS manual to see if there was a function to do it, and I actually posted the fact that it did.

I couldn't understand why you told me to look in the manual when I obviously did Smile

Enjoy Smile
Ttelmah
Guest







PostPosted: Tue Aug 18, 2009 8:57 am     Reply with quote

Because they were tucked away at the bottom of the post, when to answer the original question, they should have been the first choices....

It does really come down to them not being considered useful functions. Shifting data in and out, is common, rotating relatively rare.

Best Wishes
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Tue Aug 18, 2009 9:09 am     Reply with quote

Ttelmah wrote:
Because they were tucked away at the bottom of the post, when to answer the original question, they should have been the first choices....


Should they when they make the code CCS specific and harder to port!
Just a thought Smile

It's like using make8, make16, shift_left and shift_right. Why use those when it is just as easy to use standard C to do the same thng ?

OK, in the case of rotate_left and rotate_right there is a good reason, and that is because CCS maps it to a single opcode for an 8 bit value, hopefully, I havn't checked Smile
You could do the same with inline assembler, or even write your own function / macro to do it.

But it does annoy me when people have to resort to non standard functions to do something that is easier to do in C anyway, only because they either don't know C or someone has told them to use the function, instead of showing the C code to do it!
georgie
Guest







so..
PostPosted: Tue Aug 18, 2009 10:47 am     Reply with quote

you saying too much but at the end i dont know how to rotate Smile

lets say i have 0b01010101 and i need to rotate it to left,without loosing bit.

what is the exact line for that ??

thanks a lot..
mkuang



Joined: 14 Dec 2007
Posts: 257

View user's profile Send private message Send e-mail

PostPosted: Tue Aug 18, 2009 10:55 am     Reply with quote

Page 200-201 of the manual the example is:

x = 0x86; //0b 1000 0110

rotate_left (&x, 1);
//x is now 0x0d //0b 0000 1101

The thing to remember I suppose is that the rotate functions expect a pointer as the first argument.
John P



Joined: 17 Sep 2003
Posts: 331

View user's profile Send private message

PostPosted: Tue Aug 18, 2009 4:18 pm     Reply with quote

This does it pretty economically:

Code:

   i <<= 1;
   if (bit_test(status, 0))
      bit_set(i, 0);


This works because when the shift operation takes place, the top bit is shifted out into the carry bit, i.e. bit 0 of the status register, and the bottom bit is cleared. So you can test the carry bit, and if it contains a 1, set the bottom bit of the register which was shifted.
georgie
Guest







THANKS
PostPosted: Wed Aug 19, 2009 1:14 am     Reply with quote

thanks a lot. it helped me so much.

but if i need to rotate only the 4 low bits ?

lets say i have : 00001010
i need to rotate left only the 4 right bits.. so i wanna get: 00000101
how i do that with rotate ?
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Wed Aug 19, 2009 5:55 am     Reply with quote

It starts to look like a school assignment where we are doing your work. Post an attempt on solving the problem yourself and if you don't succeed we'll be happy to help you improve on it.
SET



Joined: 15 Nov 2005
Posts: 161
Location: Glasgow, UK

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Wed Aug 19, 2009 6:24 am     Reply with quote

Quote:
thanks a lot. it helped me so much.

but if i need to rotate only the 4 low bits ?

lets say i have : 00001010
i need to rotate left only the 4 right bits.. so i wanna get: 00000101
how i do that with rotate ?


John P's code should give you a hint on how to do this - then check out bitwise & and | operators! (Ok extra hint - you need to get the low 4 bits out (& with 0x0F) rotate that, and OR (|) back in.)
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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