Left or Right Justified ?

Thread Starter

Dodgydave

Joined Jun 22, 2012
11,303
ok i know how the result is stored , i have a 10 bit a/d pic 18f24k22,

left stores upper 8 bits in adresh lower 2 bits in adresl,
right stores lower 8 bits in adresl upper 2 bits in adresh,

now i want to know is will the upper two bits in right justified be of a value between zero and 3 because they are stored in the lsb part of an 8 bit file adresh,
or will they be read as the upper 2 bits of an 10 bit file thus having a value of 512 to 1024. hope that makes sense

what i am trying to do is put the values of adresh and adresl into a delay routine to create a variable delay using the decfsz d1,f and decfsz d2,f routine,

so i want to know which "justified" would give me the best result for time delay ?
 
Last edited:

JohnInTX

Joined Jun 26, 2012
4,787
Code:
unsigned int result; //16bits

result = ADRESH*256 + ADRESHL; // or
result = (ADRESH <<8) + ADRESHL; // if you prefer
If the ADC is left justified, result will be dddddddd dd000000
If the ADC is right justified, result will be 000000dd dddddddd

where ddd.. is the 10 significant bits of ADC reading. Left justification is useful when you want the ADC reading to span over a full integer plus its useful if you ever upgrade the converter to more sigbits - the result has the same range, just more precision. Right justification gives you a direct ADC reading from 0-2^n-1 bits in this case 0-1023. Useful for direct use or when you expect to do multiplication or other scaling on it.

Either way, the code snippet will load 'result' as shown with no further ado.
 

Thread Starter

Dodgydave

Joined Jun 22, 2012
11,303
That hasnt answered my question, what is the value of the upper two bits in the right justified, are they read as 1 ,2 ,3 or are they 256 to 1023
 

ErnieM

Joined Apr 24, 2011
8,377
That hasnt answered my question, what is the value of the upper two bits in the right justified, are they read as 1 ,2 ,3 or are they 256 to 1023
It doesn’t? Well gee, what values do you thing would fit into 000000DD?

And as far as your time delay goes that all depends on how you are using a 10 bit number (or 2 bit or 8 bit or any bit) to make some delay.
 

John P

