Как отправить шестнадцатеричную строку в последовательный порт? - PullRequest
0 голосов
/ 05 января 2019

Я разрабатываю программу последовательной связи для отправки и получения данных между хост-компьютером (Linux) и микроконтроллером. Теперь я должен отправить шестнадцатеричные байты данных в MCU. Так Как я могу преобразовать мои данные строки буфера в шестнадцатеричную строку без использования sprint / printf, чтобы пользователь отправлял строку, например «AA12CDFF1000001201» вместо «\ xAA \ x12 \ xCD \ xFF \ x10 \ x00 \ x00 \ x12 \ x01» в MCU. Я также видел отправка шестнадцатеричного числа в последовательный порт , но это бесполезно, поскольку в нем говорится, что я могу преобразовать строку в шестнадцатеричное с использованием sprintf, но здесь, в моем случае, я не хочу использовать sprinf. В основном я хочу: Если пользователь введет input = "AA12CDFF1000001201", я должен преобразовать его в следующий формат "\ xAA \ x12 \ xCD \ xFF \ x10 \ x00 \ x00 \ x12 \ x01", а затем записать его в последовательный порт.

#include <stdio.h>   /* Standard input/output definitions */
#include <string.h>  /* String function definitions */
#include <unistd.h>  /* UNIX standard function definitions */
#include <fcntl.h>   /* File control definitions */
#include <errno.h>   /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
void main()
{
int fd;
fd = open("/dev/ttyf1", O_RDWR | O_NOCTTY | O_NDELAY);
char buff[]="\xAA\x12\xCD\xFF\x10\x00\x00\x12\x01";
write(fd, buff, sizeof(buff));
close(fd);
}    

Ответы [ 5 ]

0 голосов
/ 05 января 2019

Как я могу преобразовать мои данные строки буфера в шестнадцатеричную строку .... так что пользователь отправляет ...?

give input = "AA12CDFF1000001201" Я должен преобразовать его в следующий формат "\ xAA \ x12 \ xCD \ xFF \ x10 \ x00 \ x00 \ x12 \ x01" и затем записать его в последовательный порт.

Когда промежуточное хранилище для буфера не требуется, это довольно просто.

Преобразование 2 байтов 1 оригинальной строки за один раз в байт, запись каждого байта за итерацию.

#include <ctype.h>

void write_hex_string(const char *hs) {
  while (isxdigit(hs[0]) && isxdigit(hs[1])) {
    char buf[3] = { hs[0], hs[1], '\0' };
    unsigned char value = (unsigned char) strtol(buf, 0, 16);
    write(fd, &value, sizeof value);
    hs += 2;
  }
}

Пример использования

write_hex_string("AA12CDFF1000001201");

Если код может изменить исходную строку как часть процесса, жизнь тоже проста. Так как есть удобное место для хранения конверсии.

void write_hex_string(char *hs) {
  char *pair  = hs;
  size_t length = 0;
  while (isxdigit(pair[0]) && isxdigit(pair[1])) {
    char buf[3] = { pair[0], pair[1], '\0' };
    hs[length++]  = (unsigned char) strtol(buf, 0, 16);
    pair += 2;
  }
  write(fd, hs, length);
}

1 До тех пор, пока оба символа являются шестнадцатеричными цифрами: ['0' - '9', 'A' - 'F', 'a' - 'f'].

0 голосов
/ 05 января 2019

После плодотворного обсуждения с Хессамом и Арку новая версия кода:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char* str2hexstr(char* inbuff) {

    char *outbuff;

    if (strlen(inbuff)%2) {
        outbuff=malloc((strlen(inbuff)*2+3)*sizeof(char));
        outbuff[strlen(inbuff)*2+2]='\0'; }
    else {
        outbuff=malloc(strlen(inbuff)*2+1*sizeof(char));
        outbuff[strlen(inbuff)*2]='\0'; }

    for (int strin=0,strout=0;strin<strlen(inbuff);) {
        outbuff[strout++]='\\';
        outbuff[strout++]='x';
        outbuff[strout++]=(!strin&&strlen(inbuff)%2)?'0':inbuff[strin++];
        outbuff[strout++]=inbuff[strin++];
    }
    return(outbuff);
}
int main()
{
    char inbuff1[]="123",inbuff2[]="1234";
    char *outbuff;

    outbuff=str2hexstr(inbuff1);
    printf("%s\n",outbuff);
    free(outbuff);
    outbuff=str2hexstr(inbuff2);
    printf("%s\n",outbuff);
    free(outbuff);
    return 0;
}
0 голосов
/ 05 января 2019

