Linux串口应用编程

这篇具有很好参考价值的文章主要介绍了Linux串口应用编程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在Linux系统中,操作设备的统一接口就是:open/ioctl/read/write
对于UART,又在ioctl之上封装了很多函数,主要是用来设置行规程。
所以对于UART,编程的套路就是:

  • 使用open函数打开串口
  • 设置行规程,比如波特率、数据位、停止位、检验位、RAW模式、一有数据就返回
  • read/write数据
    linux串口编程,linux,unix,串口,UART

1. 打开串口

由于串行端口是一个文件,因此使用open(2)函数来访问它。C语言代码示例如下。

1.1 示例

#include <stdio.h>   /* 标准输入/输出定义 */
#include <string.h>  /* 字符串函数定义 */
#include <unistd.h>  /* UNIX标准函数定义 */
#include <fcntl.h>   /* 文件控制定义 */
#include <errno.h>   /* 错误号定义 */
#include <termios.h> /* POSIX终端控制定义 */

// 成功时返回文件描述符,错误时返回-1。
int open_port(void){
  int fd; /* 端口的文件描述符 */
  fd = open("/dev/ttyf1", O_RDWR | O_NOCTTY | O_NDELAY);
  if (fd == -1){// 打开端口失败
    perror("open_port: Unable to open /dev/ttyf1 - ");
  }
  else
    fcntl(fd, F_SETFL, 0);
  return (fd);
}

其他系统可能需要相应的设备文件名,但除此之外代码是相同的。

1.2 open函数的标志位

当我们打开设备文件时,我们使用了另外两个标志以及读+写模式:

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

其中,

  • O_NOCTTY :表示告诉操作系统,应用程序(进程)打开串口之后,不要把程序当作控制终端。如果指定这一点,那么任何输入(如键盘中止信号等)都将影响进程。
  • O_NDELAY:表示告诉操作系统,应用程序(进程)不关心DCD信号线的状态,即不关心端口的另一端是否启动并运行。如果没有指定这个标志,进程将被置于休眠状态,直到DCD信号线是空间电压。

2. 配置串口

配置串口也就是设置行规程,行规程的参数用结构体struct termios来表示。设置行规程就是设置该结构体中成员的值。

2.1 结构体struct termios

结构体struct termios定义如下:
linux串口编程,linux,unix,串口,UART

struct termios{
	unsigned short c_iflag;   /* 输入模式标志*/
	unsigned short c_oflag;   /* 输出模式标志*/
	unsigned short c_cflag;   /* 控制模式标志*/
	unsigned short c_lflag;   /* 区域模式标志或本地模式标志或局部模式*/
	unsigned char c_line;     /* 行控制line discipline */
	unsigned char c_cc[NCC];  /* 控制字符特性*/
};

2.2 struct termios作用

struct termios被用来提供一个健全的线路设置集合, 如果这个端口在被用户初始化前使用. 驱动初始化这个变量使用一个标准的数值集, 它拷贝自 tty_std_termios 变量. tty_std_termostty 核心被定义为:

struct termios tty_std_termios = {
	.c_iflag = ICRNL | IXON;
	.c_oflag = OPOST | ONLCR;
	.c_cflag = B38400 | CS8 | CREAD | HUPCL;
	.c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE | IEXTEN;
	.c_cc = INIT_C_CC;
};

这个 struct termios 结构用来持有所有的当前线路设置,给这个 tty 设备的一个特定端口。这些线路设置控制当前波特率。数据大小。数据流控设置。以及许多其他值。

2.3 struct termios成员介绍

2.3.1 c_iflag标志常量:Input mode ( 输入模式)

输入模式成员c_iflag控制对端口上接收到的字符所做的任何输入处理。c_iflag中存储的最终值由下表中选项的按位或。

