⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 commserial.c

📁 linux下串口的访问
💻 C
字号:
#include "CommSerial.h"


/******************************************************************************/

const int speed_arr[] = {B460800, B230400, B115200, B38400, B19200, B9600, B4800, B2400, B1200, B600, B300,};
const int name_arr[] = {460800, 230400, 115200, 38400, 19200, 9600, 4800, 2400, 1200, 600, 300,};

static HANDLE	g_hPort;

/*
 *	set baudrate
 */
int 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)
				return false;
			else			
				return true;			
		}		
	}

	return false;
}

/*
 *	set databits, stopbits and parity
 */
int set_parity(int fd, int databits, int stopbits, int parity)
{
	struct termios options;

	if (tcgetattr(fd, &options) != 0)	
		return false;	
	
	options.c_cflag &= ~CSIZE;
	
	/* set databits */

	switch (databits) 
	{
	case 7:
		options.c_cflag |= CS7;
		break;
	case 8:
		options.c_cflag |= CS8;
		break;
	default:	
		return false;
	}
	
	/* set parity */

	switch (parity)
	{
	case 'n':
	case 'N':
		options.c_cflag &= ~PARENB;
		options.c_iflag &= ~INPCK;
		break;
	case 'o':
	case 'O':
		options.c_cflag |= (PARODD | PARENB);
		options.c_iflag |= INPCK;
		break;
	case 'e':
	case 'E':
		options.c_cflag |= PARENB;
		options.c_cflag &= ~PARODD;
		options.c_iflag |= INPCK;
		break;	
	default:		
		return false;
	}
	
	/* set stopbits */

	switch (stopbits)
	{
	case 1:
		options.c_cflag &= ~CSTOPB;
		break;
	case 2:
		options.c_cflag |= CSTOPB;
		break;
	default:		
		return false;
	}
	
  	/* set input parity option */

	if (parity != 'n')
		options.c_iflag |= INPCK;

	options.c_cc[VTIME] = 150;	/* 15 seconds */
	options.c_cc[VMIN] = 0;
	
	/* add by baiwei */

	options.c_cflag |= (CLOCAL | CREAD);
	options.c_iflag &= ~(INLCR | ICRNL );
	options.c_iflag &= ~(IXON | IXOFF | IXANY );	
	options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
	options.c_oflag &= ~OPOST;
	
	tcflush(fd, TCIFLUSH);	/* update the options and do it now */

	if (tcsetattr(fd, TCSANOW,&options) != 0)	
		return false;

	return true;
}

/*
 *	open device file
*/
int openComDevFile(char* com, int* fd)
{
 	*fd = open(com, O_RDWR);	/*| O_NOCTTY | O_NDELAY */	
	if (-1 == *fd)
	{
		perror( "open serial error:" );
		return false;	
	}
	else
		return true;
}

/*
 *	receive thread
*/
void* RcvThrdProc(void* arg)
{		
	int			num;
	BYTE 			buf [512];
	SERIALPORTINFO* 	spi;
	
	spi = (SERIALPORTINFO*) arg;	

	while (1)
  	{		
   		while ((num = read(spi->fd, buf, sizeof(buf)/sizeof(BYTE) - 1)) > 0)
   		{
			spi->rcvTick++;
			buf [num] = 0;			
	      		if (spi->fnOnReceive)
				spi->fnOnReceive(spi->userData, buf, num);
   	 	}	
		
   	 	Sleep(10);
	}	
}



BOOL SerialPortIsOpen()
{
	SERIALPORTINFO* info = (SERIALPORTINFO*) g_hPort;
	if (info==NULL)
		return false;
	return info->isOpen;
}

