C语言串口通信(十六进制)

UART Communication In C language (Hex)

我想向写入函数发送一个十六进制值。 (例如,0×90)。 这是因为需要通信的设备以十六进制数接收命令。 未使用的变量在测试和注释时出现丢失十六进制值,稍后将被擦除。 我怎样才能写一个十六进制值而不是字符串的写函数?

对于初学者来说, 请告诉我们如何通过读写函数交换十六进制值。

#include <termios.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <time.h>
#include <pthread.h>

int main(void)
{
    int fd;
    fd=open("/dev/ttyHSL6", O_RDWR|O_NOCTTY );
    struct termios newtio;

    char buffer[2000];
    int bytes_read=0;
    char *data;
    //int *a=0x90;

    char *a="0X90";
    const int *num1;
    
    if (fd == -1)
    {
        printf("Error! in opening port");
        exit(-100);
    }

    memset(&newtio, 0, sizeof(struct termios));
    newtio.c_cflag = B9600 | CS8 | CLOCAL | CREAD;

    newtio.c_iflag = IGNPAR;

    newtio.c_oflag = 0;
    newtio.c_lflag = 0;
    newtio.c_cc[VTIME] = 0; 
    newtio.c_cc[VMIN] = 1; 
    tcflush(fd, TCIFLUSH);

    tcsetattr(fd, TCSANOW, &newtio);
    data=malloc(sizeof(char)*140);
    while(1){
        const char *str ="0x91";
        
        //write(fd, str, strlen(str)+1);

        bytes_read = read(fd,buffer,sizeof(buffer));

        if (bytes_read > 0)
        {
            buffer[bytes_read]=0;
            printf("%s", buffer);
        }
        usleep(100000);

        
    }
    close(fd);
    return 0;
}

当前进度:

我设置了发送和接收变量,使用unsigned char编译代码,却出现这样的错误

./serial.c:48:10: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 2 has type ‘unsigned char *’ [-Wformat=]
   printf("%x\n",str);

如果我用%p,没有编译错误,但是如你所知,打印的是地址值,所以和我想要的结果不一样。我是初学者,不知道怎么做。

修改部分如下

    while(1){
        //const char *str ="0x91";
        unsigned char str[13] = {0xA5,0x80,0x90,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xBD};
        write(fd, str, strlen(str));
        printf("%x\n",str);
        bytes_read = read(fd,buffer,sizeof(buffer));

    //  printf("%x\n",*str);
        if (bytes_read > 0)
        {
            buffer[bytes_read]=0;
            

            printf("%p\n", buffer);
        }
        usleep(100000);

        //printf("%s\r\n",buffer);      

    }
    close(fd);
    return 0;

如果您想像发送 int 值 144 一样发送 0x90 值,您应该使用

unsigned char hex = 0x90

用这个你可以发送值144

您只是想发送二进制数据而不是文本数据,但是二进制数据不能像文本字符串一样处理,因为 0 (0x00) 是合法的二进制值,而它充当C 中的字符串终止符。这就是为什么二进制数据的协议通常在一个字节中有一个长度指示符,如果消息可以是可变长度,或者特定的消息定界符(消息开头和结尾的唯一值,不能重复在消息数据中)。

关于您的代码的提示: 始终尽可能初始化值,尤其是要将字符串存储到的数组,例如char buffer[2000] = {0} 如果编译器允许,否则 memset(buffer, 0, sizeof(buffer); 在使用它之前。

    unsigned char str[13] = {0xA5,0x80,0x90,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xBD};

这里有一个从 signed intunsigned char 的隐式转换,用于初始化数组的值,例如0x90 默认是 int

    write(fd, str, strlen(str));

正如所指出的 0x00 (null) 是合法的二进制值,但恰好是 C 中的文本字符串终止符,因此 strlen(str) 将 return 4 因为它需要0xA5, 0x80, 0x90, 0x08, 0x00 作为您的字符串,具有 4 个数据字节和一个终止符。对于存储字符串的数组,您必须允许放置空终止符的额外字节。

相反,您应该使用类似的东西:

write(fd, str, sizeof(str)/sizeof(str[0]));

这将计算数组中元素的数量。由于 sizeof 将 return 被调整大小的项目占用的内存字节数(八位字节),我们还需要将其除以数组元素的大小以确定元素的数量。

A char 将 return 大小为 1,int 在 16 位处理器上编译时可以 return 大小为 2,如果在 32 位处理器上编译则为 4等等

最后,您需要转换正在打印的值,因此请尝试使用:(编辑:已进行代码更正)

unsigned char str[13] = {0xA5,0x80,0x90,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xBD};

for (int i=0; i< sizeof(str)/sizeof(str[0]); i++) 
{ 
    printf("%X",(int)str[i]); 
} 
printf("\n"); 

会给

A58090800000000BD