UART通信C语言(Hex)



我想发送一个十六进制值给write函数。(例如,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("%xn",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("%xn",str);
bytes_read = read(fd,buffer,sizeof(buffer));
//  printf("%xn",*str);
if (bytes_read > 0)
{
buffer[bytes_read]=0;

printf("%pn", buffer);
}
usleep(100000);
//printf("%srn",buffer);      
}
close(fd);
return 0;

你只是想发送二进制而非文本数据,然而,不能以同样的方式处理二进制数据作为文本字符串0 (0 x00)是一个合法的二进制值,而它作为一个字符串结束符在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)将返回4,因为它将把0xA5, 0x80, 0x90, 0x08, 0x00作为您的字符串,具有4个数据字节和一个终止符。对于存储字符串的数组,必须允许在其中放置空终止符的额外字节。

你应该这样写:

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

计算数组中元素的个数。由于sizeof将返回被调整大小的项所占用的内存字节数(octet),因此还需要将其除以数组元素的大小来确定元素的数量。

char将返回大小为1,int在16位处理器上编译时可以返回大小为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

如果你想发送0x90的值,就像它是144的int值一样,你应该使用

unsigned char hex = 0x90

你可以发送值144

最新更新