Jump to content
    

Преобразование Int в строку на LCD (ICCAVR7)

При выводе текста на LCD от Nokia3210 использую стандартную функцию

 

//----------------------------

void LcdStr ( LcdFontSize size, byte *dataPtr )

{

while ( *dataPtr !=0x00)

{

LcdChr( size, *dataPtr++ );

}

}

 

!!! вопрос как отобразить на LCD числовые значения заданной переменной

например

int X;

X=4123;

пример взят с www.microsyl.com

буду признателен всем! :santa2:

Share this post


Link to post
Share on other sites

!!! вопрос как отобразить на LCD числовые значения заданной переменной

например

int X;

X=4123;

пример взят с www.microsyl.com

буду признателен всем! :santa2:

 

/*****************************************************************************
Преобразовывает переменную UINT в неупакованное BCD
Если параметр ch == TRUE, то, дополнительно, преобразует полученное число в
строку
******************************************************************************/
void uint2bcd(UINT16 src, UCHAR *trg, BOOL ch)
{ 
   UINT16 d = 10000;
   for(UCHAR i = 0; i < 5; i++) /* цикл по пяти знакам */
    { 
       trg[i] = 0; /* формируем сумму искомого числа */
       while(src > d) /* пока порядок не отрицательный */
        { src-= d; /* вычитаем из знака порядок */
         trg[i]++; /* и увеличиваем искомое число */
        }

        if(TRUE == ch) /* преобразуем в ASCII символ */
        { trg[i] += 0x30;
        }
        d /= 10; /* получаем следующий (младший) порядок */
    }
    trg[5] = 0;
}

/*****************************************************************************
Преобразовывает переменную ULONG в неупакованное BCD
Если параметр ch == TRUE, то, дополнительно, преобразует полученное число в
строку
******************************************************************************/
void ulong2bcd(UINT32 src, UCHAR *trg, BOOL ch)
{ 
   UINT32 d = 1000000000;
   for(UCHAR i = 0; i < 10; i++) /* цикл по десяти знакам */
    { 
       trg[i] = 0; /* формируем сумму искомого числа */
       while(src > d) /* пока порядок не отрицательный */
        { src-= d; /* вычитаем из знака порядок */
         trg[i]++; /* и увеличиваем искомое число */
        }

        if(TRUE == ch) /* преобразуем в ASCII символ */
        { trg[i] += 0x30;
        }
        d /= 10; /* получаем следующий (младший) порядок */
    }
    trg[10] = 0;
}

Share this post


Link to post
Share on other sites

Есть такая функция sprintf.

 

Пробовал -- не хватает памяти контроллера...

Нужно что то полегче...

 

!!! вопрос как отобразить на LCD числовые значения заданной переменной

например

int X;

X=4123;

пример взят с www.microsyl.com

буду признателен всем! :santa2:

 

/*****************************************************************************
Преобразовывает переменную UINT в неупакованное BCD
Если параметр ch == TRUE, то, дополнительно, преобразует полученное число в
строку
******************************************************************************/
void uint2bcd(UINT16 src, UCHAR *trg, BOOL ch)
{ 
   UINT16 d = 10000;
   for(UCHAR i = 0; i < 5; i++) /* цикл по пяти знакам */
    { 
       trg[i] = 0; /* формируем сумму искомого числа */
       while(src > d) /* пока порядок не отрицательный */
        { src-= d; /* вычитаем из знака порядок */
         trg[i]++; /* и увеличиваем искомое число */
        }

        if(TRUE == ch) /* преобразуем в ASCII символ */
        { trg[i] += 0x30;
        }
        d /= 10; /* получаем следующий (младший) порядок */
    }
    trg[5] = 0;
}

/*****************************************************************************
Преобразовывает переменную ULONG в неупакованное BCD
Если параметр ch == TRUE, то, дополнительно, преобразует полученное число в
строку
******************************************************************************/
void ulong2bcd(UINT32 src, UCHAR *trg, BOOL ch)
{ 
   UINT32 d = 1000000000;
   for(UCHAR i = 0; i < 10; i++) /* цикл по десяти знакам */
    { 
       trg[i] = 0; /* формируем сумму искомого числа */
       while(src > d) /* пока порядок не отрицательный */
        { src-= d; /* вычитаем из знака порядок */
         trg[i]++; /* и увеличиваем искомое число */
        }

        if(TRUE == ch) /* преобразуем в ASCII символ */
        { trg[i] += 0x30;
        }
        d /= 10; /* получаем следующий (младший) порядок */
    }
    trg[10] = 0;
}

 

 

 

Спасибо счас попробую обкатать...

Share this post


Link to post
Share on other sites

!!! вопрос как отобразить на LCD числовые значения заданной переменной

например

int X;

X=4123;