常量 描述
INPCK 启用奇偶校验
IGNPAR 忽略奇偶校验错误
PARMRK 标记奇偶校验错误
ISTRIP 去掉奇偶校验位
IXON 启用输出的 XON/XOFF 流控制
IXOFF 启用输入的 XON/XOFF 流控制
IXANY (不属于 POSIX.1;XSI) 允许任何字符来重新开始输出
IGNBRK 忽略输入中的 BREAK 状态。 (忽略命令行中的中断)
BRKINT 当检测到中断条件时发送SIGINT
INLCR 将输入中的 NL 翻译为 CR。(将收到的换行符号转换为Return)
IGNCR 忽略输入中的回车
ICRNL 将输入中的回车翻译为新行 (除非设置了 IGNCR)(否则当输入信号有 CR 时不会终止输入)
IUCLC (不属于 POSIX) 将输入中的大写字母映射为小写字母
IMAXBEL (不属于 POSIX) 当输入队列满时响零。Linux 没有实现这一位,总是将它视为已设置

2.3.2 c_oflag 标志常量: Output mode ( 输出模式)

c_oflag成员包含输出过滤选项。与输入模式一样,您可以选择已处理原始数据输出。c_oflag 中存储的最终值由下表中选项的按位或。

常量 描述
OPOST 启用具体实现自行定义的输出处理(未设置=原始输出)
OLCUC (不属于 POSIX) 将输出中的小写字母映射为大写字母
ONLCR (XSI) 将输出中的新行符映射为回车-换行
OCRNL 将输出中的回车映射为新行符
ONOCR 不在第 0 列输出回车
ONLRET 不输出回车
OFILL 发送填充字符作为延时,而不是使用定时来延时
OFDEL (不属于 POSIX) 填充字符是 ASCII DEL (0177)。如果不设置,填充字符则是 ASCII NUL
NLDLY 新行延时掩码。取值为 NL0 和 NL1
CRDLY 回车延时掩码。取值为 CR0, CR1, CR2, 或 CR3
BSDLY 回退延时掩码。取值为 BS0 或 BS1。(从来没有被实现过)
VTDLY 竖直跳格延时掩码。取值为 VT0 或 VT1
IUCLC (不属于 POSIX) 将输入中的大写字母映射为小写字母
FFDLY 进表延时掩码。取值为 FF0 或 FF1

更多选项如下图所示:
linux串口编程,linux,unix,串口,UART
一般有两种输出模式可供选择:
(1)选择已处理输出
通过在c_oflag成员中设置OPOST选项来选择处理后的输出:

options.c_oflag |= OPOST;

在所有不同的选项中,目前只能使用ONLCR选项,它将换行符映射为CR-LF对。其余的输出选项主要是历史上的,可以追溯到行打印机和终端无法跟上串行数据流的时候。
(2)选择原始输出
通过重置c_oflag成员中的OPOST选项来选择原始输出:

options.c_oflag &= ~OPOST;

OPOST选项被禁用时,c_oflag中的所有其他选项位都会被忽略。

2.3.3 c_cflag 标志常量: Control mode ( 控制模式)

c_cflag成员控制波特率、数据位数、奇偶校验、停止位和硬件流控制。所有支持的配置都有常量。

c_cflag中存储的最终值由下表中选项确定。

常量 描述
CBAUD (不属于 POSIX) 波特率掩码 (4+1 位)
OLCUC (不属于 POSIX) 扩展的波特率掩码 (1 位),包含在 CBAUD 中
CSIZE 字符长度掩码(传送或接收字元时用的位数)。取值为 CS5(传送或接收字元时用5bits), CS6, CS7, 或 CS8
CSTOPB 设置两个停止位,而不是一个
CREAD 打开接受者
PARENB 允许输出产生奇偶信息以及输入的奇偶校验(启用同位产生与侦测)
PARODD 输入和输出是奇校验(使用奇同位而非偶同位)
HUPCL 在最后一个进程关闭设备后,降低 modem 控制线 (挂断)
CLOCAL 忽略 modem 控制线
LOBLK (不属于 POSIX) 从非当前 shell 层阻塞输出(用于 shl )
CIBAUD (不属于 POSIX) 输入速度的掩码。CIBAUD 各位的值与 CBAUD 各位相同,左移了 IBSHIFT 位
CRTSCTS (不属于 POSIX) 启用 RTS/CTS (硬件) 流控制

