-1
\$\begingroup\$

We have a function:

unsigned int ADC_Read(unsigned char channel) {
    if (channel > 7) //If Invalid channel selected
        return 0; //Return 0
    Delay_ms(2);
    ADCON0.GO_DONE=1;
    while (ADCON0.GO_DONE); //Wait for A/D Conversion to complete
    {
        return ((ADRESH << 8) | ADRESL); //Returns Result
    }
}

It returns the binary value from ADRESH register as an Integer. But we need it as a character, since our Soft_UART_Write() function only accepts characters as parameters, and we need to print the values to the UART. So how can we make this function return characters? For example, if we get input as 01000010, it should return 'B' Refer here. I also tried functions like itoa(), but I get:

There is not enough ROM space adcuart.c

Since I'm using UART Library, there seems to be no space. So I'm looking for a direct or more efficient way to convert it.

\$\endgroup\$
  • 1
    \$\begingroup\$ A char is 8bits. Ascii characters are 8 bits. The adc output is more than 8bits. There will be adc values that don't have a mapping to a character. If you can only use the most significant 8 bits of your adc then you can convert them to a char easily with a cast. \$\endgroup\$ – efox29 Feb 13 at 5:01
  • \$\begingroup\$ @efox29 Thanks for your info, I read values only between 0 and 1023. Do you mean return (char)((ADRESH << 8) | ADRESL)? \$\endgroup\$ – Reejesh PK Feb 13 at 5:05
  • 1
    \$\begingroup\$ No. Do you know how many bits your adc is? How many bits would be returned from that function? How many bits is a char? Do you see where I am going with this line of questioning? \$\endgroup\$ – efox29 Feb 13 at 5:08
  • \$\begingroup\$ @efox29 yes, my ADC is a 10 bit one. So it doesn't fit into the character range? \$\endgroup\$ – Reejesh PK Feb 13 at 5:19
  • 2
    \$\begingroup\$ yup thats right. So you have to either have to have some type of mapping where 2 characters = 10bit adc value or you only use 8bits of your 10 bit ADC and then character = 8bit adc value. \$\endgroup\$ – efox29 Feb 13 at 5:24
0
\$\begingroup\$

The itoa() function can be used but since it's not a part of neither native C nor C++, it may not be defined in your compiler. Anyway, here's how it's used:

#include <stdlib.h>
char aADCValue[10];
unsigned int uiADCValue;
...
uiADCValue = ADC_Read (numChannel);
itoa (uiADValue, aADCValue, 10); //converts the number uiADValue in decimal-base.

If itoa() is not defined in your compiler then you need to convert each digit to ASCII char:

char* myitoa(int num, char* str)
{
    int i = 0;
    char t;

    // Handle 0 explicitely, otherwise empty string is printed for 0
    if (num == 0)
    {
        str[i++] = '0';
        str[i] = '\0';
        return str;
    }

    // Process individual digits
    while (num != 0)
    {
        int rem = num % 10;
        str[i++] = (rem > 9)? (rem-10) + 'a' : rem + '0';
        num = num/10;
    }

    str[i] = '\0'; // Append string terminator

    return str;
}

Another solution can be sprintf() function:

#include <stdio.h>
char aADCValue[10];
....
uiADCValue = ADC_Read (numChannel);
sprintf (aADCValue, "%s", uiADCValue);
\$\endgroup\$
  • 1
    \$\begingroup\$ would snprintf work? \$\endgroup\$ – Hearth Feb 13 at 5:00
  • \$\begingroup\$ Yea, I tried itoa, but i get the errro: There is not enough ROM space adcuart.c, since im using the UART Libarary also, so I'm trying to return it as a character itself so that i need not convert. \$\endgroup\$ – Reejesh PK Feb 13 at 5:00
  • \$\begingroup\$ @Hearth yes, sprintf() or snprintf() can be a solution. Editing my answer. Thanks. \$\endgroup\$ – Rohat Kılıç Feb 13 at 5:07
  • \$\begingroup\$ @Hearth can sprintf() return the character value? \$\endgroup\$ – Reejesh PK Feb 13 at 5:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.