/*
=====================================================================
    itoa.
=====================================================================
*/
char* itoa (int value, char *string, int radix)
{
    //~~~~~~~~~~~~~~~~~~~~~~~~~
    char            *dst;
    char            digits[32];
    unsigned int    x;
    int                i, n;
    //~~~~~~~~~~~~~~~~~~~~~~~~~

    dst = string;
    if (radix < 2 || radix > 36)
    {
        *dst = 0;
        return string;
    }
    if (radix == 10 && value < 0)
    {
        *dst++ = '-';
        x = -value;
    }
    else x = value;
    i = 0;
    do
    {
        n = x % radix;
        digits[i++] = (n < 10 ? (char)n+'0' : (char)n-10+'a');
        x /= radix;
    } while (x != 0);
    while (i > 0) *dst++ = digits[--i];
    *dst = 0;
    return string;
}

Попроще

/*
=====================================================================
    "Переворачивает" строку символов.
=====================================================================
*/
void strreverse(char* begin, char* end)
{
    char aux;
    while(end > begin) aux=*end, *end--=*begin, *begin++=aux;
}
/*
=====================================================================
    Перевод числа в строку символов.
=====================================================================
*/
char* itoa(int value, char* result, unsigned char base)
{
    //~~~~~~~~~~~~~~~~~~~
    char*    out = result;
    int        quotient;
    //~~~~~~~~~~~~~~~~~~~
    
    // check that the base if valid
    if (base < 2 || base > 16)
    {
        *result = 0;
        return result;
    };

    if (value >= 0) quotient = value;
    else quotient = -value;
    do
    {
        *out = "0123456789ABCDEF"[quotient % base];
        ++out;
        quotient /= base;
    } while (quotient);
    
    // Only apply negative sign for base 10
    if (value < 0 && base == 10) *out++ = '-';
    
    strreverse(result, out-1);
    *out = 0;
    return result;
}

Еще проще

/*
=====================================================================
    Перевод числа в строку ASCII символов.
    Принимает максимальное значение для перевода 65535.
    Результат -> в массиве char`ов.
=====================================================================
*/
void IntToStr (unsigned int val, char str[])
{
    //~~~~~~~~~~~~~~~~~~~~~~~
    signed char i = 0, j = 0;
    unsigned char digits[5];
    //~~~~~~~~~~~~~~~~~~~~~~

    while (val)
    {
        digits[i] = val % 10; i++; val = val / 10;
    };
    i--;
    while ( i >= 0 )
    {
        str[j] = (digits[i]+ 0x30); j++; i--;
    };
    str[j] = 0x00;
}

И здесь посмотрите

http://www.jb.man.ac.uk/~slowe/cpp/itoa.html

Share this post


Link to post
Share on other sites

