串口通信代码

来源:互联网 发布:mac老系统在哪下载 编辑:程序博客网 时间:2024/05/29 04:27

/*com_writer.c*/
#include "uart_api.h"

int main(void)
{
 int fd;
 char buff[BUFFER_SIZE];
 if((fd=open_port(HOST_COM_PORT))<0)  /*打开串口*/
 {
  perror("open serial error");
  return 1;
 }
 if(set_com_config(fd,115200,8,'N',1)<0) /*配置串口*/
 {
  perror("set_com_config error");
  return 1;
 }
 do
 {
  printf("Input some words(enter 'quit' to exit):");
  memset(buff,0,BUFFER_SIZE);
  if(fgets(buff,BUFFER_SIZE,stdin)==NULL)
  {
   perror("fgets");
   break;
  }
  write(fd,buff,strlen(buff));
 }while(strncmp(buff,"quit",4));
 close(fd);
 return 0;
 
}

 

/*com_reader.c*/
#include "uart_api.h"
#define COM_TYPE GNR_COM
int main(void)
{
 int fd;
 char buff[BUFFER_SIZE];
 if((fd=open_port(TARGET_COM_PORT))<0)
 {
  perror("open serial error");
  return 1;
 }
 if(set_com_config(fd,115200,8,'N',1)<0) /*配置串口*/
 {
  perror("set_com_config error");
  return 1;
 }
 do
 {
  memset(buff,0,BUFFER_SIZE);
  if(read(fd,buff,BUFFER_SIZE)>0)
  {
   printf("the receive words are:%s",buff);
  }
 }while(strncmp(buff,"quit",4));
 close(fd);
 return 0;
}

/*uart_api.h*/

#include<errno.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include <termios.h>
#include <fcntl.h>
#include <time.h>
#include <unistd.h>
#include <ctype.h>
#define HOST_COM_PORT 1
#define BUFFER_SIZE  4096
#define MAX_COM_NUM  5
#define TARGET_COM_PORT 1
extern int open_port(int com_port);

extern int set_com_config(int fd,int baud_rate, int data_bits,char parity,int stop_bits);


/*
 * 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;
}



/*
 * 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;
}




0 0