int SerialPortOpen(SERIALPORT* sp, RCVCALLBACK fnOnReceive, void* userData,int mode)
{
	SERIALPORTINFO*	spi;
	int		fd;
	//char		dev [256];
	pthread_attr_t 	attr;

	g_hPort = malloc( sizeof(SERIALPORTINFO) );
	if (g_hPort==NULL)
		return 6;
	memset( g_hPort, 0, sizeof(SERIALPORTINFO) );

	spi = (SERIALPORTINFO*) g_hPort;

/*	if (sp->com == 1 || sp->com == 2)	
		sprintf(dev, "/dev/ttyS%d", sp->com - 1);	
	else	
		sprintf(dev, "/dev/ttyM%d", sp->com - 3);
*/
	//sprintf(dev, "/dev/usb/tts/%d", sp->com);	// 07.03.2008
	//printf("Input serial port(/dev/usb/tts/): ");
	//scanf( "%s", dev);

	//strcpy( dev, sp->scom );

	if (false == openComDevFile(sp->scom, &fd))	
		return -1;
	
	//printf("serial fd:%d\n", fd);

// rs232/422/485
//	ioctl(fd, 0x9000, &mode);
//	set_link_mode(sp->com,mode);


	if (false == set_speed(fd, sp->baudrate))
	{
		close(fd);
		perror("set_speed error");
		return -2;
	}

	if (false == set_parity(fd, sp->databits, sp->stopbits, sp->parity))
	{		
		close(fd);
		perror("set_parity error");
		return -3;
	}

	spi->fd			= fd;
	spi->fnOnReceive	= fnOnReceive;
	spi->userData		= userData;	
	
	pthread_attr_init(&attr);	
	pthread_attr_setschedpolicy(&attr, 1);	

	if (pthread_create(&spi->tid, &attr, RcvThrdProc, spi) != 0)
	{		
		close(fd);
		return -4;
	}
	
	if (pthread_detach(spi->tid) != 0)
	{		
		close(fd);

		/* to add */

		return -5;
	}
	
	spi->isOpen	= true;	
	
	return 0;
}

void SerialPortClose()
{
	SERIALPORTINFO* spi = (SERIALPORTINFO*) g_hPort;

	if ( spi==NULL )
		return;
	if (spi->isOpen)
	{
		/* to add */
		close(spi->fd);
		spi->isOpen = false;		
	}
	free( g_hPort );
}

int SerialPortSend(BYTE* buf, int len)
{	
	SERIALPORTINFO*	spi;
	int		writeNum;

	if ( buf==NULL || len<=0 )
		return -1;
	
 	spi		= (SERIALPORTINFO*) g_hPort;
	writeNum	= 0;

	//printf("spi->isOpen:%d, spi->fd:%d\n", spi->isOpen, spi->fd);
	if (spi->isOpen)
		writeNum = write(spi->fd, buf, len);	
	if ( writeNum<=0 )
		perror("send data to serial error:");

	return writeNum;	
}

void SerialPortSetRcvTicker(UINT tick)
{
	SERIALPORTINFO* info = (SERIALPORTINFO*) g_hPort;
	info->rcvTick = tick;	
}

UINT SerialPortGetRcvTicker()
{
	SERIALPORTINFO* info = (SERIALPORTINFO*) g_hPort;
	return info->rcvTick;	
}

static BOOL IsBadWritePtr(void* ptr, int len)
{
	if (ptr == NULL)
		return TRUE;
	return FALSE;
}

static BOOL IsBadStringPtr(void* ptr, int len)
{
	if (ptr == NULL)
		return TRUE;
	return FALSE;
}

static int find_char(char* string, char ch, int* pos, int sizePosBuf)
{
	char*	head = string;
	char*	dest = NULL;	
	int	len = strlen(string);	
	int	n = 0;
	while ((dest = strchr(head, ch)) != NULL)
	{
		if (n > sizePosBuf - 1)
			break; 
		if ((pos[n++] = dest - string) == len - 1)
			break;
		else
			head = dest + 1;
	}
	return n;
}

int ParseSerialCommParaStr(char* para, SERIALPORT* port)
{	
	int len, commaPos[10];
	char tmp[64] = {0};

	if ( para==NULL || port==NULL )
		return 6;
	
	if (IsBadStringPtr(para, 1) || IsBadWritePtr(port, sizeof(SERIALPORT)))
		return 1;
	
	len = strlen(para);

	if (len >= 64)
		return 3;  
	if (4 != find_char(para, ',', commaPos, 10))
		return 4;
	
	memcpy( port->scom, para, commaPos[0]);
	Pt("port->scom=%s\n", port->scom);
	//port->com = atoi(tmp);

	memset(tmp, 0, 64);
	memcpy(tmp, para + commaPos[0] + 1, commaPos[1] - commaPos[0] - 1);
	port->baudrate = atoi(tmp);
	memset(tmp, 0, 64);
	memcpy(tmp, para + commaPos[1] + 1, commaPos[2] - commaPos[1] - 1);
	port->databits = atoi(tmp);
	memset(tmp, 0, 64);
	memcpy(tmp, para + commaPos[2] + 1, commaPos[3] - commaPos[2] - 1);
	port->stopbits = atoi(tmp);
	memset(tmp, 0, 64);
	strcpy(tmp, para + commaPos[3] + 1);
	if (tmp[0] == 'n' || tmp[0] == 'N' || tmp[0] == 'o' || tmp[0] == 'O' || tmp[0] == 'e' || tmp[0] == 'E')
		port->parity = tmp[0];
	else	
		return 5;
	return 0; 
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -