реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Перевод из 16 ричной в 10чную на Си
Slavast
сообщение Jan 25 2011, 13:39
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 81
Регистрация: 25-10-10
Пользователь №: 60 395



Добрый день!
Необходимо с АЦП вывести снятое напряжение на терминал.
Подскажите как на Си можно перевести число из 16ричной системы в 10чную?
А то фраза на экране "Напряжение АЦП: 0x56" смотрится как-то неубедительно.
Есть какой-то готовый код или библиотека?
Спасибо.
Go to the top of the page
 
+Quote Post
МП41
сообщение Jan 25 2011, 13:43
Сообщение #2


4 синих кубика
****

Группа: Участник
Сообщений: 526
Регистрация: 19-09-08
Из: полупроводника, металла и стекла
Пользователь №: 40 326



Вам нужно преобразование двоичного представления в двоично-десятичное, искать по фразе "bin2dec". Двоично-десятичное представление адаптировано под вывод на ЖКИ, 7-сегментные индикаторы и т.д., каждый байт отвечает за 2 разряда в диапазоне 0..9 каждый.


--------------------
p-n-p-p-n-p-n-n-p-n-p структура однако очень эффективна
Go to the top of the page
 
+Quote Post
Slavast
сообщение Jan 25 2011, 13:48
Сообщение #3


Частый гость
**

Группа: Участник
Сообщений: 81
Регистрация: 25-10-10
Пользователь №: 60 395



Цитата(МП41 @ Jan 25 2011, 17:43) *
Вам нужно преобразование двоичного представления в двоично-десятичное, искать по фразе "bin2dec". Двоично-десятичное представление адаптировано под вывод на ЖКИ, 7-сегментные индикаторы и т.д., каждый байт отвечает за 2 разряда в диапазоне 0..9 каждый.


Я оперирую на AtMega 2561 числами в 16 ричной форме. Получается мне сначала надо перевести из 16 в 2, а потом из 2 в 10 ную форму?
Go to the top of the page
 
+Quote Post
МП41
сообщение Jan 25 2011, 14:04
Сообщение #4


4 синих кубика
****

Группа: Участник
Сообщений: 526
Регистрация: 19-09-08
Из: полупроводника, металла и стекла
Пользователь №: 40 326



Если на пальцах, то можно сделать так. Например, берёте с АЦП 16-битное значение, зная, что оно в реальности 10-и битное и не будет больше 1023, начинаем отнимать 1000, покуда число больше 1000-и и считаем количество таких вычитаний (записываем в отдельную переменную). Далее вычитаем из того, что осталось сотни, покуда число не станет меньше сотни, считая количество сотен. Далее вычитаем десятки с аналогичной проверкой, в результате останутся единицы.

Цитата(Slavast @ Jan 25 2011, 15:48) *
Я оперирую на AtMega 2561 числами в 16 ричной форме.

На самом деле Вы оперируете 16-ричным представлением двоичных чисел.

Код
char dec1000=0;//тысячи
char dec100=0;//сотни
char dec10=0;//десятки
char dec1=0;//единицы

while(value>1000)
{
value-=1000;
dec1000++;
}

while(value>100)
{
value-=100;
dec100++;
}

while(value>10)
{
value-=10;
dec10++;
}

dec1=value;


Извиняюсь, не "bin2dec", а "bin2BCD" для C нужно искать.


--------------------
p-n-p-p-n-p-n-n-p-n-p структура однако очень эффективна
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jan 25 2011, 14:42
Сообщение #5


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(МП41 @ Jan 25 2011, 17:04) *
while(value>1000)

while(value>=1000)
итд итп.
Go to the top of the page
 
+Quote Post
МП41
сообщение Jan 25 2011, 14:44
Сообщение #6


4 синих кубика
****

Группа: Участник
Сообщений: 526
Регистрация: 19-09-08
Из: полупроводника, металла и стекла
Пользователь №: 40 326



_Pasha, спасибо, Вы правы.


--------------------
p-n-p-p-n-p-n-n-p-n-p структура однако очень эффективна
Go to the top of the page
 
+Quote Post
prottoss
сообщение Jan 25 2011, 15:03
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659



