trick4GLTE trick4GLTE - 1 month ago 9
C Question

Bitwise rotate right of 4-bit value

I'm currently trying to control a stepper motor using simple full steps. This means that I'm currently outputting a sequence of values like this:

1000
0100
0010
0001


I thought an easy way to do this was just take my 4-bit value and after each step, perform a rotate right operation. "Code" obviously isn't following any kind of syntax, it's simply there to illustrate my thoughts:

step = 1000;
//Looping
Motor_Out(step)
//Rotate my step variable right by 1 bit
Rotate_Right(step, 1)


My problem is that there obviously isn't any 4-bit simple data types that I can use for this, and if I use an 8-bit unsigned int I will eventually rotate the 1 off to the MSB, which means the 4-bit value I'm actually interested in, will turn into 0000 for a few steps.

I've read that you can use structs and bit-fields to solve this, but the majority of things I read from this is telling me that it's a very bad idea.

Answer

With only 4 possible values you would use a table with 9 elements:

unsigned char table_right[] = { [0x1] = 0x8 , [0x2] = 0x1 , [0x4] = 0x2 , [0x8] = 0x4 };

When you need the next value you simply use the current value as the index:

unsigned char current = 0x4;    //value is: 0b0100
unsigned char next = table_right[0x4];  //returns: 0b0010
assert( next == 0x2 );

Doing this in a loop, will loop through all four possible values.

Conveniently, passing an invalid value, will return a zero, so you can write a get function that also asserts next != 0. You should also assert value < 9 before passing the value to the array.