linux串口编程,linux,unix,串口,UART
c_cflag成员包含两个应该始终启用的选项,CLOCALCREAD。这将确保您的程序不会成为端口的“所有者”,受到零星的作业控制和挂起信号的影响,并且串行接口驱动程序将读取传入的数据字节。

不要直接初始化c_cflag(或任何其他标志)成员。应该始终使用按位的ANDORNOT操作符来设置或清除成员中的位。不同的操作系统版本可以以不同的方式使用位,因此使用位操作符将防止破坏新串行驱动程序中所需的位标志。

2.3.4 c_lflag 标志常量: Local mode ( 局部模式)

本地模式成员c_lflag控制串口驱动程序如何管理输入字符。通常,将为规范或原始输入配置c_lflag成员。c_cflag中存储的最终值由下表中选项确定。

常量 描述
ISIG 使能SIGINTR、SIGSUSP、SIGDSUSP和SIGQUIT信号
ICANON 启用规范化输入(否则为raw)
XCASE (不属于 POSIX; Linux 下不被支持) 如果同时设置了 ICANON,终端只有大写。输入被转换为小写,除了有前缀的字符。输出时,大写字符被前缀(某些系统指定的特定字符) ,小写字符被转换成大写。
ECHO 启用输入字符的回显
ECHOE 如果同时设置了 ICANON,字符 ERASE 擦除前一个输入字符,WERASE 擦除前一个词
ECHOK 如果同时设置了 ICANON,字符 KILL 删除当前行
ECHONL 如果同时设置了 ICANON,回显字符 NL,即使没有设置 ECHO
NOFLSH 禁止在产生 SIGINT, SIGQUIT 和 SIGSUSP 信号时刷新输入和输出队列,即关闭queue中的flush
IEXTEN 启用扩展功能
ECHOCTL 如果同时设置了 ECHO,除了 TAB, NL, START, 和 STOP 之外的 ASCII 控制信号被回显为 ^X, 这里 X 是比控制信号大 0x40 的 ASCII 码。例如,字符 0x08 (BS) 被回显为 ^H
ECHOPRT 如果同时设置了 ICANON 和 IECHO,字符在删除的同时被打印
CRTSCTS (不属于 POSIX) 启用 RTS/CTS (硬件) 流控制

一般有两种输入模式可供选择:
(1)选择规范输入
规范输入是面向行的。输入字符被放入缓冲区,用户可以交互地编辑缓冲区,直到收到CR(回车)或LF(换行)字符。
当选择此模式时,通常选择ICANONECHOECHO选项:

options.c_lflag |= (ICANON | ECHO | ECHOE);

(2)选择原始输入
原始输入未经处理。当接收到输入字符时,它们将完全按照接收到的方式传递。通常,当使用原始输入时,您将取消选择ICANON, ECHO, ECHOEISIG选项:

options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);

2.3.5 c_cc 数组:特殊控制字元

UNIX串行接口驱动程序提供了指定字符和数据包超时的能力。c_cc数组中的两个元素用于超时:VMINVTIME。在规范输入模式下或通过openfcntl在文件上设置NDELAY选项时,会忽略超时。

VMIN指定要读取的最小字符数。如果设置为0,则VTIME值指定等待读取每个字符的时间。请注意,这并不意味着对N个字节的读取调用将等待N个字符进入。相反,超时将应用于第一个字符,read调用将返回立即可用的字符数(最多可达您请求的字符数)。

如果VMIN不为零,则VTIME指定等待读取第一个字符的时间。如果在给定的时间内读取一个字符,则任何读取将阻塞(等待),直到读取所有VMIN字符。也就是说,一旦读取了第一个字符,串行接口驱动程序期望接收整个字符包(VMIN字节总数)。如果在允许的时间内没有读取任何字符,则调用read返回0。此方法允许您告诉串行驱动程序您需要恰好N个字节,并且任何读调用将返回0或N个字节。然而,超时只适用于第一个字符读取,所以如果由于某种原因驱动程序错过了N字节包中的一个字符,那么read调用可能会永远阻塞,等待额外的输入字符。

VTIME指定等待传入字符的时间,以十分之一秒为单位。如果VTIME设置为0(默认值),读取将无限期阻塞(等待),除非在端口上设置NDELAY选项openfcntl

VMINVTIME的组合方式如下:
(1)VMIN = 0 , VTIME =0
read立即回传,否则传回 0 ,不读取任何字元
(2)VMIN = 0 , VTIME >0
read传回读到的字元,或在十分之一秒后传回VTIME
(3)VMIN > 0 , VTIME =0
read会等待,直到VMIN字元可读
(4)VMIN > 0 , VTIME > 0
每一格字元之间计时器即会被启动
read会在读到VMIN字元,传回值或VTIME的字元计时(1/10秒)超过时将值传回

2.4 与结构体struct termios相关的函数

函数命名解释:

  • tc:terminal contorl
  • cf:control flag

2.4.1 tcgetattr()与tcsetattr()

(1)tcgetattr()函数:get terminal attributes,获得终端的属性
原型:

#include <termios.h>
#include <unistd.h>

int tcgetattr(int fd, struct termios *termios_p);

作用:取得终端介质(fd)初始值,并把其值 赋给temios_p; 函数可以从后台进程中调用;但是,终端属性可能被后来的前台进程所改变。

(2)tcsetattr() 函数:set terminal attributes,修改终端参数
原型:

#include <termios.h>
#include <unistd.h>

int tcsetattr(int fd, int optional_actions, const struct termios *termios_p);

作用:设置与终端相关的参数 ,使用 termios_p 引用的 termios 结构。optional_actionstcsetattr函数的第二个参数)指定了什么时候改变会起作用,可以使用的值如下:

  • TCSANOW:改变立即发生
  • TCSADRAIN:改变在所有写入 fd 的输出都被传输后生效。这个函数应当用于修改影响输出的参数时使用。(当前输出完成时将值改变)
  • TCSAFLUSH :改变在所有写入 fd 引用的对象的输出都被传输后生效,所有已接受但未读入的输入都在改变发生前丢弃(同TCSADRAIN,但会舍弃当前所有值)。

2.4.2 tcflush()

原型:

int tcflush(int fd, int queue_selector);

作用:丢弃要写入 引用的对象,但是尚未传输的数据,或者收到但是尚未读取的数据,取决于 queue_selector 的值。 queue_selector的取值有:

  • TCIFLUSH :刷新收到的数据但是不读
  • TCOFLUSH :刷新写入的数据但是不传送
  • TCIOFLUSH :同时刷新收到的数据但是不读,并且刷新写入的数据但是不传送

2.4.3 tcflow()

原型:

int tcflow(int fd, int action);

作用:挂起 fd 引用的对象上的数据传输或接收,取决于 action 的值。 action 取值有:

  • TCOOFF :挂起输出
  • TCOON :重新开始被挂起的输出
  • TCIOFF :发送一个 STOP 字符,停止终端设备向系统传送数据
  • TCION :发送一个 START 字符,使终端设备向系统传输数据

打开一个终端设备时的默认设置是输入和输出都没有挂起。

2.4.4 波特率函数

波特率函数被用来获取和设置 termios结构体中输入和输出波特率的值。新值不会马上生效,直到成功调用了 tcsetattr() 函数。
(1)cfgetospeed()函数
原型:

speed_t cfgetispeed(const struct termios *termios_p);

作用:返回 termios_p 指向的 termios 结构中存储的输出波特率。返回存储在终端结构中的输入波特率。
(2)cfsetispeed()函数:sets the input baud rate,设置输入波特率
原型:

int cfsetispeed(struct termios *termios_p, speed_t speed);