Я иногда пользуюсь вот таким кодом в разных вариациях. Написано было еще в универеsm.gif
CODE
/*******************************************************************************
Преобразовывает переменную UINT8 в строку с гашением не значащих нулей
*******************************************************************************/
INT uint8_2str(UINT8 val, P_CHAR str)
{
INT i, len = 0;
BOOL zero = TRUE;
UINT8 d = 100;
CHAR s;

for(i = 0; i < 3; i++) /* цикл по трем знакам */
{
s = 0; /* формируем сумму искомого числа */
while(val >= d) /* пока порядок не отрицательный */
{
val -= d; /* вычитаем из знака порядок */
s++; /* и увеличиваем искомое число */
}

if(TRUE == zero && s == 0 && i < 2)
{
}
else
{
*str++ = s + 0x30; /* преобразуем в ASCII символ */
len++;
zero = FALSE;
}
d /= 10; /* получаем следующий (младший) порядок */
}

return len;
}

/*******************************************************************************
Преобразовывает переменную UINT8 в строку без гашения
не значащих нулей в диапазоне 0...99 (два знака)
*******************************************************************************/
void uint8_2str2(UINT8 val, P_CHAR str)
{
INT i;
UINT8 d = 10;
CHAR s;

for(i = 0; i < 2; i++) /* цикл по двум знакам */
{
s = 0; /* формируем сумму искомого числа */
while(val >= d) /* пока порядок не отрицательный */
{
val -= d; /* вычитаем из знака порядок */
s++; /* и увеличиваем искомое число */
}

*str++ = s + 0x30; /* преобразуем в ASCII символ */
d /= 10; /* получаем следующий (младший) порядок */
}
}

/*******************************************************************************
Преобразовывает переменную UINT16 в строку
*******************************************************************************/
INT uint16_2str(UINT16 val, P_CHAR str)
{
INT i, len = 0;
BOOL zero = TRUE;
UINT16 d = 10000;
CHAR s;

for(i = 0; i < 5; i++) /* цикл по пяти знакам */
{
s = 0; /* формируем сумму искомого числа */
while(val >= d) /* пока порядок не отрицательный */
{
val-= d; /* вычитаем из знака порядок */
s++; /* и увеличиваем искомое число */
}

if(TRUE == zero && s == 0 && i < 4)
{
}
else
{
*str++ = s + 0x30; /* преобразуем в ASCII символ */
len++;
zero = FALSE;
}
d /= 10; /* получаем следующий (младший) порядок */
}

return len;
}

/*******************************************************************************
Преобразовывает переменную UINT32 в строку
*******************************************************************************/
INT uint32_2str(UINT32 val, P_CHAR str)
{
INT i, len = 0;
BOOL zero = TRUE;
UINT32 d = 1000000000;
CHAR s;

for(i = 0; i < 10; i++) /* цикл по десяти знакам */
{
s = 0; /* формируем сумму искомого числа */
while(val >= d) /* пока порядок не отрицательный */
{
val-= d; /* вычитаем из знака порядок */
s++; /* и увеличиваем искомое число */
}

if(TRUE == zero && s == 0 && i < 9)
{
}
else
{
*str++ = s + 0x30; /* преобразуем в ASCII символ */
len++;
zero = FALSE;
}
d /= 10; /* получаем следующий (младший) порядок */
}

return len;
}

/*******************************************************************************
Преобразует строку в 8-бит число.
Возвращает количество цифр в числе, 0 - если строка не число.
*******************************************************************************/
INT str2_uint8(P_CHAR str, P_UINT8 val)
{
INT i = 0;
UINT8 res = 0;
CHAR s;

while(i < 3)
{
s = *str++;
if(s < '0' || s > '9')
break;
res = res * 10 + s - '0';
i++;
}

*val = res;
return i;
}

/*******************************************************************************
Преобразует строку в 16-бит число.
Возвращает количество цифр в числе, 0 - если строка не число.
*******************************************************************************/
INT str2_uint16(P_CHAR str, P_UINT16 val)
{
INT i = 0;
UINT16 res = 0;
CHAR s;

while(i < 5)
{
s = *str++;
if(s < '0' || s > '9')
break;
res = res * 10 + s - '0';
i++;
}

*val = res;
return i;
}

