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

📄 mycom.c

📁 linux串口编程的一些文档以及一些示例
💻 C
字号:
/*	 本程序符合GPL条约 *	 Beneboy 2003-5-16*/#include <stdio.h>              // printf#include <fcntl.h>              // open#include <string.h>             // bzero#include <stdlib.h>             // exit#include <sys/times.h>          // times#include <sys/types.h>          // pid_t#include <termios.h>		//termios, tcgetattr(), tcsetattr()#include <unistd.h>#include <sys/ioctl.h>          // ioctl#include "MyCom.h"#define	TTY_DEV	"/dev/ttyS"	//端口路径//接收超时#define TIMEOUT_SEC(buflen,baud) (buflen*20/baud+2)#define TIMEOUT_USEC 0/******************************************* *	获得端口名称********************************************/char *get_ptty(pportinfo_t pportinfo){	char *ptty;	switch(pportinfo->tty){		case '0':{			ptty = TTY_DEV"0";		}break;		case '1':{			ptty = TTY_DEV"1";		}break;		case '2':{			ptty = TTY_DEV"2";		}break;	}	return(ptty);}/******************************************* *	波特率转化转换函数********************************************/int convbaud(unsigned long int baudrate){	switch(baudrate){		case 2400:			return B2400;		case 4800:			return B4800;		case 9600:			return B9600;		case 19200:			return B19200;		case 38400:			return B38400;		case 57600:			return B57600;		case 115200:			return B115200;		default:			return B9600;	}}/******************************************* *	Setup comm attr *	fdcom: 串口文件描述符, pportinfo: 待设置的端口信息s *********************************************/int PortSet(int fdcom, const pportinfo_t pportinfo){	struct termios termios_old, termios_new;	int 	baudrate, tmp;	char	databit, stopbit, parity, fctl;	bzero(&termios_old, sizeof(termios_old));	bzero(&termios_new, sizeof(termios_new));	cfmakeraw(&termios_new);	tcgetattr(fdcom, &termios_old);			//get the serial port attributions	/*------------设置端口属性----------------*/	//baudrates	baudrate = convbaud(pportinfo -> baudrate);	cfsetispeed(&termios_new, baudrate);		//填入串口输入端波特率	cfsetospeed(&termios_new, baudrate);		//填入串口输出端波特率	termios_new.c_cflag |= CLOCAL;			//控制模式, 保证程序不会成为端口的占有者	termios_new.c_cflag |= CREAD;			//控制模式, 使能端口读取输入的数据	// 控制模式, flow control	fctl = pportinfo-> fctl;	switch(fctl){		case '0':{			termios_new.c_cflag &= ~CRTSCTS;		//no flow control		}break;		case '1':{			termios_new.c_cflag |= CRTSCTS;			//hardware flow control		}break;		case '2':{			termios_new.c_iflag |= IXON | IXOFF |IXANY;	//software flow control		}break;	}	//控制模式, data bits	termios_new.c_cflag &= ~CSIZE;		//控制模式, 屏蔽字符大小位	databit = pportinfo -> databit;	switch(databit){		case '5':			termios_new.c_cflag |= CS5;		case '6':			termios_new.c_cflag |= CS6;		case '7':			termios_new.c_cflag |= CS7;		default:			termios_new.c_cflag |= CS8;	}	//控制模式 parity check	parity = pportinfo -> parity;	switch(parity){		case '0':{			termios_new.c_cflag &= ~PARENB;		//no parity check		}break;		case '1':{			termios_new.c_cflag |= PARENB;		//odd check			termios_new.c_cflag &= ~PARODD;		}break;		case '2':{			termios_new.c_cflag |= PARENB;		//even check			termios_new.c_cflag |= PARODD;		}break;	}	//控制模式, stop bits	stopbit = pportinfo -> stopbit;	if(stopbit == '2'){		termios_new.c_cflag |= CSTOPB;	//2 stop bits	}	else{		termios_new.c_cflag &= ~CSTOPB;	//1 stop bits	}	//other attributions default	termios_new.c_oflag &= ~OPOST;			//输出模式, 原始数据输出	termios_new.c_cc[VMIN]  = 1;			//控制字符, 所要读取字符的最小数量	termios_new.c_cc[VTIME] = 1;			//控制字符, 读取第一个字符的等待时间, 	unit: (1/10)second	tcflush(fdcom, TCIFLUSH);			//溢出的数据可以接收,但不读	tmp = tcsetattr(fdcom, TCSANOW, &termios_new);	//设置新属性, TCSANOW: 所由改变立即生效	tcgetattr(fdcom, &termios_old);	return(tmp);}/******************************************* *	Open serial port *	tty: 端口号 ttyS0, ttyS1, .... *	返回值为串口文件描述符********************************************/int PortOpen(pportinfo_t pportinfo){	int fdcom;	//串口文件描述符	char *ptty;	ptty = get_ptty(pportinfo);	//fdcom = open(ptty, O_RDWR | O_NOCTTY | O_NONBLOCK | O_NDELAY);	fdcom = open(ptty, O_RDWR | O_NOCTTY | O_NONBLOCK);	return (fdcom);}/******************************************* *	Close serial port********************************************/void PortClose(int fdcom){	close(fdcom);}/******************************************** *	send data *	fdcom: 串口描述符, data: 待发送数据, datalen: 数据长度 *	返回实际发送长度*********************************************/int PortSend(int fdcom, char *data, int datalen){	int len = 0;	len = write(fdcom, data, datalen);	//实际写入的长度	if(len == datalen){		return (len);	}	else{		tcflush(fdcom, TCOFLUSH);		return -1;	}}/******************************************* *	receive data *	返回实际读入的字节数 *********************************************/int PortRecv(int fdcom, char *data, int datalen, int baudrate){	int readlen, fs_sel;	fd_set	fs_read;	struct timeval tv_timeout;	FD_ZERO(&fs_read);	FD_SET(fdcom, &fs_read);	tv_timeout.tv_sec = TIMEOUT_SEC(datalen, baudrate);	tv_timeout.tv_usec = TIMEOUT_USEC;	fs_sel = select(fdcom+1, &fs_read, NULL, NULL, &tv_timeout);	if(fs_sel){		readlen = read(fdcom, data, datalen);		return(readlen);	}	else{		return(-1);	}	return (readlen);}//*************************Test*********************************/*int main(int argc, char *argv[]){	int fdcom, i, SendLen, RecvLen;	struct termios termios_cur;	char RecvBuf[10];	portinfo_t portinfo ={		'0',                          // print prompt after receiving 		115200,                       // baudrate: 9600 		'8',                          // databit: 8 		'0',                          // debug: off 		'0',                          // echo: off 		'2',                          // flow control: software 		'0',                          // default tty: COM1 		'0',                          // parity: none 		'1',                          // stopbit: 1 		 0    	                      // reserved	};	if(argc != 2){		printf("Usage: <type 0 -- send 1 -- receive>\n");		printf("   eg:");		printf("        MyPort 0");		exit(-1);	}	fdcom = PortOpen(&portinfo);	if(fdcom<0){		printf("Error: open serial port error.\n");		exit(1);	}	PortSet(fdcom, &portinfo);	if(atoi(argv[1]) == 0){		//send data		for(i=0; i<1000; i++){			SendLen = PortSend(fdcom, "1234567890", 10);			if(SendLen>0){				printf("No %d send %d data 1234567890.\n", i, SendLen);			}			else{				printf("Error: send failed.\n");			}			sleep(1);		}		PortClose(fdcom);	}	else{		for(;;){			RecvLen = PortRecv(fdcom, RecvBuf, 10, portinfo.baudrate);			if(RecvLen>0){				for(i=0; i<RecvLen; i++){					printf("Receive data No %d is %x.\n", i, RecvBuf[i]);				}				printf("Total frame length is %d.\n", RecvLen);			}			else{				printf("Error: receive error.\n");			}			sleep(2);		}	}	return 0;}*/

⌨️ 快捷键说明

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