MSP430 inconsistent conversion from int to hex string

74 Views Asked by At

I'm having trouble converting some sensor readings to a hex string on my MSP430G2231. I'm using this library: https://github.com/jwr/msp430_usi_i2c To read temperature data from a couple TI TMP117-sensors. The reading performs just fine and I've even done traces of the i2c data through a ligic analyzer and it looks all fine. I'm printing my results throught UART with this code:

//------------------------------------------------------------------------------
// Function configures Timer_A for full-duplex UART operation
//------------------------------------------------------------------------------
void TimerA_UART_init(void)
{
    TACCTL0 = OUT;                          // Set TXD Idle as Mark = '1'
    TACCTL1 = SCS + CM1 + CAP + CCIE;       // Sync, Neg Edge, Capture, Int
    TACTL = TASSEL_2 + MC_2;                // SMCLK, start in continuous mode
}
//------------------------------------------------------------------------------
// Function halts Timer_A
//------------------------------------------------------------------------------
void TimerA_UART_halt(void)
{
    TACTL &= ~(MC_2);                       // SMCLK, stop
}
//------------------------------------------------------------------------------
// Outputs one byte using the Timer_A UART
//------------------------------------------------------------------------------
void TimerA_UART_tx(unsigned char byte)
{
    while (TACCTL0 & CCIE);                 // Ensure last char got TX'd
    TACCR0 = TAR;                           // Current state of TA counter
    TACCR0 += UART_TBIT;                    // One bit time till first bit
    TACCTL0 = OUTMOD0 + CCIE;               // Set TXD on EQU0, Int
    txData = byte;                          // Load global variable
    txData |= 0x100;                        // Add mark stop bit to TXData
    txData <<= 1;                           // Add space start bit
}

//------------------------------------------------------------------------------
// Prints a string over using the Timer_A UART
//------------------------------------------------------------------------------

void TimerA_UART_print(char *string)
{
    while (*string) {
        TimerA_UART_tx(*string++);
    }
}

#pragma vector = WDT_VECTOR
__interrupt void watchdog_timer (void)
{
  __bic_SR_register_on_exit(LPM3_bits);     // Clear LPM3 bits from 0(SR)
}

#pragma vector = TIMERA0_VECTOR
__interrupt void Timer_A0_ISR(void)
{
    static unsigned char txBitCnt = 10;

    TACCR0 += UART_TBIT;                    // Add Offset to CCRx
    if (txBitCnt == 0) {                    // All bits TXed?
        TACCTL0 &= ~CCIE;                   // All bits TXed, disable interrupt
        txBitCnt = 10;                      // Re-load bit counter
    }
    else {
        if (txData & 0x01) {
          TACCTL0 &= ~OUTMOD2;              // TX Mark '1'
        }
        else {
          TACCTL0 |= OUTMOD2;               // TX Space '0'
        }
        txData >>= 1;
        txBitCnt--;
    }
}

And the code for turning my uint16_t temperature readings to a hex string is done with this code:

static char *itohexa_helper(char *dest, unsigned x) {
  if (x >= 16) {
    dest = itohexa_helper(dest, x/16);
  }
  *dest++ = "0123456789abcdef"[x & 15];
  return dest;
}

char *itohexa(char *dest, unsigned x) {
  *itohexa_helper(dest, x) = '\0';
  return dest;
}

Credit to https://stackoverflow.com/a/44549691/10035529 for this function.

And my code that iterates actually does the reading and prints out the temperature through uart looks like this:

for(i=0;i<SENSORS;i++)
{
    uint8_t b[2];
    pld[0] = tmp[i];
    pld[3] = tmp[i] + 1;
    i2c_send_sequence(pld, 6, b, LPM3_bits);
    while(!i2c_done());
    uint16_t n = (b[0] << 8) | b[1];
    TimerA_UART_print(itohexa(status,n));
}

Here status is defined as char status[4]. The UART_init(); and UART_halt(); functions are called elsewhere outside the loop above. What I'm getting on my UART-line for each sensor is exactly what I'd expect: enter image description here With the last two full bytes in the trace being the temperature (0x0B and 0x4C), and printing these as-is yields the correct message, and my serial monitor recognizes these as both 0x0B and 0x4C as hex (not ASCII).

However, when converting these to a hex-string with the code above, my serial monitor only receives this for the same reading (0x0B and 0x4C): b4ì as ASCII and 0x62, 0x36, 0xEC as raw hex. The output I'm expecting from serial would be "0B4C" as ASCII. And for the whole loop above, which reads through a total of 4 sensors, I'm expecting an output of "0B4C0B600B5C0B55" as ASCII, corresponding to these uint16_t readings: 0x0B4C,0x0B60,0x0B5C,0x0B55.

However, I'm getting this: b4ìb6˜b5ìb55 in ASCII

and: 0x62, 0x34, 0xEC, 0x62, 0x36, 0x98, 0x62, 0x35, 0xEC, 0x62, 0x35, 0x35 in raw hex

0

There are 0 best solutions below