作用:设置 termios 结构中存储的输入波特率为 speed。如果输入波特率被设为0,实际输入波特率将等于输出波特率。
(3)cfsetospeed()函数:sets the output baud rate,设置输出波特率
原型:

int cfsetospeed(struct termios *termios_p, speed_t speed);

作用:设置 termios 结构中存储的输出波特率为 speed

(4)cfsetspeed()函数:同时设置输入、输出波特率
原型:

int cfsetspeed(struct termios *termios_p, speed_t speed);

作用:cfsetspeed()是一个4.4BSD扩展。它接受与cfsetispeed()相同的参数,并设置输入和输出速度。
(5)波特率大小设置选择
如图:
linux串口编程,linux,unix,串口,UART

3. Linux串口应用编程实例

下面给出了串口配置的完整的函数。通常,为了函数的通用性,通常将常用的选项都在函数中列出,这样可以大大方便以后用户的调试使用。该设置函数如下所示:

3.1 串口配置的函数

// fd:设备文件描述符;nSpeed:需要设置的波特率;nBits:需要设置的数据位数;nEvent:奇偶校验位;nStop:停止位
int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop){
	struct termios newtio,oldtio;

	/*保存测试现有串口参数设置,在这里如果串口号等出错,会有相关的出错信息*/
	if  ( tcgetattr( fd,&oldtio)  !=  0) { 
		perror("SetupSerial 1");
		return -1;
	}
	
	//将 newtio 清零
	bzero( &newtio, sizeof( newtio ) );

	/*步骤一,设置字符大小*/
	newtio.c_cflag  |=  CLOCAL | CREAD; 
	newtio.c_cflag &= ~CSIZE; 

	/*设置数据位*/
	switch( nBits ){
		case 7:
			newtio.c_cflag |= CS7;
			break;
		case 8:
			newtio.c_cflag |= CS8;
			break;
	}

	/*设置奇偶校验位*/
	switch( nEvent ){
		case 'O': //奇数
			newtio.c_cflag |= PARENB;
			newtio.c_cflag |= PARODD;
			newtio.c_iflag |= (INPCK | ISTRIP);
			break;

		case 'E': //偶数
			newtio.c_iflag |= (INPCK | ISTRIP);
			newtio.c_cflag |= PARENB;
			newtio.c_cflag &= ~PARODD;
			break;
		case 'N':  //无奇偶校验位
			newtio.c_cflag &= ~PARENB;
			break;
	}

	/*设置波特率*/
	switch( nSpeed ){
		case 2400:
			cfsetispeed(&newtio, B2400);
			cfsetospeed(&newtio, B2400);
			break;
		case 4800:
			cfsetispeed(&newtio, B4800);
			cfsetospeed(&newtio, B4800);
			break;
		case 9600:
			cfsetispeed(&newtio, B9600);
			cfsetospeed(&newtio, B9600);
			break;
		case 115200:
			cfsetispeed(&newtio, B115200);
			cfsetospeed(&newtio, B115200);
			break;
		case 460800:
			cfsetispeed(&newtio, B460800);
			cfsetospeed(&newtio, B460800);
			break;
		default:
			cfsetispeed(&newtio, B9600);
			cfsetospeed(&newtio, B9600);
			break;
	}

	/*设置停止位*/
	if( nStop == 1 )
		newtio.c_cflag &=  ~CSTOPB;
	else if ( nStop == 2 )
		newtio.c_cflag |=  CSTOPB;

	/*设置等待时间和最小接收字符*/
	newtio.c_cc[VTIME]  = 0;
	newtio.c_cc[VMIN] = 0;

	/*处理未接收字符*/
	tcflush(fd,TCIFLUSH);

	/*激活新配置*/
	if((tcsetattr(fd,TCSANOW,&newtio))!=0){
		perror("com set error");
		return -1;
	}
	printf("set done!\n");
	return 0;
}

3.2 打开串口的函数

下面给出了一个完整的打开串口的函数,同样写考虑到了各种不同的情况。程序如下所示:

