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

Nibble to word

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
kmp84



Joined: 02 Feb 2010
Posts: 354

View user's profile Send private message

Nibble to word
PostPosted: Sat Nov 23, 2019 3:17 am     Reply with quote

Hello,
Any faster and simple method to make word from nibbles?
Code:

  byte3 <<= 4;
  byte2 &=0xF;
  byte3 |= byte2;
  byte1 <<= 4;
  byte0 &=0xF;
  byte1 |= byte0;

  word = make16(byte3, byte1);


Best Regards!
temtronic



Joined: 01 Jul 2010
Posts: 9243
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat Nov 23, 2019 7:22 am     Reply with quote

Use of 'structure' would allow direct access to the 4 nibbles within the 16bit word.

Just be sure the order is correct by testing known values !

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19540

View user's profile Send private message

PostPosted: Sat Nov 23, 2019 12:50 pm     Reply with quote

Combining a union with a bitfield structure is the easiest way to get a
word:
Code:

struct nibble {
    int8 one:4; //4bit bitfield
    int8 two:4;
}

union {
    struct nibble nib[2];
    int16 word;
} combiner;
//you can then access the nibbles as
combiner.nib[n].one //etc..

//The word is then combiner.word;


Also, look at the machine instruction 'swap'. CCS makes this available
as a C instruction, and it would get rid of all the 4bit rotations:
Code:

 swap(byte3);
 byte3=(byte3 & 0xF0) | (byte2 & 0xF);


Will give you 'byte3 containing what was byte2 in the top nibble and byte2
in the bottom nibble. If you can be sure that the values arriving will never
exceed 0xF, then the '& instructions are not needed.
kmp84



Joined: 02 Feb 2010
Posts: 354

View user's profile Send private message

PostPosted: Sat Nov 23, 2019 1:46 pm     Reply with quote

Hi Mr. Ttelmah and Mr. Temtronic,

In my case I have four bytes in array, for example:
0x3A, 0x3B, 0x3C, 0x3D and have to be converted to word 0xABCD.

Thanks and Best Regards!
Ttelmah



Joined: 11 Mar 2010
Posts: 19540

View user's profile Send private message

PostPosted: Sat Nov 23, 2019 2:27 pm     Reply with quote

The union is for a 16bit result. You have:
combiner.nib[0].one
combiner.nib[0].two
combiner.nib[1].one
combiner.nib[1].two

Write your bytes into these, and combiner.word is the 16bit result.
On using swap I was showing just one byte, but you already know
how to combine two bytes to make a word.
kmp84



Joined: 02 Feb 2010
Posts: 354

View user's profile Send private message

PostPosted: Sun Nov 24, 2019 2:53 am     Reply with quote

Hello,

Thanks for help!

Any idea why when I'm in debug mode I can't see all data: https://ibb.co/h9tVSmT

Compiler ver. 5.076.
ICD U64.

Best Regards!
temtronic



Joined: 01 Jul 2010
Posts: 9243
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Nov 24, 2019 7:00 am     Reply with quote

Please post your test code, somethings 'funny' for sure.
There may be a 'cleaner' way to do what you want.
Ttelmah



Joined: 11 Mar 2010
Posts: 19540

View user's profile Send private message

PostPosted: Sun Nov 24, 2019 7:42 am     Reply with quote

Consider not storing your nibbles separately.
Instead store them directly into 4bit variables:
Code:

#include <18F45K80.h>
#device ADC=12

#FUSES NOWDT
#use delay(crystal=20000000)
#use RS232(UART1, ERRORS, BAUD=9600) //setup basic comm port

union {
   struct {
      int8 byte0:4;
      int8 byte1:4;
      int8 byte2:4;
      int8 byte3:4;
   } parts;
   unsigned int16 word;
} combiner;

void main()
{
   //Write the four nibble variables as a demo
   combiner.parts.byte0=4;
   combiner.parts.byte1=3;
   combiner.parts.byte2=2;
   combiner.parts.byte3=1;
   
   //Print the 16bit value
   printf("%LD\n", combiner.word);
   
   while(TRUE)
   {
      delay_cycles(1);
   }
}


