读串口小程序 serialport-read.c

本文介绍了一个简单的串口通信程序实现方法,包括串口参数设置、打开串口、读取数据等关键步骤,并展示了如何验证接收到的数据正确性。
#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>
#include	<string.h>

#define		TRUE	1
#define		FALSE	0

#define		BUFFER_SIZE		1024 * 10

// for AM3517 ttyS2 is available. //ttyUSB0

//#define		DEVICE_FILE		"/dev/ttyS0"



int set_opt(int fd, int nSpeed, int nBits, char nEvent, int nStop)
{
	struct termios newtio, oldtio;
	if(tcgetattr(fd, &oldtio) != 0)
	{
		perror("SetupSerial 1");
		return -1;
	}
	bzero(&newtio, sizeof(newtio));
	newtio.c_cflag |= CLOCAL | CREAD;
	newtio.c_cflag &= ~CSIZE;
	switch(nBits)
	{
		case 7:
				newtio.c_cflag |= CS7;
				break;
		case 8:
				newtio.c_cflag |= CS8;
				break;
	}
	switch(nEvent)
	{
		case 'O':
				newtio.c_cflag |= PARENB ;
				newtio.c_cflag |= PARODD ;
				newtio.c_iflag |= (INPCK | ISTRIP);
				break;
		case 'E':
				newtio.c_cflag |= PARENB ;
				newtio.c_cflag &= ~PARODD ;
				newtio.c_iflag |= (INPCK | ISTRIP);
				break;
		case 'N':
				newtio.c_cflag &= ~PARENB ;
				break;
	}
	switch(nSpeed)
	{
		case 4800:
				cfsetispeed(&newtio, B4800);
				cfsetospeed(&newtio, B4800);
				break;
		case 9600:
				cfsetispeed(&newtio, B9600);
				cfsetospeed(&newtio, B9600);
				break;
		case 19200:
				cfsetispeed(&newtio, B19200);
				cfsetospeed(&newtio, B19200);
				break;
		case 57600:
				cfsetispeed(&newtio, B57600);
				cfsetospeed(&newtio, B57600);
				break;
		case 115200:
				cfsetispeed(&newtio, B115200);
				cfsetospeed(&newtio, B115200);
				break;
		default:
				cfsetispeed(&newtio, B115200);
				cfsetospeed(&newtio, B115200);
				break;
	}
	if(1 == nStop)
		newtio.c_cflag &= ~CSTOPB;
	else if(2 == nStop)
		newtio.c_cflag |= CSTOPB;
	newtio.c_cc[VTIME] = 0;
	newtio.c_cc[VMIN] = 1;
	tcflush(fd, TCIFLUSH);
	if((tcsetattr(fd, TCSANOW, &newtio))!=0)
	{
		perror("com set error!");
		return -1;
	}

	return 0;
}


int main(int argc, char **argv)
{
//	const char package[] = "abcdefghijklmnopqrstuvwxyz1234567890";
	char package[32] = "";
	
	char device[] = "/dev/ttyS0";
	int baud_rate = 115200;
	int data_bit = 8;
	int stop_bit = 1;
	char parity = 'N';		
	
	int fd;
	int nread, nwrite;
	int ret;

	char recv_buf[BUFFER_SIZE];
	char total_buf[BUFFER_SIZE];
	
	long total_bytes, total_packages;
	
	int pos, len_package;

	if(argc == 1)
	{
		printf("Usage: %s <device> <checkstring>.\n", argv[0]);
		printf("   eg. %s /dev/ttyS0 abcde12345\n", argv[0]);
		return 0;
	}

/*
	if(argc == 2 && strcmp(argv[1], "-h") == 0)
	{
		printf("Supported Baud Rate: 115200, 57600, 19200,9600,4800\n");
		return 0;
	}
*/

/*
	if(argc == 3 && strcmp(argv[1], "-b") == 0)
	{
		baud_rate = atoi(argv[2]);
	}
*/

	strcpy(device, argv[1]);
	strcpy(package, argv[2]);

	printf("device=%s,baud_rate=%d,data_bit=%d,stop_bit=%d,parity=%c\n", device, baud_rate, data_bit, stop_bit, parity);

	// open
	fd = open(device, O_RDWR|O_NOCTTY|O_NDELAY);
	if(-1 == fd)
	{
		perror("Can't open Serial Port");
		return -1;
	}
	if(fcntl(fd, F_SETFL, 0)<0)
	{
		printf("fcntl failed!\n");
		return -1;
	}
	
	// set 
	ret = set_opt(fd, baud_rate, data_bit, parity, stop_bit);
	if(ret < 0)
	{
		perror("Set_opt error!");
		return;
	}	
	
	pos = 0;	
	total_bytes = 0;
	total_packages = 0;
	
	len_package = strlen(package);
	

	while(1)
	{
		nread = read(fd, recv_buf, sizeof(recv_buf));
		if(nread > 0)
		{
			total_bytes += nread;
		
			printf("Total Bytes = %ld\n", total_bytes);
		
			memcpy(total_buf + pos, recv_buf, nread);
			pos += nread;
		
			while(pos >= len_package)
			{
				if(memcmp(package, total_buf, len_package) == 0)
				{
					total_packages++;
					memmove(total_buf, total_buf +len_package, pos - len_package);
					pos -= len_package;
					printf("Total Packages = %ld\n", total_packages);			
				}
				else
				{
					printf("Error - Inconsistent Data!\n");
					return 1;
				}
			}
		}
		else if(nread < 0)
		{
			perror("read error");
			break;
		}
		
	}

    close(fd);
    return 0;
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值