使用多路复用实现3个串口的通信

如题,Linux环境下操作串口设备,实现多路复用。

串口配置函数:

/*
 * set_com_config.c
 *
 *  Created on: 2012-7-18
 *      Author: liwei.cai
 */
#include <termios.h>
int set_com_config(int fd, int baud_rate,
		int data_bits, char parity, int stop_bits)
{
	struct termios new_cfg, old_cfg;
	int speed;

	//保存并测试现在有串口参数设置,在这里如果串口号等出错,会有相关的出错信息
	if(tcgetattr(fd, &old_cfg) != 0)
	{
		perror("tcgetattr");
		return -1;
	}
	//设置字符大小
	new_cfg = old_cfg;
	cfmakeraw(&new_cfg);//配置为原始模式
	new_cfg.c_cflag &= ~CSIZE;

	//设置波特率
	switch(baud_rate)
	{
		case 2400:
		{
			speed = B2400;
		}
		break;
		case 4800:
		{
			speed = B4800;
		}
		break;
		case 9600:
		{
			speed = B9600;
		}
		break;
		case 19200:
		{
			speed = B19200;
		}
		break;
		case 38400:
		{
			speed = B38400;
		}
		break;
		default:
		case 115200:
		{
			speed = B115200;
		}
		break;
	}
	cfsetispeed(&new_cfg, speed);
	cfsetospeed(&new_cfg, speed);

	//设置数据位
	switch(data_bits)
	{
		case 7:
		{
			new_cfg.c_cflag |=CS7;
		}
		break;
		default:
		case 8:
		{
			new_cfg.c_cflag |=CS8;
		}
		break;
	}

	//设置奇偶校验位
	switch(parity)
	{
		default:
		case 'n':
		case 'N':
		{
			new_cfg.c_cflag &= ~PARENB;
			new_cfg.c_iflag &= ~INPCK;
		}
		break;

		case 'o':
		case 'O':
		{
			new_cfg.c_cflag |= (PARODD | PARENB);
			new_cfg.c_iflag |= INPCK;
		}
		break;
		case 'e':
		case 'E':
		{
			new_cfg.c_cflag |= PARENB;
			new_cfg.c_iflag &= ~PARODD;
			new_cfg.c_cflag |= INPCK;
		}
		break;

		case 's':
		case 'S':
		{
			new_cfg.c_cflag &= ~PARENB;
			new_cfg.c_iflag &= ~CSTOPB;
		}
		break;
	}

	//设置停止位
	switch(stop_bits)
	{
	default:
	case 1:
	{
		new_cfg.c_iflag &= ~CSTOPB;
	}
	break;

	case 2:
		new_cfg.c_iflag |= CSTOPB;
		break;
	}
	//设置等待时间和最小接受字符
	new_cfg.c_cc[VTIME] = 0;
	new_cfg.c_cc[VMIN] = 1;

	//处理未接受字符
	tcflush(fd, TCIFLUSH);
	//激活新配置
	if ((tcsetattr(fd, TCSANOW, &new_cfg)) != 0)
	{
		perror("tcsetattr");
		return -1;
	}
	return 0;
}
读取串口函数:

/*
 * open_port.c
 *
 *  Created on: 2012-7-18
 *      Author: liwei.cai
 */
//#include <termio.h>
//打开串口函数
int open_port(int com_port)
{
	int fd;
#if (COM_TYPE == GNR_COM) //使用普通串口
	char *dev[] = {"/dev/ttyS0", "/dev/ttyS1", "/dev/ttyS2"};
#else //使用USB转串口
	char *dev[] = {"/dev/ttyUSB0", "/dev/ttyUSB1", "/dev/ttyUSB2"};
#endif
	if ((com_port < 0) || (com_port > MAX_COM_NUM))
	{
		return -1;
	}
	//打开串口
	fd = open(dev[com_port -1], O_RDWR|O_NOCTTY|O_NDELAY);
	if(fd < 0)
	{
		perror("open serial port");
		return -1;
	}
	//恢复串口为阻塞状态
	if(fcntl(fd, F_SETFL, 0) < 0)
	{
		perror("fcntl F_SETFL\n");
	}
	//测试是否为终端设备
	if(isatty(STDIN_FILENO) == 0)
	{
		perror("standard input is not a terminal device");
	}
	return fd;
}
相关头文件:

/*
 * uart_api.h
 *
 *  Created on: 2012-7-18
 *      Author: liwei.cai
 */

#ifndef UART_API_H_
#define UART_API_H_

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

#define BUFFER_SIZE 1024
#define HOST_COM_PORT 1
#define TARGET_COM_PORT 2
#define MAX_COM_NUM 3

#include "open_port.c"
#include "set_com_config.c"


#endif /* UART_API_H_ */

功能主函数:

/*
 * main.c
 *
 *  Created on: 2012-7-19
 *      Author: liwei.cai
 */
#include <poll.h>
#include "uart_api.h"
int main(void)
{
	struct pollfd fds[MAX_COM_NUM];
	char buf[BUFFER_SIZE];
	int i, res, real_read, maxfd;

	//首先按照一定的权限打开两个源文件

	if((fds[0].fd = open_port(COM_1)) < 0) //串口1 接受数据
	{
		printf("Open COM1 error!\n");
		return 1;
	}
	if (set_com_config(fds[0].fd,115200, 8, 'N', 1) < 0)//配置串口1
	{
		perror("set_com_config3");
		return 1;
	}

	if((fds[1].fd = open_port(COM_2)) < 0)
	{
		printf("Open COM2 error!\n");
		return 1;
	}
	if (set_com_config(fds[1].fd,115200, 8, 'N', 1) < 0)//配置串口2
	{
		perror("set_com_config3");
		return 1;
	}

	if((fds[2].fd = open_port(COM_3)) < 0)
	{
		printf("Open COM3 error!\n");
		return 1;
	}
	if (set_com_config(fds[2].fd,115200, 8, 'N', 1) < 0)//配置串口3
	{
		perror("set_com_config3");
		return 1;
	}

	//取出两个文件描述符中的较大者
	for(i = 0; i < MAX_COM_NUM; i++)
	{
		fds[i].events = POLLIN;
	}
	//循环测试该文件描述符是否准备就绪,并调用select函数对象相关文件描述符做对应操作
	while(fds[0].events || fds[1].events
			|| fds[2].events)
	{
		if(poll(fds, MAX_COM_NUM,0) < 0)
		{
			printf("Poll error!\n");
			return 1;
		}
		for (i = 0; i < MAX_COM_NUM; i++)
		{
			if (fds[i].revents)
			{
				memset(buf, 0, BUFFER_SIZE);
				real_read = read (fds[i].fd, buf, BUFFER_SIZE);
				if (real_read < 0)
				{
					if (errno != EAGAIN)
					{
						return 1;
					}
				}
				else if (!real_read)
				{
					close(fds[i].fd);
					fds[i].events = 0;
				}
				else
				{
					buf[real_read] = '\0';
					//printf("%s", buf);
					if (i == 0)
					{
						write(fds[1].fd, buf, strlen(buf));
						write(fds[2].fd, buf, strlen(buf));
					}
					else
					{
						write(fds[0].fd, buf, strlen(buf));
					}

					if ((buf[0] == 'q') || (buf[0] == 'Q'))
					{
						return 1;
					}
				}// end of if real_read
			} //end of if revents
		} //end of for
	} //end of while
	return 0;
}





  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
