C语言的UART通信(十六进制) [英] UART Communication In C language (Hex)

查看:53
本文介绍了C语言的UART通信(十六进制)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to send a hexadecimal value to the write function. (e.g., 0×90). This is because the device that needs to communicate receives commands in hexadecimal numbers. The unused variables appeared as they were tested and annotated to lose the hexadecimal value, and will be erased later. How can I write a write function with a hexadecimal value other than String?

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

For beginners, please tell us how to exchange hexadecimal values through read and write functions.

#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编译了代码,但是出现了这样的错误.

I set up transmission and reception variables and compiled the code using unsigned char, but such an error occurs.

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

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

If I use %p, there is no compilation error, but as you know, the address value is printed, so it is different from the result I want. I don't know how to do it because I'm a beginner.

修改部分如下.

    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
",str);
        bytes_read = read(fd,buffer,sizeof(buffer));

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

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

        //printf("%s
",buffer);      

    }
    close(fd);
    return 0;

推荐答案

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

You're just wanting to send binary rather than text data, however, binary data can't be handled in the same way as a text string as 0 (0x00) is a legitimate binary value whereas it acts as a string terminator in C. This is why protocols for binary data normally have a length indicator in one byte, if messages can be of variable length, or specific message delimiters (unique values at the start and end of the message that can't be repeated in the message data).

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

Pointers regarding your code: Always initialize values where possible, especially arrays into which you're going to store strings e.g. char buffer[2000] = {0} if the compiler allows otherwise memset(buffer, 0, sizeof(buffer); before using it.

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

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

There is an implicit cast here from a signed int to an unsigned char for the values that you are initializing your array with e.g. 0x90 is an int by default.

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

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

As pointed out 0x00 (null) is a legitimate binary value, but happens to be a text string terminator in C, therefore strlen(str) will return 4 as it will take 0xA5, 0x80, 0x90, 0x08, 0x00 as your string, with 4 data bytes and one terminator. For arrays storing strings you must allow for an extra byte into which the null terminator is placed.

你应该使用类似的东西:

Instead you should use something like:

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

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

This calculates the number of elements in the array. As sizeof will return the number of bytes (octets) of memory taken up by the item being sized we also need to divide that by the size of an array element to determine the number of elements.

char 将返回 1 的大小,int 在 16 位处理器上编译时可以返回 2,如果是 32 位,则返回 4 等等.

A char will return a size of 1, an int can return a size of 2 when compiled on a 16 bit processor, 4 if 32 bit etc.

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

Finally, you will need to cast your value that is being printed, so try using: (edit: code correction made)

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("
"); 

会给

A58090800000000BD

这篇关于C语言的UART通信(十六进制)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