Forums

What is the use of left and right alignment in ADC registers?

Started by Aditya_Ubarhande 4 months ago14 replieslatest reply 3 months ago165 views

Hi,

I am using the STM32F4 Discovery Board. I was going through the ADC peripheral and I saw this:screenshot (1401)_5969.png

Right and Left alignment of 12-bit data. What is meant by this?

I mean what is the use of aligning data to right side of the register or left side of the registers?

I am seriously stuck in this question.

Please explain this to me in the simplest words possible. 

Also, it would be really great if you let me know the advantage and disadvantage of both the alignments.


[ - ]
Reply by CustomSargeJune 4, 2021

It can be handy depending on what processing you do with the value.

Right justified is for dealing with it as a simple 12 bit value.

Left is for treating it as a 16 bit.

It saves you from doing the shift by 4 yourself.

Interesting aspect is "sign" injection: straight 0-4095 or +/- 2047.

[ - ]
Reply by Aditya_UbarhandeJune 4, 2021

So, do you mean that it would save me the bit shifting for reading the data in right alignment

[ - ]
Reply by thiccrickJune 4, 2021

Basically, right-aligned is what you’ll want most of the time because it’s just a 16-bit number where only the lower 12 bits actually contain useful information (There isn’t a 12-bit integer in standard C, so the 16-bit integer is the next best thing).

I think what’s probably more confusing is why the heck would you want to use left-justified then? Well, it’s useful when say, you’re constrained on memory and just want 8 bits of precision. In that case, you can easily just take the most significant byte (top 8 bits) without having to do any shifting and store that into an 8-bit integer. Now you can store twice as many values, albeit at a lower precision.

[ - ]
Reply by Aditya_UbarhandeJune 5, 2021

@thiccrick


I am familiar with the right alignment and I know that out of the 16 bits, only 12 bits are useful because the ADC has a maximum amount of 12 bit. But I am totally not familiar with left alignment. But, from your reply what I understand is that the 12 bit data with start from the MSB instead from the LSB right?

Also, what is precision and why do I need it in less amount of memory?

I understand that in case of less memory, I need to save as much space as possible by choosing the right type of variables, but again what is 8 bits of precision?

Please answer me (in simple words :-)

Thanks for the reply!

[ - ]
Reply by DilbertoJune 4, 2021

Hi, @Aditya_Ubarha!

The other use for left alignment is whether you'll have to scale ( = multiply ) the A/D's result in order to do some math to obtain a meaningful measurement.

This is the case when you use just integer arithmetic for these computations.

This way, left alignment can save you a multiply operation on each computation.

If you have to do several such operations, this can save you a good processing time.

Cheers



[ - ]
Reply by Steve_WheelerJune 4, 2021

@Dilberto is right. This is the key thing. For example, if you define a 32-bit integer to contain a 16-bit integer value in the upper 16 bits, and a fraction in the lower 16 bits, then the left-justified conversion value is effectively a fraction between 0 and 0.9998 (roughly), and scaling the conversion result into a real-world value becomes a simple multiplication.

[ - ]
Reply by Aditya_UbarhandeJune 5, 2021

@Steve_Wheeler

But can't I do the multiplicaiton in the right alignment? It would be great if you share a diagram for me to understand. Please

[ - ]
Reply by Steve_WheelerJune 5, 2021

You certainly can; it's just a matter of what's more understandable under your specific set of circumstances. 

Say, for example, you were monitoring a battery level that was nominally 9V. To convert from a right-justified ADC value to a voltage requires, effectively, the equation

volts = reading * 9 / 4096

(which works for floats, but I'm operating under the assumption that floating-point can't be used in this instance.)

Presuming that you're using the scaled representation I mentioned before, with the implied decimal point in the middle of a 32-bit value, is it more understandable to multiply a left-aligned voltage by 9, or to multiply a right-aligned voltage by 144 (9 x 16)?

If you're looking at bits, the scaled representation I mentioned earlier places the understood decimal point as follows:

0000000000000000.0000000000000000

So, a left-justified value from the ADC would be

0000000000000000.vvvvvvvvvvvv0000

which makes it a fractional value. Multiplying by 9 would shift it left 3 bits and add in the value once more, resulting in a maximum value of 8.something, or

000000000000xxxx.xxxxxxxxx0000000

If you start with a right-justified value, you calculate a 9V real-world value with the equation

value = result * 144

to produce the same scaled representation, because you're starting from

0000000000000000.0000vvvvvvvvvvvv

which means that the maximum ADC value does not match up with where the decimal point is expected to be. Effectively, the left-justified value hides the scaling factor necessary to get into that representation.

If you're not using that representation, then the tradeoffs are different. If you use a scaled representation with the decimal point after the 12th bit

00000000000000000000.000000000000

then the right-justified value becomes the simple thing to use, because you have

00000000000000000000.vvvvvvvvvvvv

When it comes down to it, it's a mental trick. It's all a matter of looking at the same data in different ways, and figuring out which is the one that makes the most sense in your specific set of circumstances.