串口控制12路晶体管输出板JMDM-28DIOMT串口控制器rar,串口控制12路继电器(晶体管)输出板 28点工业级高可靠单片机控制板 RS232串口控制器 步进电机控制器 继电器气缸电磁阀控制器 精密转速控制 精密运动控制 精密机械加工控制器 包括晶体管输出(JMDM-28DIOMT)和继电器输出(JMDM-28DIOMR)两种本产品研发制造商:深圳市精敏数字机器有限公司一、特性1.8位高性能单片机作为主控制芯片,64K程序存储器,也可以用来保存数据,断电数据不丢失;2.16路光电隔离数字量输入,NPN输入形式,输入电流为10mA;其中有两路可作中断源用于计数;3.工作电源:JMDM-28DIOMR: 12V交流电或直流电,标准功率为10W;JMDM-28DIOMT:9V交流电,外围驱动电源:12V或24V交流电。4.输出形式:JMDM-28DIOMR:12路继电器输出,输出电压为0~220V,最大输出电流为5A, 输出口状态可回读;JMDM-28DIOMT:12路光电隔离数字量输出,集电极开路输出形式,输出电压为24/12V,最大输出电流为1A, 输出口状态可回读;5.系统采用光电隔离和启用内部看门狗及严格的高频滤除特性,使系统工作稳定可靠,无死机现象;6.有两盏LED灯显示工作状态,LED灯和拨码开关是复用的,也可用来设置两个参数;7.有1路标准的RS232串行通信接口(抗15KV静电冲击),可直接与电脑或触摸屏等外设通信;8.可直接通过RS232接口下载程序,无需烧录器,方便程序修改、升级;9.紧凑型 (适合任何尺寸的机箱) ,PCB尺寸:155mm*110mm;10.用Keil C 或汇编编程;二、规格 1.工作温度:-10~ 65°C;2.储存温度:-20~ 80°C ;3.湿度:5~95% 无凝结 ;4.功耗(无外部设备): [email protected](典型值) ;三、用途1.可用于各种28个点以内的控制系统,可控制气缸,电磁阀,继电器,步进电机,可外接光电式,电容式,电感式,霍尔式等各种传感器;2.可用于替代28点以内的PLC用于各种控制场合(如各种机器控制);3.可用于单片机学习和试验。四、JMDM-28DIOMR/MT应用:JMDM-28DIOMR/MT以其出色的多功能、稳定可靠性、高性价比,成为业内广受客户喜爱的一款28点单片机控制器,广泛应用在多种场合。(一)可采用RS232串口控制步进电机等应用;步进电机控制应用案例如下:1、串口通讯自动化设备2、自动化质量检测仪3、生产线智能检测系统4、定长控制系统5、候车岗亭广告牌自动切换系统6、精密转速控制、精密运动控制、精密机械加工等场合。(二)可采用RS-485总线作为各个控制板之间的通信载体,最多可由255个控制板构成一个由4080个输入点,3060个输出点的大系统;可采用电脑或主PLC作为主控制单元。RS-485 总线型远程测控系统应用案例如下:1、用于各种集散型控制系统;2、用于各种远程测控系统;3、可用于灯光控制,电厂控制,自动化车间的大中型控制项目;4、可用作远程IO模块;5、可用于电脑集中控制。更多产品详细资料,欢迎垂询:电话:0755- 29769287;13427969290 陶小姐;传真:0755-29958512 E-mail:[email protected];QQ: 957302591 MSN:[email protected]; 阿里旺旺:jingminsz阿里巴巴网上店:http://china.alibaba.com/company/detail/jingminsz.html公司网址:www.jingmindm.com 中华工控网店铺:http://www.gkong.com/comm/userdetail.asp?id=66456
JMDM-28DIOMR串口控制器16路输入12路继电器输出rar,串口控制12路继电器(晶体管)输出板 28点工业级高可靠单片机控制板 RS232串口控制器 步进电机控制器 继电器气缸电磁阀控制器 精密转速控制 精密运动控制 精密机械加工控制器 包括晶体管输出(JMDM-28DIOMT)和继电器输出(JMDM-28DIOMR)两种本产品研发制造商:深圳市精敏数字机器有限公司一、特性1.8位高性能单片机作为主控制芯片,64K程序存储器,也可以用来保存数据,断电数据不丢失;2.16路光电隔离数字量输入,NPN输入形式,输入电流为10mA;其中有两路可作中断源用于计数;3.工作电源:JMDM-28DIOMR: 12V交流电或直流电,标准功率为10W;JMDM-28DIOMT:9V交流电,外围驱动电源:12V或24V交流电。4.输出形式:JMDM-28DIOMR:12路继电器输出,输出电压为0~220V,最大输出电流为5A, 输出口状态可回读;JMDM-28DIOMT:12路光电隔离数字量输出,集电极开路输出形式,输出电压为24/12V,最大输出电流为1A, 输出口状态可回读;5.系统采用光电隔离和启用内部看门狗及严格的高频滤除特性,使系统工作稳定可靠,无死机现象;6.有两盏LED灯显示工作状态,LED灯和拨码开关是复用的,也可用来设置两个参数;7.有1路标准的RS232串行通信接口(抗15KV静电冲击),可直接与电脑或触摸屏等外设通信;8.可直接通过RS232接口下载程序,无需烧录器,方便程序修改、升级;9.紧凑型 (适合任何尺寸的机箱) ,PCB尺寸:155mm*110mm;10.用Keil C 或汇编编程;二、规格 1.工作温度:-10~ 65°C;2.储存温度:-20~ 80°C ;3.湿度:5~95% 无凝结 ;4.功耗(无外部设备): [email protected](典型值) ;三、用途1.可用于各种28个点以内的控制系统,可控制气缸,电磁阀,继电器,步进电机,可外接光电式,电容式,电感式,霍尔式等各种传感器;2.可用于替代28点以内的PLC用于各种控制场合(如各种机器控制);3.可用于单片机学习和试验。四、JMDM-28DIOMR/MT应用:JMDM-28DIOMR/MT以其出色的多功能、稳定可靠性、高性价比,成为业内广受客户喜爱的一款28点单片机控制器,广泛应用在多种场合。(一)可采用RS232串口控制步进电机等应用;步进电机控制应用案例如下:1、串口通讯自动化设备2、自动化质量检测仪3、生产线智能检测系统4、定长控制系统5、候车岗亭广告牌自动切换系统6、精密转速控制、精密运动控制、精密机械加工等场合。(二)可采用RS-485总线作为各个控制板之间的通信载体,最多可由255个控制板构成一个由4080个输入点,3060个输出点的大系统;可采用电脑或主PLC作为主控制单元。RS-485 总线型远程测控系统应用案例如下:1、用于各种集散型控制系统;2、用于各种远程测控系统;3、可用于灯光控制,电厂控制,自动化车间的大中型控制项目;4、可用作远程IO模块;5、可用于电脑集中控制。更多产品详细资料,欢迎垂询:电话:0755- 29769287;13427969290 陶小姐;传真:0755-29958512 E-mail:[email protected];QQ: 957302591 MSN:[email protected]; 阿里旺旺:jingminsz阿里巴巴网上店:http://china.alibaba.com/company/detail/jingminsz.html公司网址:www.jingmindm.com 中华工控网店铺:http://www.gkong.com/comm/userdetail.asp?id=66456

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值