Linux串口通信编程

 目标效果:

本文实现的效果:使用野火Linux开发板,上位机从键盘输入字符串,然后从串口发给下位机,下位机从串口收到字符串后,将收到的字符串打印出来,并写入指定的文件中,将下位机程序下载到实验箱运行。

 实现过程:

  • 让Ubuntu和开发板ping通

在保持联网的情况下,在Ubuntu中输入以下命令安装nfs服务:

sudo apt-get install nfs-kernel-server

sudo apt-get install nfs-common

sudo apt-get install portmap

sudo vim /etc/exports

在打开的exports配置文件中最底下输入以下内容:

/nfsFile  *(rw,sync,no_root_squash)

启动nfs服务

sudo /etc/init.d/nfs-kernel-server restart

连接开发板与电脑,更改IP地址,让Ubuntu和开发板互相ping通

ifconfig eth1 192.168.7.114 netmask 255.255.255.0

ping 192.168.7.123

二、使用SecureCRT 8.3登录开发板

安装SecureCRT 8.3软件,新建一个端口连接,将开发板和电脑连接在一起,输入账号密码登录开发板账号:debian,密码:temppwd

  • 在开发板上挂载Ubuntu中创建的共享文件目录

sudo mount -t nfs 192.168.7.114:/nfsFile /mnt

  • 在Ubuntu中编译程序

修改:uart_api.h

 fd = open("/dev/ttyUSB0", O_RDWR|O_NOCTTY|O_NDELAY);

编译好的可执行文件:com_host_reader

五、开发板使用交叉编译工具链编译

导出全局变量指令:(确保交叉编译工具链在/usr/local/arm下解压)

export PATH=$PATH:/usr/local/arm/gcc-linaro-4.9.4-2017.01-i686_arm-linux-gnueabihf/bin/

编译好的可执行文件:com_host_writer

 uart_api.h:

/* 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 3
#define COM_TYPE fire_COM
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);
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); /* 配置为原始模式 */
	
	/*设置波特率*/
  	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);
	
	new_cfg.c_cflag &= ~CSIZE;
	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_cflag &= ~PARODD; 
			new_cfg.c_iflag |= INPCK;   
		}
		break;

		case 's':  /*as no parity*/
		case 'S':
		{
			new_cfg.c_cflag &= ~PARENB;
			new_cfg.c_cflag &= ~CSTOPB;
		}
		break;
	}
		
	switch (stop_bits) /*设置停止位*/
	{
		default:
		case 1:
		{
			new_cfg.c_cflag &=  ~CSTOPB;
		}
		break;

		case 2:
		{
			new_cfg.c_cflag |= CSTOPB;
		}
	}
	
	/*设置等待时间和最小接收字符*/
	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;
}

/*打开串口函数*/
int open_port(int com_port)
{
	int fd;
#if (COM_TYPE == GNR_COM)  /* 使用普通串口 */
	char *dev[] = {"/dev/ttyS0", "/dev/ttyS1", "/dev/ttyS2"};
#elif (COM_TYPE==fire_COM)
	char *dev[] = {"/dev/ttymxc0", "/dev/ttymxc1", "/dev/ttymxc2"};
	
#else /* 使用USB转串口 */
        char *dev[] = {"/dev/ttyUSB0", "/dev/ttyUSB1", "/dev/ttyUSB2"};

#endif
	
	if ((com_port < 0) || (com_port > MAX_COM_NUM))
	{
		return -1;
	}
	/* 打开串口 */
	printf("com=%s\n",dev[com_port-1]);
	fd = open("/dev/ttyUSB0", 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(fd) == 0) /*测试打开的文件是否为终端设备*/
	{
		perror("This is not a terminal device");
	}	
	return fd;
}







  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值