This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Timer problem

If i'm using that the decimal value which to store into the timer for example: in Assembly code we are writing as
TIMER_0 EQU -1027

but in the C, how can we actually extract this -1027 to TL0 = -3 and TH0 = -5?

thanx

Parents
  • I tend to think of timer values as unsigned. For that matter, almost all values I use in embedded programming are unsigned.

    TL0 is the least significant byte of a 16-bit value. TH0 is the most significant byte. So, the question is really just how to get these values. This can be as simple as:

    U16 timerVal = (U16)-1027;
    
    TL0 = timerVal;
    TH0 = timerVal >> 8;
    

    Thanks to the way assignment is defined between integers of different sizes, the assignment to TL0 will copy the low byte from timerVal. To get the high-order byte for TH0, we shift 8 bits to the right (or divide by 256).

    Another way to do this that avoids the shift is to use a union.

    typedef struct
        {
        U8 msb; // Keil C stores ints big-endian
        U8 lsb;
        } U16AsBytes;
    
    typedef union
        {
        U16 u16;
        U16AsBytes asBytes;
        U8 array[2];
        } ByteAccess16;
    
    ByteAccess16 timerVal;
    
    timerVal.u16 = -1027;
    
    TL0 = timerVal.asBytes.lsb;
    TH0 = timerVal.asBytes.msb;
    
    TL0 = timerVal.array[1];
    TH0 = timerVal.array[0];
    

    The code for the union access is pretty efficient, even though the source is a little more cluttered.

    The compiler is not as smart as I might wish about strength-reducing shifts that are multiples of 8.

Reply
  • I tend to think of timer values as unsigned. For that matter, almost all values I use in embedded programming are unsigned.

    TL0 is the least significant byte of a 16-bit value. TH0 is the most significant byte. So, the question is really just how to get these values. This can be as simple as:

    U16 timerVal = (U16)-1027;
    
    TL0 = timerVal;
    TH0 = timerVal >> 8;
    

    Thanks to the way assignment is defined between integers of different sizes, the assignment to TL0 will copy the low byte from timerVal. To get the high-order byte for TH0, we shift 8 bits to the right (or divide by 256).

    Another way to do this that avoids the shift is to use a union.

    typedef struct
        {
        U8 msb; // Keil C stores ints big-endian
        U8 lsb;
        } U16AsBytes;
    
    typedef union
        {
        U16 u16;
        U16AsBytes asBytes;
        U8 array[2];
        } ByteAccess16;
    
    ByteAccess16 timerVal;
    
    timerVal.u16 = -1027;
    
    TL0 = timerVal.asBytes.lsb;
    TH0 = timerVal.asBytes.msb;
    
    TL0 = timerVal.array[1];
    TH0 = timerVal.array[0];
    

    The code for the union access is pretty efficient, even though the source is a little more cluttered.

    The compiler is not as smart as I might wish about strength-reducing shifts that are multiples of 8.

Children