Treating an integer as a fractional value can sometimes be quite useful - I once had write an assembly routine to print ASCII representations of integers on a PIC when I didn't have enough RAM to do the simple algorithm of repeated divisions by 10, which produces the digits in reverse order, so you have to save them in a buffer to print out once you've extracted them all. Multiplying the integers by a scaling factor to convert them into a fraction allowed me to extract each digit in order by multiplying by 10, and required no more RAM than either multiplication or division would use. 

[ - ]
Reply by Aditya_UbarhandeJune 5, 2021

@Steve_Wheeler

Thanks Steve!

I appreciate your efforts for such a enormous answer!

In the decimal representation you typed there, I feel that right alignment is a bit easy to read than the left alignment.

Also, I have got one last query, suppose the DR was of 16 bit and so was the ADC.

In this case, will the left or right alignment matter?

Also, are we taking the decimal because the value will be a floating one? If yes, then why didn't you type any value before the decimal point?


Again, thanks a ton for the answer!

[ - ]
Reply by Steve_WheelerJune 6, 2021

Put it this way: the right-justified value is an integer in the range 0-4095. If you're measuring a voltage that has a maximum value of 4.096 volts, you have 1 bit per millivolt. If you're measuring anything that doesn't have a one-to-one correspondence between bits and real-world value, you will have to multiply your conversion value by some scaling value. I used to work with a hardware engineer who liked to scale his analog voltages to a maximum of 4.096 volts going into the ADC so that bits were equal to millivolts. This is not usually the case.

For clarity, it may be easier to do the scaling with two multiplications or with a multiplication and a division, which allows one number to be the real-world value you're measuring, and the other is a "magic" number that makes that calculation work.

The left-justified conversion result can be treated as a fractional value in the range 0.0 to 1.0, with 1.0 having a binary representation of

1.0000000000000000

Note that this is a 17-bit value, which is why I was talking about 32-bit values in my previous response. Because it is a fraction in the range 0-1, you only need one multiplication that does not involve a magic number to get the real-world value. You do, however, have to be able to use the numbers in that representation.

I did not put anything before the decimal point (actually, it's a binary point) because I'm treating the left-justified conversion result as zero point conversion-value.

If you want to know more, do a search for "fixed point number representation" or "fixed point arithmetic." It's not floating-point, but it does allow representation of fractions, and the left-justified ADC results work well with it, and there's a lot of good information out there. 

[ - ]
Reply by Aditya_UbarhandeJune 6, 2021

Thanks Steve! 

So you meant that when using a right aligned mode, we need to multiply or divide several times with or without magic number to get a real world value. Buy in the left justified value, we don't have to multiply or divide with magic numbers but one or two multiplication would give me a real world value. 

Is this the right definition for a beginner? 

Also can you please let me know some nice websites through which I can study embedded stuff and some new concepts? 

I have taken courses on udemy but it would be really great to have another  knowledge source. 

Again thanks for your efforts! 


[ - ]
Reply by Steve_WheelerJune 6, 2021

You don't have to multiply or divide at all, if you can use the conversion value directly. If you're reading a joystick to get position on a screen, is a right-justified value of 3750 within the dimensions of your display? If not, then you'll have to scale it. Does your conversion value match temperature, or voltage, or whatever you're measuring? If not, then you'll have to scale it.

Left-justified values, to me, are fractional values, so they naturally fall into the range of 0-1. This makes it simple to perform one multiply by the maximum value you want, using fixed-point numbers, to get the scaled value you need.

Right-justified values tend to need two multiplications, or a multiply and a divide, to be scaled to an arbitrary range. Often at least one of those can be a bit-shift. That's likely to cost more time per reading than with a left-aligned result. However, if you're not using fixed-point numbers, it's likely not a problem. Using fixed-point numbers has its own costs; they just fall into different parts of the program.

As for websites for study, I can't make any recommendations, because the sites I used most often were associated with magazines (Embedded Systems Programming, for one) that have been out of business for several years. If I'm interested in some topic that isn't covered in the books or back issues of magazines that I have accumulated, I just look on YouTube or do a web search for it.

[ - ]
Reply by Aditya_UbarhandeJune 7, 2021

@Steeve_Wheeler

Thanks Again.

Just clarify my one point so that it gets fixed in my brain and I can close the discussion

Advantage of right alignment: I can use the value directly as long as scaling is not required.

Advantage of left alignment: I can scale it easily by just one multiply or one divide.

Is the thing written above correct?

Please let me know the changes if it is wrong.

Thanks!

Aditya.

[ - ]
Reply by DilbertoJune 11, 2021

Hi, @Aditya_Ubarha!

What I think @Steve_Wheller is trying to say to you is that LEFT JUSTIFIED works as a percentage ( in p. u. notation ) of the A/D's full-scale, so you need only multiply it by YOUR quantity's full-scale to get the right amount.

Cheers!