Linux-循环读取UART串口数据编程

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>

#define FALSE -1
#define TRUE 0

int speed_arr[] = {
	B38400,
	B19200,
	B9600,
	B4800,
	B2400,
	B1200,
	B300,
	B38400,
	B19200,
	B9600,
	B4800,
	B2400,
	B1200,
	B300,
};
int name_arr[] = {
	38400,
	19200,
	9600,
	4800,
	2400,
	1200,
	300,
	38400,
	19200,
	9600,
	4800,
	2400,
	1200,
	300,
};
void set_speed(int fd, int speed)
{
	int i;
	int status;
	struct termios Opt;
	tcgetattr(fd, &Opt);
	for (i = 0; i < sizeof(speed_arr) / sizeof(int); i++)
	{
		if (speed == name_arr[i])
		{
			tcflush(fd, TCIOFLUSH);
			cfsetispeed(&Opt, speed_arr[i]);
			cfsetospeed(&Opt, speed_arr[i]);
			status = tcsetattr(fd, TCSANOW, &Opt);
			if (status != 0)
			{
				perror("tcsetattr fd1");
				return;
			}
			tcflush(fd, TCIOFLUSH);
		}
	}
}

int set_Parity(int fd, int databits, int stopbits, int parity)
{
	struct termios options;
	if (tcgetattr(fd, &options) != 0)
	{
		perror("SetupSerial 1");
		return (FALSE);
	}
	options.c_cflag &= ~CSIZE;
	switch (databits)
	{
	case 7:
		options.c_cflag |= CS7;
		break;
	case 8:
		options.c_cflag |= CS8;
		break;
	default:
		fprintf(stderr, "Unsupported data size\n");
		return (FALSE);
	}
	switch (parity)
	{
	case 'n':
	case 'N':
		options.c_cflag &= ~PARENB; /* Clear parity enable */
		options.c_iflag &= ~INPCK;	/* Enable parity checking */
		break;
	case 'o':
	case 'O':
		options.c_cflag |= (PARODD | PARENB);
		options.c_iflag |= INPCK; /* Disnable parity checking */
		break;
	case 'e':
	case 'E':
		options.c_cflag |= PARENB; /* Enable parity */
		options.c_cflag &= ~PARODD;
		options.c_iflag |= INPCK; /* Disnable parity checking */
		break;
	case 'S':
	case 's': /*as no parity*/
		options.c_cflag &= ~PARENB;
		options.c_cflag &= ~CSTOPB;
		break;
	default:
		fprintf(stderr, "Unsupported parity\n");
		return (FALSE);
	}

	switch (stopbits)
	{
	case 1:
		options.c_cflag &= ~CSTOPB;
		break;
	case 2:
		options.c_cflag |= CSTOPB;
		break;
	default:
		fprintf(stderr, "Unsupported stop bits\n");
		return (FALSE);
	}
	/* Set input parity option */
	if (parity != 'n')
		options.c_iflag |= INPCK;
	tcflush(fd, TCIFLUSH);
	options.c_cc[VTIME] = 150;
	options.c_cc[VMIN] = 0; /* Update the options and do it NOW */
	if (tcsetattr(fd, TCSANOW, &options) != 0)
	{
		perror("SetupSerial 3");
		return (FALSE);
	}
	return (TRUE);
}

int main()
{
	printf("This program updates last time at %s   %s\n", __TIME__, __DATE__);
	printf("STDIO COM1\n");
	int fd;
	fd = open("/dev/ttyUSB0", O_RDWR);
	if (fd == -1)
	{
		perror("serialport error\n");
	}
	else
	{
		printf("open ");
		printf("%s", ttyname(fd));
		printf(" succesfully\n");
	}

	set_speed(fd, 115200);
	if (set_Parity(fd, 8, 1, 'N') == FALSE)
	{
		printf("Set Parity Error\n");
		exit(0);
	}
	/*char buf[] = "fe55aa07bc010203040506073d";    //发送数据
	write(fd, buf, 26);*/
	unsigned char buff[1];
	while (1)
	{
		if (read(fd, buff, 1) > 0)
		{
			printf("%#x ", buff[0]);    //打印接收数据 16进制
			buff[0] = '\0';
		}
		else
		{
			perror("read");
		}
	}
	close(fd);
	return 0;
}

踩坑记录:

注意波特率,数据位、停止位,校验位,要匹配上才能通信。

接收16进制数据一定要用unsigned char数据类型,要不然会数据越界。例如0xaa(10进制170,超过char的正数边界127),打印出来为0xffffffaa。

执行程序若串口连接成功,没有接收到数据。sudo打开minicom,则可以收到数据。

参考资料:

https://blog.csdn.net/duhui75/article/details/122578147

https://blog.csdn.net/qq_41786131/article/details/91637358

https://blog.csdn.net/weixin_43919932/article/details/102995408

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值