Forum Menu




 


Log in Problems?
New User? Sign Up!
AVR Freaks Forum Index

Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Author Message
Shadow Warrior
PostPosted: Aug 17, 2005 - 02:43 AM
Rookie


Joined: Oct 01, 2004
Posts: 35
Location: Belgrade

hi,
i need to convert some integer value into char, and then print it on a LCD, and i need to convert some ASCII commands from UART to integers, but don't want to include stdio.h because its too bulky.
does anyone know are there any included functions which i could use for this???
thanx
 
 View user's profile Send private message  
Reply with quote Back to top
dl8dtl
PostPosted: Aug 17, 2005 - 06:04 AM
Raving lunatic


Joined: Dec 20, 2002
Posts: 7374
Location: Dresden, Germany

Why don't you do what you're suggesting in the subject, and use itoa() then?

_________________
Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.
Please read the `General information...' article before.
 
 View user's profile Send private message Send e-mail Visit poster's website 
Reply with quote Back to top
clawson
PostPosted: Aug 17, 2005 - 10:39 AM
10k+ Postman


Joined: Jul 18, 2005
Posts: 71163
Location: (using avr-gcc in) Finchingfield, Essex, England

Just including stdio.h doesn't add anything to your code. But when you actually use one of the functions defined in it then at link time the conpiler/linker ONLY pulls in the bits of libc that are involved in supporting the function/s that you have used. The chances are that the itoa() in the C lib is going to be as efficiently codes as anything you can come up with. But to give you an idea of how an itoa() can be done I've sometimes used something along the lines of:

Code:
char* my_itoa(int value, char *string, int radix)
{
   if(!string)
   {
      return NULL;
   }

   if(0 != value)
   {
      char scratch[34];
      int neg;
      int offset;
      int c;
      unsigned int accum;

      offset =32;
      scratch[33] = '\0';

      if(radix == 10 && value < 0)
      {
         neg = 1;
         accum = -value;
      }
      else
      {
         neg = 0;
         accum = (unsigned int)value;
      }

      while(accum)
      {
         c = accum % radix;
         if(c < 10)
         {
            c += '0';
         }
         else
         {
            c += 'A' - 10;
         }
         scratch[offset] = c;
         accum /= radix;
         offset--;
      }
      
      if(neg)
      {
         scratch[offset] = '-';
      }
      else
      {
         offset++;
      }

      strcpy(string,&scratch[offset]);
   }
   else
   {
      string[0] = '0';
      string[1] = '\0';
   }

   return string;
}


which is used in the form:

Code:
char buff[40];
int x = 37215;

   my_itoa(x, buff, 10);


which converts 'x' to a string of characters in 'buff' using base 10.

However you'll note that this uses strcpy() from libc anyway, if you really want to avoid the library stuff being dragged in you'll need to implement your own version (*p++ = *q++ kind of thing)

Cliff
 
 View user's profile Send private message  
Reply with quote Back to top
Iguaner
PostPosted: Aug 17, 2005 - 08:09 PM
Wannabe


Joined: May 31, 2004
Posts: 70


Hi

maybe that these ym functions can help you. The first is for small number and the second for 32 bit number.

Code:

void LCD_PrintAsDec (u16 num) //for vlue from 0 to 999
//or void LCD_PrintAsDec (u08 num) //for vlue from 0 to 254
{
u08 temp1;
u08 temp2;
u08 temp3;

temp1 = 0x30 + (num %10);
num /= 10;

temp2 = 0x30 + (num %10);
num /= 10;

temp3 = 0x30 + (num %10);
num /= 10;

if (temp3 == 0x30) LCD_SendByte (0x20); 
else LCD_SendByte(temp3);

if (temp2 == 0x30 && temp3 == 0x30) LCD_SendByte (0x20);
else LCD_SendByte(temp2);

LCD_SendByte(temp1);
}


Code:

void USART_PrintAsDec(u32 num)
{
    //support max 0xffffffff (32 bit) in dec 4 294 967 295
    //print argument as decimal
    char string[14];//we work with max 4 294 967 295 its 10 num and 1 char for "end string"
    char *p;
    p = string;
   
    do //do becouse if we use only while it not vork for num =0
    {
    *p = 0x30 + (num %10);
    num /= 10;
   
    if ( (p-string)%4 == 2)  { p++; *p = 0x20;}
   
    p++;
    }while (num !=0);//do
   
    p--;                 //this is here for fix num like 132 or 123 456,
    if (*p != 0x20) p++; //becouse if its not here it write "123" like " 123" (with space)
                       
    while (p--  != string)
    {
    USART_SendByte (*p);
    }

}//printasdec


and here is function to read integrs from usart

Code:

u32 USART_GetsNumber (void)
{
u32 sec = 0;
u08 c;

while (1)
{
    c = USART_ReceiveByte();
    delayms (1);//for some terminal
   
    USART_SendByte(c);
   
    if (c == 0xD) //0xd = Enter
        {
        return sec;
        }
    else if (c == '\b') //'\b' = BackSpace
        {
        sec /= 0xA;
        USART_SendByte (0x20);
        USART_SendByte ('\b');
        }
    else if (sec)
        {
        c = c - 0x30;//its work becouse 0x30 is 0, 0x31 is 1 ... and 0x39 is 9
        sec *= 0xA; //* 10 in decimal
        sec += c;       
        }
    else
        {
        c -= 0x30;
        sec = c;
        } //if   
    }//while
} //GetsUSARTNUmber
 
 View user's profile Send private message Send e-mail Visit poster's website 
Reply with quote Back to top
jesper
PostPosted: Aug 17, 2005 - 08:39 PM
Raving lunatic


Joined: Mar 07, 2001
Posts: 2376
Location: Stockholm, Sweden

Here's a compact routine for printing a number in various bases. Not exactly what you need, but you can easily modify it.

Code:

//
// Print a number in the given base
//
void print_number (int base, int unsigned_p, long n)
{
    static char chars[16] = "0123456789abcdef";
    char *p, buf[32];
   
    if (!unsigned_p && n < 0) {
        UART_SendByte('-');
        n = -n;
    }
   
    p = buf + sizeof (buf);
    *--p = '\0';

    do {
        *--p = chars[n % base];
        n /= base;
    } while (n != 0);
   
    while (*p)
        UART_SendByte(*p++);
}

_________________
/Jesper
http://www.yampp.com
The quick black AVR jumped over the lazy PIC.
What boots up, must come down.
 
 View user's profile Send private message Send e-mail Visit poster's website 
Reply with quote Back to top
Iguaner
PostPosted: Aug 18, 2005 - 06:01 PM
Wannabe


Joined: May 31, 2004
Posts: 70


Hi

nice function Jesper. But why are base and unsigned_p defined as int and not char (or even bit)??
 
 View user's profile Send private message Send e-mail Visit poster's website 
Reply with quote Back to top
jesper
PostPosted: Aug 18, 2005 - 06:52 PM
Raving lunatic


Joined: Mar 07, 2001
Posts: 2376
Location: Stockholm, Sweden

For historical reasons. You can change it to uint8_t

_________________
/Jesper
http://www.yampp.com
The quick black AVR jumped over the lazy PIC.
What boots up, must come down.
 
 View user's profile Send private message Send e-mail Visit poster's website 
Reply with quote Back to top
smileymicros
PostPosted: Aug 18, 2005 - 08:18 PM
Raving lunatic


Joined: Nov 17, 2004
Posts: 6496
Location: Great Smokey Mountains.

Or you might do what K&R did:

Code:

//NOTE: stolen from K&R p. 64 itoa function
void itoa(int n, char s[])
{
   int i, sign;
   
   if ((sign = n) < 0) // record sign
      n = -n;         // make n positive
   i = 0;
   do {   // generate digits in reverse order
      s[i++] = n % 10 + '0'; // get next digit
   } while ((n /= 10) > 0); // delete it
   if (sign < 0)
      s[i++] = '-';
   s[i] = '\0'; // add null terminator for string
   reverse(s);
}


//NOTE: stolen from K&R p. 62 reverse function
// reverse: reverse a string s in place
void reverse(char s[])
{
   int c, i, j;
   
   for (i = 0, j = strLen(s)-1; i < j; i++, j--){
      c = s[i];
      s[i] = s[j];
      s[j] = c;
   }
}


Do it backwards then reverse the number. Those guys are way cleverer than me. (But who is surprised?)

Smiley

_________________
FREE TUTORIAL: 'Quick Start Guide for Using the WinAVR C Compiler with ATMEL's AVR Butterfly' AVAILABLE AT: http://www.smileymicros.com
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
pfleury
PostPosted: Aug 18, 2005 - 09:01 PM
Rookie


Joined: Oct 01, 2001
Posts: 38


Here a version which does not use divisions (only for base 10)

Code:

void itoa( int val, char *s )
{
  char *p;
  unsigned char d, i;
  unsigned char zero;
  unsigned int test;
  unsigned int uval = val;
 

  p = s;
 
  if( val < 0 ){
    uval = -val;
    *p++ = '-';
  }

  zero = 1;

  i = 4;
  do{
    i--;   
    if ( i==0) test = 10;
    else if ( i==1) test=100;
    else if ( i==2) test=1000;
    else test=10000;

    for( d = '0'; uval >= test; uval -= test )
    {
      d++;
      zero = 0;
    }
    if( zero == 0 )
      *p++ = d ;
  }while( i );

  *p++ = (unsigned char)uval + '0';
}
 
 View user's profile Send private message  
Reply with quote Back to top
Shadow Warrior
PostPosted: Aug 21, 2005 - 02:55 PM
Rookie


Joined: Oct 01, 2004
Posts: 35
Location: Belgrade

thanx guys you helped me alot!
 
 View user's profile Send private message  
Reply with quote Back to top
realiser
PostPosted: Jan 19, 2011 - 08:55 PM
Newbie


Joined: Jan 10, 2011
Posts: 1


And after 6 years, you helped me too!

Here's a modified version for unsigned long long used with an RFID reader.

Code:

void ulltostr(unsigned long long val, char *s )
{
  char *p;
  unsigned char d, i;
  unsigned char zero;
  unsigned long long test;
  unsigned long long uval = val;
 
  p = s;

  zero = 1;

  i = 12;
  do{
    i--;   
    if ( i==0)       test =10;
    else if ( i==1) test =100;
    else if ( i==2) test =1000;
    else if ( i==3) test =10000;
    else if ( i==4) test =100000;
    else if ( i==5) test =1000000;
    else if ( i==6) test =10000000;
    else if ( i==7) test =100000000;
    else if ( i==8) test =1000000000;
    else if ( i==9) test =10000000000;
    else if ( i==10) test=100000000000;
    else if ( i==11) test=1000000000000;
    else if ( i==12) test=10000000000000;
   
    for( d = '0'; uval >= test; uval -= test )
    {
      d++;
      zero = 0;
    }
    if( zero == 0 )
      *p++ = d ;
  }while( i );

  *p++ = (unsigned char)uval + '0';
}
 
 View user's profile Send private message  
Reply with quote Back to top
Display posts from previous:     
Jump to:  
All times are GMT + 1 Hour
Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Powered by PNphpBB2 © 2003-2006 The PNphpBB Group
Credits