/*打开串口函数*/
int open_port(int fd,int comport){
	char *dev[]={"/dev/ttyS0","/dev/ttyS1","/dev/ttyS2"};

	//串口 1
	if (comport==1){
		fd = open( "/dev/ttyS0", O_RDWR|O_NOCTTY|O_NDELAY);
		if (-1 == fd){
			perror("Can't Open Serial Port");
			return(-1);
		}
	}
	else if(comport==2){//串口 2
		fd = open( "/dev/ttyS1", O_RDWR|O_NOCTTY|O_NDELAY);
		if (-1 == fd){
			perror("Can't Open Serial Port");
			return(-1);
		}
	}
	else if (comport==3){//串口 3
		fd = open( "/dev/ttyS2", O_RDWR|O_NOCTTY|O_NDELAY);
		if (-1 == fd){
			perror("Can't Open Serial Port");
			return(-1);
		}
	}

	/*恢复串口为阻塞状态*/
	if(fcntl(fd, F_SETFL, 0)<0)
		printf("fcntl failed!\n");
	else
		printf("fcntl=%d\n",fcntl(fd, F_SETFL,0));

	/*测试是否为终端设备*/
	if(isatty(STDIN_FILENO)==0)
		printf("standard input is not a terminal device\n");
	else
		printf("isatty success!\n");
		
	printf("fd-open=%d\n",fd);

	return fd;
}

3.3 从串口中读取数据

//
int read_datas(int fd, char *rcv_buf,int rcv_wait){
	int retval;

	fd_set rfds;

	struct timeval tv;

	int ret,pos;

	tv.tv_sec = rcv_wait;      // wait 2.5s
	tv.tv_usec = 0;

	pos = 0; // point to rceeive buf

	while (1){
		FD_ZERO(&rfds);

		FD_SET(fd, &rfds);

		retval = select(fd+1 , &rfds, NULL, NULL, &tv);

		if (retval == -1){
			perror("select()");
			break;
		}
		else if (retval){// pan duan shi fou hai you shu ju
			ret = read(fd, rcv_buf+pos, 2048);
			pos += ret;
	
			if (rcv_buf[pos-2] == '\r' && rcv_buf[pos-1] == '\n'){
				FD_ZERO(&rfds);
				FD_SET(fd, &rfds);
	
				retval = select(fd+1 , &rfds, NULL, NULL, &tv);
	
				if (!retval) break;// no datas, break
		
			}
		}
		else{
			printf("No data\n");
			break;
		}

	}
	return 1;
}

3.4 向串口传数据

int send_data(int fd, char *send_buf){
	ssize_t ret;
	ret = write(fd,send_buf,strlen(send_buf));

    if (ret == -1){
		printf ("write device %s error\n", DEVICE_TTYS);
		return -1;
	}
    return 1;
}

参考

[1] https://digilander.libero.it/robang/rubrica/serial.htm
[2] https://blog.csdn.net/yemingzhu163/article/details/5897156
[3] https://www.cnblogs.com/feisky/archive/2010/05/21/1740893.html文章来源地址https://www.toymoban.com/news/detail-762777.html

到了这里,关于Linux串口应用编程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 嵌入式Linux裸机开发(七)UART串口、IIC、SPI通信

    大概学完这三种通信后,之后就先去学系统移植,其他的先暂时放下 串口全称叫做串行接口,通常也叫做 COM 接口。 UART:(Universal Asynchronous Receiver/Trasmitter)通用异步串行收发器。 USART:(Universal Synchronous/Asynchronous Receiver/Transmitter)通用同步/异步串行收发器,相比 UART多了

    2024年02月07日
    浏览(78)
  • Unix/Linux系统编程:信号驱动IO

    详细信息参考unix/linux系统编程手册第63章  在I/O多路复用中,进程是通过系统调用(select()或poll())来检查文件描述符上是否可以执行I/O操作。而在信号驱动I/O中,当文件描述符上可执行I/O操作时,进程请求内核为自己发送一个信号。之后进程就可以执行任何其他的任务直到

    2024年02月11日
    浏览(37)
  • Unix/Linux编程:UDS 流(Stream)

    socket 是一种 IPC (Inter-Process Communication,进程间通信)方法,它允许位于同一主机(计算机)或使用网络连接起来的不同主机上的应用程序之间交换数据。通过使用Socket,开发人员可以创建网络应用程序,使其能够通过网络进行数据交换和通信。 Socket API通常用于基于TCP/IP协

    2024年02月08日
    浏览(39)
  • 【Linux专区】 Linux is not unix | Linux发展史 | Linux应用现状

    💞💞 欢迎来到 Claffic 的博客 💞💞      👉  专栏 : 《Linux专区》👈         前言: 上次提前带大家搭建了Linux的环境,其实之前应该还有一步的,就是向大家介绍Linux发展史,毕竟如此伟大的产品,不懂Linux史就学Linux总觉得有点奇怪... ...   本文入选全站综合热榜第

    2024年02月06日
    浏览(45)
  • Linux串口编程

    本篇文章将讲解如何在Linux下使用串口。 在Linux系统中,tty(Teletypewriter)是指一种终端设备,它提供了用户与操作系统之间的交互界面。在较早的计算机系统中,tty是以打字机作为输入输出设备的终端系统,而现代的Linux系统中,tty则对应着虚拟终端。 Linux下的tty体系是由多

    2024年02月09日
    浏览(21)
  • 嵌入式培训机构四个月实训课程笔记(完整版)-Linux ARM驱动编程第四天-ARM Linux编程之IIC与uart (物联技术666)

    链接:https://pan.baidu.com/s/1V0E9IHSoLbpiWJsncmFgdA?pwd=1688 提取码:1688 教学内容: 1 、 I2C 总线: I2C(Inter-Integrated Circuit),PHILIPS公司开发的两线式半双工同步串行总线;可以用来连接存储器(EEPROM、FLASH)、A/D、D/A转换器、LCD驱动器、传感器等等。 I2C总线有两根信号线:双向数据线

    2024年02月19日
    浏览(45)
  • 基于Linux的树莓派和电脑之间的串口通信编程

    目录 1、串口基本认知 2、USB转TTL,使用ch340通信 2.1 TTL电平 2.2 串口接线方式 ​3、串口通信常用的API 4、代码通信实例 4.1 发送一个字符/字符串到串口 4.2 树莓读取串口数据(字符串) 4.3 双方互相通信 4.3.1 树莓派接收一个字符同时再发送字符到串口 4.3.2 树莓派子进程接收

    2024年02月03日
    浏览(42)
  • [imx6ull]Linux下TTY-串口编程

    TTY 是Teletype或Teletypewriter的缩写,原来是指电传打字机,在以前计算机体积很大,所以用teletype这个设备来连接到计算机,后来这种设备键盘显示器取代,但是他们都作为计算机的终端设备所存在,所以TTY沿用至今,用来泛指计算机的终端设备,它作为一个子系统既支持串口,

    2023年04月08日
    浏览(37)
  • 嵌入式Linux应用开发笔记:串口

    串口(UART)是嵌入式设备中比较常用的功能。这篇文章将记录下应用程序中串口操作相关内容。 这篇文章中内容均在下面的开发板上进行测试: 《新唐NUC980使用记录:自制开发板(基于NUC980DK61YC)》 这篇文章是在下面文章基础上进行的: 《新唐NUC980使用记录(5.10.y内核)

    2024年02月09日
    浏览(50)
  • Linux系统应用编程(五)Linux网络编程(上篇)

    1.两个网络模型和常见协议 (1)OSI七层模型(物数网传会表应) 物理层、数据链路层、网络层、传输层、会话层、表示层、应用层(自下到上) (2)TCP/IP四层模型(网网传应) 网络接口层(链路层)、网络层、传输层、应用层 (3)常见网络协议所属层 2.字节序 (1)两种

    2023年04月25日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包