Because of the holidays, TI E2E™ design support forum responses will be delayed from Dec. 25 through Jan. 2. Thank you for your patience.

This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

converting ADC hexadecimal value to decimal equivalent to analog input

Other Parts Discussed in Thread: CC430F5137

Hello,

I am acquiring the analog voltage value using one of the ADC12 channel on the CC430F5137.The converted ADC value is shown in ADC12MEMx as hexadecimal value.But how to convert this hexadecimal value in to decimal value as same as analog input.

For example,If analog input value is 0.7 then how to convert the hexadecimal value of ADC12MEMx to the same value as 0.7

thanks.

  • stefan 12 said:
    ADC value is shown in ADC12MEMx as hexadecimal value

    No it's not. Read 5-series "User's guide", Table 28-7. ADC12MEMx Register Description. It says:

    Binary unsigned format: This data format is used if ADC12DF = 0. The 12-bit
    conversion results are right justified. Bit 11 is the MSB. Bits 15–12 are 0 in 12-
    bit mode, bits 15–10 are 0 in 10-bit mode, and bits 15–8 are 0 in 8-bit mode.
    Writing to the conversion memory registers corrupts the results.
    2s-complement format: This data format is used if ADC12DF = 1. The 12-bit
    conversion results are left justified, 2s-complement format. Bit 15 is the MSB.
    Bits 3–0 are 0 in 12-bit mode, bits 5–0 are 0 in 10-bit mode, and bits 7–0 are 0
    in 8-bit mode. The data is stored in the right-justified format and is converted to
    the left-justified 2s-complement format during read back.

    So to convert unsigned or signed integer you can use C standard int to string conversion functions. If you don't know any, you shall read some C programmer's manual/book.

  • Yes, you are right.I understood it.And I got some related conversions in two ways as

    1.Displaying  through UART by using sprintf as in this link 

    http://e2e.ti.com/support/microcontrollers/msp430/f/166/p/41263/144901.aspx#144901

    void UART_send(void)
    {
      int i;
      sprintf(str,"%04d\r\n",ADC_result);
      for(i=0;i<6;i++)
      {
        while (!(UCTXIFG));             // USCI_A0 TX buffer ready?
          UCA0TXBUF = str[i];                   // send char
        __delay_cycles(1000);
      }
    }

    But here the 12bit ADC resolution taken into account so giving out ADCresult 12bit result as mentioned in above post.But can someone explain why the length as 6 and how this really works.

    2.Binary to BCD in this post 

    http://e2e.ti.com/support/microcontrollers/msp430/f/166/p/51983/189716.aspx#189716

    uint32_t UIntToBCD (uint16_t UIntValue)
    {
      uint32_t converted;
      uint8_t i;
      converted = 0;
      for (i = 0; i < 16; ++i) {
        converted = __bcd_add_long (converted , converted );
        if (( UIntValue & BITF) != 0) {
          converted = __bcd_add_long (converted , 1);
        }
        UIntValue <<= 1;
      }
      return converted;
    }

    And in this the resolution is default so 8-bit giving out only 8bit result.Why the length 16.How this gonna work?

    Can someone explain this difference between the two and which can be used for the decimal conversion.

    Thanks.


  • (1)12-bit unsigned binary number has a decimal value between 0 and 4095 (inclusive). The sprintf function was told to convert that to "%04d\r\n" which means 4 decimal digits with leading zeros followed by a <carriage-return> and a <new-line>. 4+1+1=6 characters.

    (2) I did not see any fault or default. That routine converts an unsigned 16-bit integer and returns a 32-bit binary-coded-decimal. The 32-bit BCD type is capable of expressing up to 8 digits. But unsigned 16-bit integer can only be between 0 and 65535 (inclusive). And if it is only 12-bit, the range is 0 to 4095 (inclusive).

    You are very resourceful in finding example code in c. What you need is somewhat more understanding of the c-language.

  • Hello,

    I used the example of UART with slight modifications like to print the ADConversion result on the hyperterminal

    #include <msp430.h>
    #include<string.h>
    #include<stdio.h>
    char str[10];
    int result=0;
    void UART_init(void)
    {
    PMAPPWD = 0x02D52;                        // Get write-access to port mapping regs
    P1MAP5 = PM_UCA0RXD;                      // Map UCA0RXD output to P1.5
    P1MAP6 = PM_UCA0TXD;                      // Map UCA0TXD output to P1.6
    PMAPPWD = 0;                              // Lock port mapping registers
    
    P1DIR |= BIT6;                            // Set P1.6 as TX output
    P1SEL |= BIT5 + BIT6;                     // Select P1.5 & P1.6 to UART function
    
    UCA0CTL1 |= UCSWRST;                      // **Put state machine in reset**
    UCA0CTL1 |= UCSSEL_1;                     // CLK = ACLK
    UCA0BR0 = 0x03;                           // 32kHz/9600=3.41 (see User's Guide)
    UCA0BR1 = 0x00;                           //
    UCA0MCTL = UCBRS_3+UCBRF_0;               // Modulation UCBRSx=3, UCBRFx=0
    UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
    UCA0IE |= UCRXIE;
    }
    void UART_send(void)
    {
      int i;
      sprintf(str,"%04d\r\n",result);
      for(i=0;i<6;i++)
      {
    	  while (!(UCA0IFG&UCTXIFG));               // USCI_A0 TX buffer ready?
          UCA0TXBUF = str[i];                   // send char
        __delay_cycles(1000);
      }
    }
    
    int main(void)
    {
      WDTCTL = WDTPW+WDTHOLD;                   // Stop watchdog timer
      UART_init();
           
      ADC settings 
    
      while (1)
      {
        ADC12CTL0 |= ADC12SC;                   // Start conversion
        result=ADC12MEM0;
        UART_send();
        while (!(ADC12IFG & BIT0));
        __no_operation();                       //Placed a breakpoint here
      }
    }

    Output on Hyperterminal: 4d

                                             4d

                                             4d

    But it is not displaying the result on the terminal.

    Can someone help me with this.

    thanks.

     

  • stefan 12 said:
    Output on Hyperterminal: 4d

    Maybe your printf/sprintf functions does not fully support all the fancy format extensions. Try simple "%d" format sting, check results.

  • IImars,

    When tried like this sprintf(str,"%d\r\n",result); it showing only d on termianl window.

     

  • stefan 12 said:
    When tried like this sprintf(str,"%d\r\n",result); it showing only d on termianl window.

    since sprintf requires lots of code, there are different implementations available, from a simple copy of the format string (e.g. for simple debug output when no more value outputs are required) to full support of floating point and exponential formats (huge pack of code). Maybe your project settings are on the lowest setting, so (s)printf is rather dumb and doe snot support number conversion.

  • Thanks Jens,

    Btu how to calculate the baudrate needed to transmit 500 ADC values where each(single)ADC value  is transmitted as below so that the total 500 values can be sent in <2ms

     ADC_value(k)=ADC_result[0 to 500];
    for (i=0;i<3;i++)
    {
     uart_send(ADC_value(i))
    }

    In example it is like this

      UCA0BR0 = 0x03;   // 32kHz/9600=3.41

    What are the things taken into account to calculate this so that uart can send 500 sample and what changes to be made to send 1000 samples in <2ms.

    thanks.

     

  • I have never used CCS.

    Is springf(...); part of the standard io library? Or, may be there is a sub-standard io library?

    Just for kicks, I tried with the Kick-start, and it seems to produce my expected result. The code size only increased by 5.5 KB by adding that line of c code.  Well within the 8 KB limit of Kick-start.

    For the propose of converting a 12-bit unsigned binary to an ASCII string. It seems this should be sufficient.

      for (int i = 3; i >= 0; i--)
      {
        str[i] = u12 % 10 + 0x30; //changed u to u12
        u12 = u12 / 10;
      }
      str[4] = 0x0D;
      str[5] = 0x0A;
      str[6] = 0x00;

  • Hi stefan,

    you can try this .....few lines of code.......

    int BintoDec(unsigned int val)
    {
    b= (val/1000);
    c=(val/100)%10;
    d=(val/10)%10;
    e=(val%10);
    WriteDataToLCD(b+48);
    WriteDataToLCD(c+48);
    WriteDataToLCD(d+48);
    WriteDataToLCD(e+48);
    }

    and u can use this formulae for getting analog value

    Nadc=( (Vin - Vrl)/(Vrh - Vrl) )*2^(bits of ADC)

  • I doubt you can send 1000 samples in under 2ms. I hope I got the numbers right.

    9600 bits per second
    9 bits per character (start+7 data+stop=9)
    1066.6 characters per second
    0.9375 ms per character
    6 ASCII characters per sample (4 ASCII character+CR+LF)
    5.625 ms per sample

    The User Guide (slau259e.pdf) has register settings for 460800 bps:

    460800 bits per second
    9 bits per character (start+7 data+stop=9)
    51200 characters per second
    0.01953125 ms per character
    6 ASCII characters per sample (4 ASCII character+CR+LF)
    0.1171875 ms per sample
    17.06 samples per 2 ms

    All this assumes that ADC acquistion and binary to ASCII conversion are done prior to tranmission and the data can be sent without any overhead between samples.

    If you use 2 binary bytes instead of 6 ASCII bytes that would be 3 times more efficient.

    460800 bits per second
    10 bits per character (start+8 data+stop=10)
    46080 characters per second
    0.02170139 ms per character
    2 character per sample
    0.0434028 ms per sample
    46.08 samples per 2 ms


  • Hello,

     I cannot find any Standard baud-rate data for UCA but on page 594 of user guide the baudrate for UCB is available.

    Could someone help me in finding the baudrate for UCA.

    thnks

     

  • stefan 12 said:
    I cannot find any Standard baud-rate data for UCA

    ???

    There is no 'standard baudrate'. You have a clock source and a baudrate divider. And clock source divided by the divider is the resulting baudrate.
    Basically, you have a clock of a known frequency (e.g. SMCLK) and want a baudrate so clock/baudrate gives you the divider to use.

    The mechanism is the same for USCIA and USCIB. But since USCIB does not provide an UART module (only I2C and SPI, which are both synchronous), USCIB has no modulation register.

    stefan 12 said:
    page 594 of user guide the baudrate for UCB is available.

    Which users guide? On mine, the 2x users guide slau144j has DAC12 interrupts on page 594, while the 5x users guide slau208m introduces the RTC_B. The FR57xx users guide has only 498 pages at all. None of all users guides I have has any table on page 594.

    However, there is no baudrate table for the USCIB, because it is so very very very simple to calculate with a calculator or worst case with your fingers. So I rather guess you are talking about the UCBR column in the tables for the USCI_A UART baudrate. The 'BR' stands for 'BaudRate' and UCBR is the baudrate divider register in both USCIA and USCIB.

  • Hello Jens,

    Here is the user guide that I was representing

    3652.slau259e.pdf

    Ok, then the tabular column represents the same UCBR value for both USCIA and USCIB you mean.Now I got it.

    thanks.

  • stefan 12 said:
    Ok, then the tabular column represents the same UCBR value for both USCIA and USCIB you mean.

    Those standard baudrates are only meaningful for RS232 communication. For plain UART, any baudrate up to the maximum is okay, like 500kBd or 1MBd. As soon as both sides support it. And for synchronous operation, where the master delivers the clock together with the data, an exact baudrate is totally unimportant, as long as it does not exceed the slave maximum. Since USCIB only has synchronous operating modes, this table is rather useless for USCIB. Simple division is enough. Therefore you won't find this table in the SPI and I2C chapters of the users guide, only in the (USCIA only) UART chapter.

    The table is only there because for RS232-compatible baudrates, you will need a modulation value to come close to these baudrates when the clock is not an exact multiple of the baudrate. (on ATMega, the CPU is often run form a 14,7456MHz crystal, as this is 115200*128. The ATMega does not support modulation.

**Attention** This is a public forum