Посмотрите на это, а не на чистый код, но вы должны выполнить работу

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void hexify(const char *input, char *output)
{
    int i = 0;
    int o = 0;
    while(1)
    {
        if(input[i] == 0) break; 
        output[o++] = '\\';
        output[o++] = 'x';
        output[o++] = input[i++];
        if(input[i] == 0) break; 
        output[o++] = input[i++];
    }
    output[o] = 0;
}

 int main()
 {
     char test[]="112233AA"; //user input
     if((strlen(test) % 2) && strlen(test) != 1)
         printf("Input is not in correct format");
     else
     {
         char *out = malloc(2 * strlen(test) + 1);
         hexify(test, out);
         printf("%s", out);
         free(out);//dont forget this
     }
     return 0;
 }
0 голосов
/ 05 января 2019

Хотите что-нибудь подобное:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    char inbuff[]="AA12CDFF1000001201";
    char *outbuff;

    if (strlen(inbuff)%2) {
            printf("error : strlen is odd");
            exit(1);}
    outbuff=malloc((strlen(inbuff)*2+1)*sizeof(char));
    for (int strin=0,strout=0;strin<strlen(inbuff);) {
        outbuff[strout++]='\\';
        outbuff[strout++]='x';
        outbuff[strout++]=inbuff[strin++];
        outbuff[strout++]=inbuff[strin++];
    }
    outbuff[strlen(inbuff)*2]='\0';
    printf("%s\n",outbuff);
    return 0;
}
0 голосов
/ 05 января 2019

Преобразовать из строки в байты

#include <stdio.h>
#include <string.h>
#include <stdint.h>

/* Dummy input */
char input[] = "11121314151617181920";
uint8_t output[32];

/* Convert input char to int */
uint8_t
char2byte(char c) {
    if (c >= '0' && c <= '9') {
        return c - '0';
    } else if (c >= 'A' && c <= 'F') {
        return c - 'A' + 10;
    } else if (c >= 'a' && c <= 'f') {
        return c - 'a' + 10;
    }
    return 0;
}

int
main() {
    size_t len;

    /* String must be even */
    len = strlen(input);
    if (len & 1 == 0) {

    }
    /* Process all inputs, 2 chars for single byte */
    for (size_t i = 0; i < len / 2; ++i) {
        output[i] = char2byte(input[2 * i]) << 4;
        output[i] |= char2byte(input[2 * i + 1]);
    }

    /* Test, expected is 0x13 */
    printf("Test output[2] = %02X\r\n", (unsigned)output[2]);

    return 0;
}

Если вы запустите код: Test output[2] = 13

Преобразовать из байтов в строку

Как то так. Цель состоит в том, чтобы перевести каждый кусок каждого байта в символ. Это означает, что длина вывода в два раза больше исходного размера буфера.

#include <stdio.h>
#include <string.h>
#include <stdint.h>

/* Output array */
char output[128];

/* Dummy input data array */
char data[] = {0x12, 0x13, 0x14, 0x00, 0x5A};

/* Convert each nibble to char */
char num2char(uint8_t num) {
    if (num < 10) {
        return num + '0';
    } else if (num < 16) {
        return num - 10 + 'A';
    }
}

int
main() {
    size_t i;
    printf("Hello World\r\n");

    /* Process all bytes */
    for (i = 0; i < sizeof(data) / sizeof(data[0]); i++) {
        /* Generate it twice, for high and low nibble */
        output[2 * i] = num2char((data[i] >> 4) & 0x0F);
        output[2 * i + 1] = num2char((data[i]) & 0x0F);
    }
    /* Trailing zero for string */
    output[2 * i] = 0;

    printf("Output: %s\r\n", output);

    return 0;
}

Когда вы запускаете код:

Output: 121314005A  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...