串口应用编程

#include  <time.h>
#include  <stdio.h>      /*标准输入输出定义*/
#include  <stdlib.h>     /*标准函数库定义*/
#include  <unistd.h>     /*Unix 标准函数定义*/
#include  <sys/types.h>  
#include  <sys/stat.h>   
#include  <fcntl.h>      /*文件控制定义*/
#include  <termios.h>    /*PPSIX 终端控制定义*/
#include  <errno.h>      /*错误号定义*/
#include  <poll.h> 
#include  <pthread.h>
#include  <semaphore.h>
#include  <netdb.h>
#include  <sys/types.h>
#include  <sys/time.h>
#include  <pthread.h>

#define FALSE 0
#define TRUE  1

#define COM1 "/dev/ttySAC1"
#define COM2 "/dev/ttySAC2"
#define COM3 "/dev/ttySAC3"

#define INFTIM        -1


int speed_arr[]={B38400,B19200,B9600,B4800,B2400,B1200,B300,B38400,B19200,B9600,B4800,B2400,B1200,B300,B115200};
int name_arr[] ={38400,19200,9600,4800,2400,1200,300,38400,19200,9600,4800,2400,1200,300,115200};

pthread_mutex_t mutex_rx_thread   =PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond_rx_thread     =PTHREAD_COND_INITIALIZER;


//设置数据位,停止位,校验位
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:
			return (FALSE);
	}

	//设置奇偶校验
	switch (parity){
		case 'n':
		case 'N':
			options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /*Input*/
			options.c_oflag &= ~OPOST;   /*Output*/
			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:
			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')&&(parity != 'N'))
		options.c_iflag |= INPCK;

	options.c_cc[VTIME] = 5; // 0.5 seconds
	options.c_cc[VMIN] = 1;


	options.c_cflag &= ~HUPCL;
	options.c_iflag &= ~INPCK;
	options.c_iflag |= IGNBRK;
	options.c_iflag &= ~ICRNL;
	options.c_iflag &= ~IXON;
	options.c_lflag &= ~IEXTEN;
	options.c_lflag &= ~ECHOK;
	options.c_lflag &= ~ECHOCTL;
	options.c_lflag &= ~ECHOKE;
	options.c_oflag &= ~ONLCR;


	//刷新
	tcflush(fd,TCIFLUSH); 
	if (tcsetattr(fd,TCSANOW,&options) != 0){
		return (FALSE);
	}

	return (TRUE);
}

//设置波特率
int set_speed(int fd,int speed)
{
	struct termios opt;
	int i;
	int status;
	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 -1;
			}
			tcflush(fd,TCIOFLUSH);
		}
	}

	if(tcgetattr(fd,&opt)!=0){
		return -1;
	}
}

//初始化物理层
int init_serial(char *pSerial)
{
	int ret;
	int len;
	int fd;
	
	printf("init_serial now,com:%s\r\n",pSerial);
	//打开COM口
	fd=open(pSerial,O_RDWR|O_NOCTTY);
	if(fd<0){
		printf("open the file errno: the errno=%d\r\n",errno);
		return -1;
	}

	printf("fd:%d\r\n");

	//设置数据位
	if(set_parity(fd,8,1,'N')<0){
		printf("set_Parity failed :the errno=%d\r\n",errno);
		return -1;
	}
	//LOGD("set_Parity success;");


	//设置波特率
	if(set_speed(fd,115200)<0){
		printf("set_speed failed : the errno=%d",errno);
		return -1;
	}

	printf("init serial finish\r\n");

	return fd;
} 

//接收COM数据线程
void rx_thread(int *arg)
{
	int	len;	
	int nfd=1;
	int i;
	int j;
	int fd = *arg;
	char serial_buffer[1000];
	int serial_buffer_pos;

	
	struct pollfd pfd[1];
	pfd[0].fd = fd;
	pfd[0].events = POLLIN;

	printf("create rx_thread succeed \r\n");  
	while(1){  	

		//pthread_mutex_lock(&mutex_rx_thread);		
		//pthread_cond_wait(&cond_rx_thread,&mutex_rx_thread);
		//pthread_mutex_unlock(&mutex_rx_thread);

		tcflush(fd,TCIFLUSH );
		while(1){
			if (poll(pfd,nfd,INFTIM)> 0){
				if(pfd[0].revents){
					len = read(fd,&serial_buffer[serial_buffer_pos],1000);
					if(len<0){
						printf("RXThread:read the data failed,the errno=%d\r\n",errno);
						return;
					}
					else if (len>0){

						//LOGE("RXThread:read len=%d",len);
						serial_buffer[serial_buffer_pos+len]=0;
						printf("%s",&serial_buffer[serial_buffer_pos]);
						if (serial_buffer_pos>900){
							printf("[RXThread] Exceed FIFOPKT_MAX_SIZE\r\n ");
							tcflush(fd,TCIFLUSH );
							continue;
						}
					}
				}
			}
		}
		//LOGE("out the while loop");
	}
}

int main(int argc, char **argv){
	int fd,ret;
	int byte_write=0;
	int thread_id;
	char *msg = "hello world\r\n";

	fd=init_serial(COM2);
	if(fd<0){
		printf("init serial failed!!\r\n");
		return -1;
	}

	printf("init serial success!!\r\n");

	byte_write=write(fd,msg,strlen(msg));
	
	printf("byte wirte :%d\r\n",byte_write);

	/*
	ret=pthread_create(&thread_id,NULL,(void*)rx_thread,(int*)&fd);
	if(ret!=0){
		printf("thread_id thread creat errno: the errno=%d\r\n",errno);
		return FALSE;
	}
	*/

	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值