Вот еще. bin2bcd32 - преобразование bin-packed bcd (num_bytes - количество байтов на выходе), ilcd_ks066_pul - вывод беззнакового числа data в память по адресу buf, options - параметры вывода (биты 0..2 - количество знаков-1, биты 4..6 - положение точки, считая справа, бит 7=1 для преобразования bin-bcd, бит 3=1 для удаления незначащих нулей. ilcd_ks066_point_char - используемый символ точки. ilcd_ks066_psl - вывод знакового числа с теми же параметрами.

uint32_t bin2bcd32(uint32_t num, uint8_t num_bytes) /**< \brief Convert uint32_t num to packed BCD using num_bytes of number - universal \ingroup ul_math */
{uint32_t ul1=0; /*result*/
uint8_t uc1;
for (uc1=(4-num_bytes);uc1;uc1--) num<<=8; /*adjust input bytes*/
for (uc1=(num_bytes<<3);uc1;uc1--) /*bit shift loop*/
{uint8_t uc2,uc3;
  /*BCD nibbles correction*/
  ul1+=0x33333333;
  for (uc3=4;uc3;uc3--)
  {uc2=(uint8_t)(ul1>>24);
   if (!(uc2&0x08)) uc2-=0x03;
   if (!(uc2&0x80)) uc2-=0x30;
   ul1=ul1<<8; ul1|=uc2;
  }
  /*shift next bit of input and result*/
  ul1<<=1;
  if ((num>>24)&0x80) ul1|=1;
  num<<=1;
}
return(ul1);
}

static unsigned char ilcd_ks066_point_char='.'; /*point symbol,can be changed*/
void ilcd_ks066_pul(unsigned long data,void* ibuf,unsigned char options)
{unsigned char uc1,uc2,uc3,uc4;
  uc1=(options&7)+1;
  if (options&0x80)
  {unsigned char uc5;
   uc5=(uc1+1)>>1;
   if (uc5>4) uc5=4;
   if (uc5==0) uc5=1;
   data=conv_bin2bcd(data,uc5);
  }
  uc3=((options>>4)&7);
  uc2=uc1-uc3;
  if (uc3) uc2++;
  while (uc1)
  {if ((options&8)&&(data==0)&&(uc1<uc2)) *(unsigned char *)ibuf=' ';
   else
   {uc4=(data&0xf)+'0';
    if (uc4>'9') uc4+=7;
    if ((uc1==uc2)&&(uc3))
    {*(unsigned char *)ibuf=ilcd_ks066_point_char;
     ibuf--;
    }
    *(unsigned char *)ibuf=uc4;
   }
   uc1--; data>>=4; ibuf--;
  }
}

void ilcd_ks066_psl(signed long data,void *ibuf,unsigned char options)
{if (data<0)
  {ilcd_ks066_pul(-data,ibuf,options);
   *(unsigned char*)(ibuf-(options&7))='-';
  } else ilcd_ks066_pul(data,ibuf,options);
}

Share this post


Link to post
Share on other sites

При выводе текста на LCD от Nokia3210 использую стандартную функцию

 

//----------------------------

void LcdStr ( LcdFontSize size, byte *dataPtr )

{

while ( *dataPtr !=0x00)

{

LcdChr( size, *dataPtr++ );

}

}

 

!!! вопрос как отобразить на LCD числовые значения заданной переменной

например

int X;

X=4123;

пример взят с www.microsyl.com

буду признателен всем! :santa2:

 

 

Вот еще вариант itoa(). Здесь строку-приемник не нужно переворачивать. А вообще, на мой взгляд,

с этой itoa() полный бардак. В IAR ее вообще нет, в других компиляторах набор параметров, какой автору в голову взбредет...

 

char *itoa(int In, char *OString, int Base) {

 

const int IntSize = 16+3; //Самый худший вариант - двоичное число

 

register char *p;

register int minus;

 

p = &OString[intSize];

*--p = '\0';

if ((In < 0) && (Base==10)){

minus = 1;

In = -In;

}

else

minus = 0;

if (In == 0)

*--p = '0';

else

while (In > 0) {

*--p = "0123456789abcdef"[in % Base];

In /= Base;

}

if (minus)

*--p = '-';

return p;

}

Share this post


Link to post
Share on other sites

Большое спасибо за оказанную помощь!!!

Особая благодарность prottoss, aleksey_g, Stefan, umup и другим. С наступающим Новым годом!

Vovan007 :santa2:

Share this post


Link to post
Share on other sites

On 12/17/2006 at 6:02 AM, Ljubitel said:

Еще проще

 

/*
=====================================================================
    Перевод числа в строку ASCII символов.
    Принимает максимальное значение для перевода 65535.
    Результат -> в массиве char`ов.
=====================================================================
*/
void IntToStr (unsigned int val, char str[])
{
    //~~~~~~~~~~~~~~~~~~~~~~~
    signed char i = 0, j = 0;
    unsigned char digits[5];
    //~~~~~~~~~~~~~~~~~~~~~~

    while (val)
    {
        digits[i] = val % 10; i++; val = val / 10;
    };
    i--;
    while ( i >= 0 )
    {
        str[j] = (digits[i]+ 0x30); j++; i--;
    };
    str[j] = 0x00;
}

Подскажите, а как пользоваться этой функцией? Как мне число 35 преобразовать в текст "35"? Что передавать в IntToStr?

Share this post


Link to post
Share on other sites

Спасибо, заработало!

А почему тут четверка: char buffer[4]; ? Почему не 5, если максимальное число пятизначное?

Я пробовал char buffer[от 2 до 10] и число 65535 нормально выводится на LCD 1602, целиком. Вот при char buffer[1] возникают глюки.

А еще, как преобразовать не двухбайтное число, а трех- или четырехбайтное?

Share this post


Link to post
Share on other sites

2 hours ago, James D. said:

Спасибо, заработало!

А почему тут четверка: char buffer[4]; ? Почему не 5, если максимальное число пятизначное?

Я пробовал char buffer[от 2 до 10] и число 65535 нормально выводится на LCD 1602, целиком. Вот при char buffer[1] возникают глюки.

А еще, как преобразовать не двухбайтное число, а трех- или четырехбайтное?

Потому что спрашивали про 35.

char buffer[11];
от 0 до 4294967295 (если unsigned int = uint32_t)

char buffer[6];
от 0 до 65535 (если unsigned int = uint16_t)

Share this post


Link to post
Share on other sites

11 hours ago, x893 said:

char buffer[11];

А почему 11, если цифр 10?

 

11 hours ago, x893 said:

(если unsigned int = uint32_t)

Насчет этого я не понял. Я сделал void IntToStr(unsigned long val, char str[]). Работает.

Share this post


Link to post
Share on other sites

4 minutes ago, James D. said:

А почему 11, если цифр 10?

Потому что строка должна заканчиваться \0

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...