You have four values called combiner.parts.bytex, each of which can
hold a four bit value. You can use these just like any normal variable
reading or writing them at will. Then when you want to access the
combined 16bit value, just use combiner.word. Use the 'parts', where
you currently use bytex.
kmp84



Joined: 02 Feb 2010
Posts: 354

View user's profile Send private message

PostPosted: Sun Nov 24, 2019 12:38 pm     Reply with quote

Hi,

This is test code which has a problem in debug mode:
Code:

#include <16F1459.h>
//#device *=16
#fuses INTRC_IO,NOPROTECT,MCLR,PUT,WDT
#use delay(clock=4M)
#use rs232(DEBUGGER, stream=MONITOR, rcv=PIN_B6, xmit=PIN_B6)


/* Ttelmah's example*/
union {
   struct {
      int8 byte0:4;
      int8 byte1:4;
      int8 byte2:4;
      int8 byte3:4;
   } parts;
   unsigned int16 word;
} combiner;

#zero_ram
void main (){

   delay_ms(100);
   
   fprintf(MONITOR, "\n\rTarget 16F1459 StartUp!");
   
   combiner.parts.byte0=1;
   combiner.parts.byte1=2;
   combiner.parts.byte2=3;
   combiner.parts.byte3=4;
   
   fprintf(MONITOR, "\n\r a : 0x%LX", combiner.word);
   
   for(;;){

   }
}


and it's debug screen: https://ibb.co/RjPBpxv
temtronic



Joined: 01 Jul 2010
Posts: 9243
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Nov 24, 2019 2:15 pm     Reply with quote

Maybe it's just me but I'd like you to refer to 4 bit wide variables as nibbles or nibs instead of bytes...
4nibs instead of parts.... it just 'reads' better to me...
Old guys like me think bytes are 8 bits wide, nibbles are 4, words are 16....

have to ask though, does the ..
fprintf(MONITOR, "\n\r a : 0x%LX", combiner.word);

actually send the correct 0x1234 data to a PC terminal program ?

Jay
kmp84



Joined: 02 Feb 2010
Posts: 354

View user's profile Send private message

PostPosted: Sun Nov 24, 2019 2:41 pm     Reply with quote

temtronic wrote:


have to ask though, does the ..
fprintf(MONITOR, "\n\r a : 0x%LX", combiner.word);

actually send the correct 0x1234 data to a PC terminal program ?


Yes, Mr.temtronic. The printed word value is correct!
Debuggers and debugging is not the best part of the CCS Compiler! Smile

We may have diverted a bit from the main topic..Smile
temtronic



Joined: 01 Jul 2010
Posts: 9243
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Nov 24, 2019 3:01 pm     Reply with quote

well.. you've confirmed Mr. T's code is correct and the PIC is sending data to the PC !! It'd the debugger that appers to be faulty.

I never use the ICD or debugger, prefer to test in the 'Real World'.

Jay
kmp84



Joined: 02 Feb 2010
Posts: 354

View user's profile Send private message

PostPosted: Sun Nov 24, 2019 3:28 pm     Reply with quote

temtronic wrote:

I never use the ICD or debugger, prefer to test in the 'Real World'.

Jay


I think so, but when developing new code debugging save more time IF work correct!

Ttelmah



Joined: 11 Mar 2010
Posts: 19540

View user's profile Send private message

PostPosted: Sun Nov 24, 2019 11:20 pm     Reply with quote

Obviously the issue here is that the debugger can't understand offset
bitfields. Not really surprising. Honestly probably better to just display
the combined result. If you think about it expecting the debugger to be
able to display a variable that could be anywhere in the actual byte
and could be any size, is asking rather too much....
Ttelmah



Joined: 11 Mar 2010
Posts: 19540

View user's profile Send private message

PostPosted: Mon Nov 25, 2019 1:01 am     Reply with quote

temtronic wrote:
Maybe it's just me but I'd like you to refer to 4 bit wide variables as nibbles or nibs instead of bytes...
4nibs instead of parts.... it just 'reads' better to me...
Old guys like me think bytes are 8 bits wide, nibbles are 4, words are 16....

have to ask though, does the ..
fprintf(MONITOR, "\n\r a : 0x%LX", combiner.word);

actually send the correct 0x1234 data to a PC terminal program ?

Jay


Agree wholeheartedly. I only called them 'bytex', to match his existing
variables.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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