Electronics > Microcontrollers

Combining ADC Result Over 2 Registers Into 1 Variable

<< < (4/5) > >>

johnmx:
The simplest, cleanest and fastest way:

--- Code: ---union IntOr2Char
{
unsigned int ir;
unsigned char cr[2];
};

union IntOr2Char ADCResult;

ADCResult.cr[1] = ADRESH;
ADCResult.cr[0] = ADRESL;

ADC result can be accessed like this: ADC_Mean += ADCResult.ir;
--- End code ---

RayJones:

--- Quote from: johnmx on June 03, 2011, 10:12:40 am ---The simplest, cleanest and fastest way:

--- Code: ---union IntOr2Char
{
unsigned int ir;
unsigned char cr[2];
};

union IntOr2Char ADCResult;

ADCResult.cr[1] = ADRESH;
ADCResult.cr[0] = ADRESL;

ADC result can be accessed like this: ADC_Mean += ADCResult.ir;
--- End code ---


--- End quote ---

Finally commonsense prevails.
You must remember at the end, a 16 bit value is exactly as johnmx has shown, 2 sequential bytes in memory.
When you have a 8 bit bus, you are simply wasting time wanking about with 16 bit shorts bit shifting and oring to simply read the data from the ADC.

Do as John says and use a union and the ADC read opration will take place very efficiently as per the sample code.
Yes it is micro specific, but so is the architecture of the PIC's ADC.

RayJones:
a variation I am fond of also uses a union


--- Code: ---union ADCshort {
  unsigned short word;
  struct bytes {
     unsigned char lsb;
     unsigned char msb;
  }
}

union ADCshort ADCval;
short testo;

ADCval.bytes.msb = ADRESH;    // read and store ADC's msb
ADCval.bytes.lsb = ADRESL;    // read and store ADC's lsb

testo = ADCval.word;          // utilise 16bit result


--- End code ---

The proof is looking at the assembler listing that the compiler generates.
You will see that the structure de-referencing boils down to simple reads from one address to another address.
All the tom foolery of calculating the addresses is pre-determined by the compiler.

(It would be good if fixed font size appeared in the forum's editor when punching in "code" blocks - hence the edits. :-/)

Mechatrommer:
i concur. if you know how data is represented in memory location, there should be not much trouble. union is a great tool for bit/byte arrangement.

ziq8tsi:

--- Quote from: RayJones on June 03, 2011, 10:24:11 pm ---You must remember at the end, a 16 bit value is exactly as johnmx has shown, 2 sequential bytes in memory.

--- End quote ---

But you do need to know what order they are stored.  There is no compelling reason to prefer one endianness or another on the pic14 architecture, so it is really up to the compiler to choose.


--- Quote ---When you have a 8 bit bus, you are simply wasting time wanking about with 16 bit shorts bit shifting and oring to simply read the data from the ADC.

--- End quote ---

When you have an 8bit ALU, there are no instructions that can be used to shift a 16bit value by more than one bit at a time.  So you can pretty much guarantee that even a poorly optimizing compiler will have to eliminate the shift.  Not to mention that it is a common idiom.


--- Quote from: RayJones on June 03, 2011, 10:29:39 pm ---The proof is looking at the assembler listing that the compiler generates.

--- End quote ---

Okay.  First we need to insert your two missing semicolons and complete the declaration of the member "bytes" so that the code will compile.

Hi-tech C lite produces twelve instructions for your code (plus six for the extra assignment) compared to fifteen for the shift and or.

Navigation

[0] Message Index

[#] Next page

[*] Previous page

There was an error while thanking
Thanking...
Go to full version