/*******************************************************************************
Преобразует строку в 16-бит число.
Возвращает количество цифр в числе, 0 - если строка не число.
*******************************************************************************/
INT str2_uint32(P_CHAR str, P_UINT32 val)
{
INT i = 0;
UINT32 res = 0;
CHAR s;

while(i < 10)
{
s = *str++;
if(s < '0' || s > '9')
break;
res = res * 10 + s - '0';
i++;
}

*val = res;
return i;
}


--------------------
Go to the top of the page
 
+Quote Post
Marian
сообщение Jan 25 2011, 15:21
Сообщение #8


Частый гость
**

Группа: Участник
Сообщений: 148
Регистрация: 23-02-07
Пользователь №: 25 618



Цитата(Slavast @ Jan 25 2011, 16:39) *
Добрый день!
Необходимо с АЦП вывести снятое напряжение на терминал.
Подскажите как на Си можно перевести число из 16ричной системы в 10чную?
А то фраза на экране "Напряжение АЦП: 0x56" смотрится как-то неубедительно.
Есть какой-то готовый код или библиотека?
Спасибо.


Для вывода использую функцию printf из <stdio.h>
Преобразовать в строку без вывода sprintf
Если вы говорите что на экране 0x56,
по идее вы уже использовали преобразование или я что не так понял?

Сообщение отредактировал Marian - Jan 25 2011, 15:34
Go to the top of the page
 
+Quote Post
AndOr
сообщение Jan 25 2011, 16:00
Сообщение #9


Участник
*

Группа: Участник
Сообщений: 44
Регистрация: 10-03-09
Из: Всея Руси
Пользователь №: 45 907



Можно пользовать вариации print, но тяжелые в плане размеров кода.
Если пишется под CVAVR'ом я пользую itoa(var, str); //где var число из АЦП (осторожнее со знаком), str - строчный массив.
Часто нужно переводить в вольты, для этого целая цепь событий:
Например, если опора АЦП 2,56В (ступень 2,5мВ), а мерить нужно до 10В, я ставлю резистивный делитель на 4 на входе (30кОм послед, 10кОм ll 10нФ на землю).
Получили, соответственно, уже 10мВ на ступень, но для вывода в Вольтах нужно делить на 100, что делается путем установки запятой.
Вот пример (правда старый):
CODE

//==================================================================
// Convert int var value (up to 999) to string formated 1,23 and add endstrf string as suffix, V for example
void into1_2str (char *str, unsigned int var, char flash *endstrf)
{
char len;

if (var >= 1000) var = 999;
itoa (var, str);
len = strlen(str);
switch (len)
{
case 1:
str[3] = str[0];
str[2] = '0';
str[1] = ',';
str[0] = '0';
break;

case 2:
str[3] = str[1];
str[2] = str[0];
str[1] = ',';
str[0] = '0';
break;

case 3:
str[3] = str[2];
str[2] = str[1];
str[1] = ',';
break;
}
str[4] = 0;
strcatf(str, endstrf);

}
//==========================================================================

Которая из этих требуется не помню, можно определить методом исключения:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <bcd.h>

пример вызова:
{
unsigned int adc_data[LAST_ADC_INPUT-FIRST_ADC_INPUT+1]; //в CVAVR обычно инициализируется перед обработчиком прерывания ADC_INT
char menu_str[20], temp_str[20];
.......
strcpyf(menu_str, "Vcc=");
into1_2str (temp_str, adc_data[VCC], "В");
strcat(menu_str, temp_str);
.......
}


--------------------
Чужие ошибки ничему не учат, гораздо интереснее наделать своих.
Go to the top of the page
 
+Quote Post
_Bill
сообщение Jan 25 2011, 18:27
Сообщение #10


Местный
***

Группа: Участник
Сообщений: 416
Регистрация: 18-04-06
Из: Челябинск
Пользователь №: 16 219



Цитата(Slavast @ Jan 25 2011, 17:48) *
Я оперирую на AtMega 2561 числами в 16 ричной форме. Получается мне сначала надо перевести из 16 в 2, а потом из 2 в 10 ную форму?

Вообще-то, ATmega оперирует с двоичными числами, равно как и практически все остальные процессоры (компьютеры).
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 03:58
Рейтинг@Mail.ru


Страница сгенерированна за 0.01449 секунд с 7
ELECTRONIX ©2004-2016