Joined Oct 14, 2008
2,026
The point is, are you loading the A/D converter result into a 16-bit register pair, or treating the two bytes (adresl and adresh, or whatever you've loaded them into) as separate bytes? Actually if you insist on working in assembly language, you're stuck in the 8-bit world. I don't see the point in that when free compilers are so easily available (unless you absolutely must have total control over timing).

In a 16-bit number (of which the top 6 bits would always be 0 in this case) the contents of adresh would determine whether you've got a number in the range 0-255, 256-511, 512-767, or 768-1023. But if you haven't created a 16-bit quantity, then adresh is just another register with the value 0-3, and you have to consider it separately from adresl.

Note that the decfsz assembly language instruction only works with 8-bit quantities, not 16. And if you nest an inner loop inside an outer one, don't neglect the situation where either byte starts out already at 0. Decrement 0 and what do you have?
 

JohnInTX

Joined Jun 26, 2012
4,787
Right justify the ADC and do something like this..

Code:
unsigned int delay, i;

// launch the ADC conversion and wait until done
// then..
delay = ADRESH*256 + ADRESHL // read ADC value 0-1023

for (i=0, i<result, ++i)
__delay_ms(1);  // delay 1ms * ADC counts = 0 - 1023 ms (not counting overhead)
 

ErnieM

Joined Apr 24, 2011
8,377
Dodgydave: Since the majority of the world uses higher level languages you should learn how to read them (which is much easier then writing them). Asking for assembly coded routines is asking a bit too much IMHO.

Additionally, your asking for a vague concept rather than anything specific. Is this delay routine going for microseconds or hours or what?

John P: You can tighten that up a bit:
Code:
    unsigned int16 the_count;
 
    the_count = (adresh << 8) + adresl;
    while (the_count--);
I'm not sure if it compiles to anything smaller but it's worth a shot. :D
 

joeyd999

Joined Jun 6, 2011
5,283
Dodgydave: Since the majority of the world uses higher level languages you should learn how to read them (which is much easier then writing them). Asking for assembly coded routines is asking a bit too much IMHO.
Bad form, Ernie. High level languages are not a prerequisite of .asm. In fact, it should be the other way around.

And, while I think it is perfectly acceptable to provide .asm code examples to those who ask for them, I refuse to in this case because I consider hard-coded delay loops to be a lousy programming practice.
 

ErnieM

Joined Apr 24, 2011
8,377
John P: I just spent some time playing with both the C18 and the xc8 compilers. This works on them both:

Code:
    unsigned int16 the_count;
 
    the_count = ADRES;
    while (the_count--);
ADRES is defined in the dot h files and works like any other unsigned 8 bit int
 

ErnieM

Joined Apr 24, 2011
8,377
Bad form, Ernie. High level languages are not a prerequisite of .asm. In fact, it should be the other way around.
Another topic that will never have a definitive answer as it is entirely a matter of opinion and taste.

My opinion is assembly is not an introductory topic, if it was then every CS101 class would begin with assembly on some platform. A higher level language will teach program structure much better (as it actually exists!) than assembly which is inherently closer to spaghetti over structured code.

Yes, one can write structured assembly. It takes much knowledge and discipline to do so.

I would go a bit further to say knowing any assembly is unnecessary. It is quite useful and something I recommend knowing, but if you choose to skip it I don’t see any big issue.

(My apologies to DoggyDave as we derail his thread, though he seems to have abandoned all hope here anyway.)
 

djsfantasi

Joined Apr 11, 2010
9,163
John P: I just spent some time playing with both the C18 and the xc8 compilers. This works on them both:

Code:
    unsigned int16 the_count;

    the_count = ADRES;
    while (the_count--);
ADRES is defined in the dot h files and works like any other unsigned 8 bit int
I'm confused. you're assigning an unsigned 1nt16 an unsigned 8 bit? I thought ADRESH and ADRESL were unsigned 8 bit variables, of an unsigned 16 bit value?
 

ErnieM

Joined Apr 24, 2011
8,377
Yes, ADRESH and ADRESL were and still are unsigned 8 bit variables.

But the dot h defines ADRES as:

Code:
extern volatile unsigned short          ADRES               @ 0xFC3;
which is a different thing altogether.

I've since noticed that it is the most efficient way of doing the transfer. Takes just 4 instructions while doing a shift takes 9 and a multiply takes 8. joey could make a better count than I can; I don;t write C18 assembly and I suspect some of what I could as instructions are instead extended instructions.

Code:
12:                        delay1 = ADRESH *256 + ADRESL;
  3FB8    6E08     MOVWF 0x8, ACCESS
  3FBA    6A07     CLRF 0x7, ACCESS
  3FBC    50C3     MOVF 0xfc3, W, ACCESS
  3FBE    2407     ADDWF 0x7, W, ACCESS
  3FC0    6E03     MOVWF 0x3, ACCESS
  3FC2    0E00     MOVLW 0
  3FC4    2008     ADDWFC 0x8, W, ACCESS
  3FC6    6E04     MOVWF 0x4, ACCESS
13:                        delay2 = (ADRESH<<8) + ADRESL;
  3FC8    50C4     MOVF 0xfc4, W, ACCESS
  3FCA    6E08     MOVWF 0x8, ACCESS
  3FCC    6A07     CLRF 0x7, ACCESS
  3FCE    50C3     MOVF 0xfc3, W, ACCESS
  3FD0    2407     ADDWF 0x7, W, ACCESS
  3FD2    6E05     MOVWF 0x5, ACCESS
  3FD4    0E00     MOVLW 0
  3FD6    2008     ADDWFC 0x8, W, ACCESS
  3FD8    6E06     MOVWF 0x6, ACCESS
14:                        Value = ADRES;
  3FDA    CFC3     MOVFF 0xfc3, 0x1
  3FDC    F001     NOP
  3FDE    CFC4     MOVFF 0xfc4, 0x2
  3FE0    F002     NOP
 

Thread Starter

Dodgydave

Joined Jun 22, 2012
11,303
If you can point me to a web site that teaches C for pics, that starts at beginners level, i can try to understand it, but upto now i cant seem to find anywhere to explain all this Void, while, {} stuff...
 

JohnInTX

Joined Jun 26, 2012
4,787
Indeed, one of the enduring problems with C is that there is almost no information available on the web on how to use it.
 

ErnieM

Joined Apr 24, 2011
8,377
If you wish to use C on Microchip's products I suggest you look into the horse's mouth:

http://www.microchip.com/Developmenttools/ProductDetails.aspx?PartNO=DV164130

The user's guide shows how to do basic tasks in both assembler and C. The full source code is also provided. You can buy the board they work on too.

As far as learning C itself I'm sure Google will turn up a huge number of hits.

C is a small language, but the details can spiral out wide. Any tutorial for a beginner will cover void (indicated there are no variables in the list) or while() {} loops (a loop that runs until some condition is met).
 

Thread Starter

Dodgydave

Joined Jun 22, 2012
11,303
Thanks for the pointers, having studied the C web pages which are useless, i think i will stay with asm files .
 
Last edited:
Top