终端及串口编程

7.1.1 实际的物理串口

如果使用虚拟机开发串口程序,可以使用win下文件来代替串口

7.1.2 控制台终端

tty1-tty6为控制台终端

7.1.3 虚拟终端

  1. /dev/ptmx虚拟设备
    是一个字符文件,用于创建虚拟网络设备master/slave配对设备,要打开一个未使用的虚拟终端,通过调用posix_openpt(),来打开/dev/ptmx。
  2. /dev/pts虚拟设备

7.2 终端属性控制

终端属性包括:
输入属性、输出属性、控制属性、本地属性、行路规划属性和控制字符

7.2.1 读取/设置终端属性信息

终端属性结构体

#define NCCS 19
struct termios{
	tcflag_t c_iflag //输入属性
		tcflag_t c_oflag //输出属性
			tcflag_t c_cflag //控制属性
 				tcflag_t c_lflag //本地属性
					cc_t c_line //线路规划属性
						cc_t c_cc[NCCS] //控制字符
}

获取某个打开的终端属性
extern int tcgetattr(int __fd, struct termios *__termios_p)
设置某个终端的属性
extern int tcsetattr(int __fd, int __optional_actions, __const struct termios *__termios_p)
__optional_actions指定什么时候改变会起作用
TCSANOW 改变立即发生
TCSADRAIN 应用于修改影像输出的选项时使用
TCSAFLUSH 应用于所有已接收但未读入的输入都在改变发生前丢弃

7.2.2 c_cflag终端控制选项

1.设置baud rate

波特率和比特率的区别
https://blog.csdn.net/qq_42035602/article/details/80194941

说白了就是波特率是信号经过调制后,单位时间内载波变化的次数,
比特率是单位时间内传输的位数,之所以不同,是因为一个载波内,可能传输多个二进制位,即;
比特率=波特率*单个调制状态对应的二进制位数
uart刚好对应一个载波传输一位,莫搞混。

获取输出波特率的属性
extern speed_t cfgetospeed(__const struct termios *__termios_p);
获取输入波特率的属性
extern speed_t cfgetispeed(__const struct termios *__termios_p);
设置输入、输出波特率
extern int cfsetospeed(struct termios *__termios_p, speed_t __speed);
extern int cfsetispeed(struct termios *__termios_p, speed_t __speed);
extern int cfsetspeed(struct termios *__termios_p, speed_t __speed);
2.设置帧数据位宽度
struct termios options;
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
3.设置奇偶校验方式
options.c_cflag &= ~PARENB //无奇偶校验
options.c_cflag &= ~STOPB //1位停止位
4.设置硬件流控制

7.2.3 c_lflag

管理采用何种方式来输入字符,一般为标准模式或者原始模式
使用默认方式
所有字符缓存在buffer空间中,指导用户输入CR或者LF字符后才将其发送,输入内容的回显由本端完成
options.c_lflag |= (ICANON|ECHO|ECHOE);
使用原始方式
每输入一个字符都立即发送到服务器,服务器将把这个字符回显给客户的屏幕,这种情况将不需要用户自己支持回显。
options.c_lflag |= (ICANON|ECHO|ECHOE|ISIG);

7.2.4 c_iflag终端输入回显

输入 man cfsetispeed 查看输入选项常量描述
如果c_cflag允许了奇偶校验,则必须再允许输入校验

7.2.5 c_oflag终端输入选项

在上述打开文件内/c_oflag查看输出选项常量描述

7.2.6 c_cc终端控制字符

7.2.7 IOCTLS控制终端

7.3 串口编程

vicli@www.100ask.org:~/2_linux_program/_7_serial$ cat serial_exp.c 
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "unistd.h"
#include "sys/types.h"
#include "sys/stat.h"
#include "fcntl.h"
#include "termios.h"
#include "errno.h"
#include "curses.h"

//设置数据位长度,奇偶校验、停止位等
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 8 : options.c_cflag |= CS8;
			 break;
		default: fprintf(stderr, "unsupported data size\n");
			 return (FALSE);
	}
	switch(parity){
		case 'N': options.c_cflag &= ~PARENB;
			  options.c_iflag &= ~INPCK;
			  break;
		default : fprintf(stderr, "unsupported parity\n"); 	
	}
	switch(stopbits){
		case 1: options.c_cflag &= ~CSTOPB;
			break;
		default: fprintf(stderr, "unsupported stop bits\n");
			 return (FALSE);
	}

	if(parity != 'n')
		options.c_iflag |= INPCK;
	options.c_cc[VTIME] = 150;
	options.c_cc[VMIN] = 0;
	//刷清(扔掉)输入缓存(终端驱动法度已接管到,但用户法度尚未读)或输出缓存(用户法度已经写,但尚未发送).
	tcflush(fd, TCIFLUSH);
	if(tcsetattr(fd, TCSANOW, &options) != 0){
		perror("setupserial 3");
		return (FALSE);	
	}
	return (TRUE);
}

int speed_arr[] = {B115200, B38400, B19200, B9600};
int name_arr[] = {115200, 38400, 19200, 9600};
void set_speed(int fd, int speed)
{
	int i;
	int status;
	struct termios Opt;
	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){
				perror("tcsetattr\n");
			}
			return;	
		}
	}
}

int main(int argc, char *argv[])
{
	int fd;
	int nread;
	char *ptr = argv[2];
	char *dev = argv[1];
	if(argc < 3){
		printf("pls usage %s/dev/ttyS[n] your_message", argv[1]);
		exit(EXIT_FAILURE);
	}	

	if((fd = open(dev, O_RDWR)) == -1){
		perror("open");
		exit(EXIT_FAILURE);	
	}
	set_speed(fd, 115200);

	if((set_Parity(fd, 8, 1, 'N')) == FALSE){
		printf("set parity error\n");	
		exit(EXIT_FAILURE);
	}
	if(write(fd, ptr, strlen(ptr)) < 0){
		perror("write\n");
		exit(EXIT_FAILURE);
	}
	printf("pls check the tty data\n");
	close(fd);
	exit(EXIT_SUCCESS);
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值