Объединить 5 или более байтов и преобразовать в десятичный, а затем в ASCII

У меня есть этот массив ниже:

dataIn[5] = 0x88;
dataIn[6] = 0x2A;
dataIn[7] = 0xC7;
dataIn[8] = 0x2B;
dataIn[9] = 0x00;
dataIn[10] = 0x28;

Мне нужно преобразовать эти значения в десятичные, потому что после этого мне нужно преобразовать десятичные значения в ASCII и отправить в UART.

Eg:

|    Hexa      |      Decimal      | ASCII (I need to send this data to UART)
| 0x882AC72B00  | 584 833 248 000  | 35 38 34 38 33 33 32 34 38 30 30 30
| 0x5769345612  | 375 427 192 338  | 33 37 35 34 32 37 31 39 32 33 33 38

Моя проблема: эти данные должны быть собраны вместе и преобразованы в десятичные числа, но мой компилятор рассчитан только на 4 байта, и я не знаю, как это сделать, потому что у меня когда-либо было 5 или более байтов.

Ps.: Я использую PIC18F46K80 и компилятор C18.

[Отредактировано]

Нажмите здесь, чтобы узнать, что произойдет, если я попытаюсь использовать более 4 байтов. Это моя проблема

Кто-нибудь может мне помочь?

Заранее спасибо.


person Pedro Junior    schedule 28.01.2018    source источник
comment
Как вы группируете десятичные значения? Сколько битов вы используете для каждого десятичного значения? Как разбить пять байтов на четыре десятичных значения? Извините за повторение и повторение одного и того же вопроса три раза, но это действительно важно, чтобы помочь понять вашу проблему и способы ее решения.   -  person Some programmer dude    schedule 28.01.2018
comment
Почему вам нужно отправить их как символы? Для показа?   -  person Benjamin Barrois    schedule 28.01.2018
comment
Эти данные поступают от UART, поэтому я получаю их один за другим и помещаю в этот массив. Как мне сгруппировать десятичные значения? Я использую побитовый сдвиг битов, но это моя проблема, я не могу этого сделать, потому что мой компилятор может максимум 4 байта.   -  person Pedro Junior    schedule 30.01.2018
comment
Да, это для отображения данных, но я отправляю эти данные в свое приложение для Android, и это приложение может понимать только ASCII.   -  person Pedro Junior    schedule 30.01.2018


Ответы (2)


Если я правильно понял, прежде всего вы должны определить союз следующим образом:

typedef union _DATA64
{
    uint64_t dataIn64;
    uint8_t dataIn8[8];
}tu_DATA64;

а затем скопируйте шестнадцатеричные значения в предыдущем определенном объединении:

uint8_t i;
tu_DATA64 data;

...

data.dataIn64=0;
for(i=0; i<5; i++)
    data.dataIn8[4-i]=dataIn[i];

теперь вам нужно преобразовать 64-битную переменную в строку с помощью функции lltoa, как это предлагается в этой опубликовать:

char *str;

...

str=lltoa(data.dataIn64,10);

str — это строка буфера для отправки.

person LucaG    schedule 29.01.2018
comment
Мой компилятор не долго долго. Моя большая переменная имеет 4 байта (длинные), это моя проблема. Когда я пытаюсь установить переменную с 8 байтами и открываю проверку отладки, я вижу только 4 байта, потому что это максимум для моего компилятора. В этом случае, что я могу сделать? Должен ли я создать союз, как вы упоминали ранее? - person Pedro Junior; 30.01.2018
comment
Я прикрепил изображение к моему вопросу выше с примером. Может быть, это поможет вам лучше понять, что мне нужно. Так же, спасибо за ответ - person Pedro Junior; 30.01.2018
comment
Но пытались ли вы включить библиотеку stdint.h и использовать uint64_t для объявления переменной long long? Обычно для этого используется stdint.h. - person LucaG; 30.01.2018
comment
Да, но самая большая переменная у меня есть uint32_t, компилятор xc8 не поддерживает uint64_t. Вот почему я не знаю, как справиться с этим. - person Pedro Junior; 30.01.2018
comment
Извините за задержку. Я думаю, что единственным решением является реализация пользовательской функции itoa, которая преобразует байтовый буфер в строку. Вы можете получить подсказку на этом сайте: ссылка. Основное внимание уделяется повторной реализации модулей num % base и операций деления num/base для буфера вместо целочисленного. - person LucaG; 02.02.2018
comment
Привет, Лукас, не беспокойтесь о вашей задержке, ваши идеи были очень полезными. У меня не было времени, чтобы попытаться реализовать это решение, но когда я найду решение, я вернусь сюда, чтобы сообщить всем вам, как с этим бороться. - person Pedro Junior; 05.02.2018

Рассматривали ли вы возможность написания собственной функции преобразования? Вот рабочий пример, который можно настроить на любую длину.

ВНИМАНИЕ: Мои навыки C не самые лучшие!

#include <stdio.h>

/******************************************************************************/

void base10_ascii(unsigned char data[], int data_size, char ans[], int ans_size) {
  char done;
  do {
    char r = 0;
    done = 1;
    for (int i=0; i<data_size; i++) {
      int b = (r<<8) + data[i]; //previous remainder and current byte
      data[i] = b / 10;
      if (data[i] > 0) done = 0; //if any digit is non-zero, not done yet
      r = b % 10;
    }
    for (int i=ans_size-1; i>0; i--) ans[i] = ans[i-1]; //bump up result
    ans[0] = r + '0'; //save next digit as ASCII (right to left)
  } while (!done);
}

/******************************************************************************/

int main(){
  char outputBuffer[15] = {0};
  char data[] = { 0x88, 0x2A, 0xC7, 0x2B, 0x00 }; //584833248000
  base10_ascii(data,sizeof data,outputBuffer,sizeof outputBuffer);
  printf("Output: %s\n",outputBuffer);
  return 0;
}
person tonypdmtr    schedule 03.02.2018