Pages

Wednesday, July 28, 2010

how to transfer 2 byte data

Sometimes you want to send 2 byte data or more. But we all know that many transfer medium like serial, I2C, CAN bus, bluetooth, etc; only allows use 1 byte data transfer only. So how to send integer value into byte medium? One way is converting into a sequence of character. Another way is splitting the data per bytes. For example, sending integer16 into byteHi and byteLo. It may easy if using assembly languages.
This time I'll show you how to send integer data from microcontroller to PC. I'm using C language in the microcontroller, and C# in the PC.
The key of these processes are 16 bit to 8 bit converter.

On the PC, using C#
memory mapping
//using System.Runtime.InteropServices
struct unionStruct {
   [FieldOffset(0)]
   public short bigVal;
   [FieldOffset(0)]
   public byte smallLow;
   [FieldOffset(1)]
   public byte smallHi;
}

Basically, we create struct. But somehow, we make one field is overlapped in the memory. This is the splitting work. As shown on the picture, bigVal is overlapped with the memory of smallLow and smallHi. In the other words, when we put a value in the smallLow, we can access it from smallLow or from bigVal. When we put 0x12 in the smallLow, it's same like we put 0x0012 in the bigVal. When we put 0x34 in the smallHi, then, in the bigVal will be read 0x3400. So if we put 0x1234 in the bigVal, then we can read the low byte in the smallLow which has the value of 0x34. And also we can read the high byte in the smallHi which has the value of 0x12. It has the same principles on C language.

On the microcontroller, using C
typedef struct {
memory mapping
   unsigned char lo;
   unsigned char hi;
}hilo_t;

typedef union {
   unsigned int besar;
   hilo_t  kecil;
}hilo_ut;

In the C language, we can't control the field offset. So we can create a structure that has 2 byte field. And then we put the structure in the union to make it overlapped with 2 byte memory.

How it works?
To send data, make sure the sequence is same for the microcntroller and the PC.This to avoid misunderstanding between PC and microcontroller of how to put the high byte and the low byte.
  1. Splitting 16-bit data to send to PC.
    hilo_ut byteInterface; //declaration
    byteInterface.besar = data16;   //put 16-bit data
    send(byteInterface.kecil.lo);      //send low byte first
    send(byteInterface.kecil.hi);      //send high byte
  2. Assembly two 8-bit data into 16-bit data in the PC
    unionStruct byteInterface = new byteInterface();  //declaration
    byteInterface.smallLow = read();   //read low byte first because microcontroller sends low byte first
    byteInterface.smallHi = read();      //read high byte
    short needee = byteInterface.bigVal; //read the 16-bit data
  3. Splitting 16-bit data to send to microcontroller.
    unionStruct byteInterface = new byteInterface();  //declaration
    byteInterface.bigVal = dataBig;   //put the 16-bit value
    send(byteInterface.smallLow);      //send low byte
    send(byteInterface.smallHi);      //send high byte
  4. Assembly two 8-bit data into 16-bit data from the PC
    hilo_ut byteInterface; //declaration
    byteInterface.kecil.lo = read();   //read low byte first
    byteInterface.kecil.hi = read();      //read high byte
    unsigned int nedee = byteInterface.besar;
That is how the easy way.

No comments: