IO端口复用的几种方式
io口复用原理

io口复用原理
I/O 口复用原理是指在电子设备中,通过硬件或软件的方式,将一个I/O 端口用于多种不同的功能或通信协议。
I/O 口复用的原理基于以下几个方面:
1. 功能复用:通过复用I/O 口,可以在不同的时间或条件下,将其配置为不同的功能。
例如,一个I/O 口可以在某些时候作为输入端口,用于读取传感器数据,而在其他时候作为输出端口,用于控制外部设备。
2. 通信协议复用:I/O 口还可以复用为支持多种通信协议的端口。
例如,一个USB 接口可以通过复用支持多种USB 协议,如USB 2.0、USB
3.0 等。
3. 时间复用:通过时分复用(TDMA)或轮询的方式,可以在不同的时间段内将I/O 口分配给不同的功能或通信协议。
这样可以实现多个功能或协议共享同一个I/O 口。
4. 引脚复用:在一些集成电路中,I/O 引脚可以通过内部寄存器或配置选项进行复用。
通过设置相应的寄存器或选项,可以将一个引脚配置为不同的功能,如输入、输出、UART、SPI 等。
I/O 口复用的优势包括减少硬件成本、降低系统复杂度、提高系统灵活性和可扩展性等。
通过复用I/O 口,可以充分利用有限的引脚资源,实现更多的功能和通信协议。
3.IO口输入输出,IO口复用,按键LED灯驱动例程

第三章通用和复用功能I/O3.1 概述STM32F10x系列有着丰富的端口可供使用,有26/37/51/80/112个多功能双向5V兼容的快速I/O口,所有I/O口可以映像到16个外部中断。
每个GPI/O端口有两个32位配置寄存器(GPIOx_CRL,GPIOx_CRH),两个32位数据寄存器GPIOx_IDR,GPIOx_ODR),一个32位置位/复位寄存器(GPIOx_BSRR),一个16位复位寄存器(GPIOx_BRR)和一个32位锁定寄存器(GPIOx_LCKR)。
GPIO端口的每个位可以由软件分别配置成多种模式。
─输入浮空─输入上拉─输入下拉─模拟输入─开漏输出─推挽式输出─推挽式复用功能─开漏复用功能每个I/O端口位可以自由编程,I/0端口寄存器必须按32位字被访问(不允许半字或字节访问)。
GPIOx_BSRR 和GPIOx_BRR寄存器允许对任何GPIO寄存器的读/更改的独立访问;这样,在读和更改访问之间产生IRQ时不会发生危险。
图3-1-1给出了一个I/O端口位的基本结构。
图3-1-1 I/O端口位的基本结构3.1.1 通用I/O(GPIO)复位期间和复位后,复用功能未开启,I/O端口被配置成浮空输入模式。
复位后,JTAG引脚被置于输入上拉或下拉模式:─PA15:JTDI置于上拉模式─PA14:JTCK置于下拉模式─PA13:JTMS置于上拉模式─PB4:JNTRST置于上拉模当I/O脚作为输出配置时,写到输出数据寄存器上的值(GPIOx_ODR)输出到相应的I/O引脚。
可以以推挽模式或开漏模式(当输出0时,只有N-MOS被打开)使用输出驱动器。
输入数据寄存器(GPIOx_IDR)在每个APB2时钟周期捕捉I/O引脚上的数据。
所有GPIO引脚都有一个内部弱上拉和弱下拉,当配置为输入时,它们可以被激活也可以被断开。
3.1.2单独的位设置或位清除当对GPIOx_ODR的个别位编程时,软件不需要禁止中断:在单次APB2写操作里,可以只更改一个或多个位。
STM32八种IO口模式区别

如图所示,推挽放大器的输出级有两个“臂”(两组放大元件),一个“臂”的电流增加时,另一个“臂”的电流则减小,二者的状态轮流转换。
对负载而言,好像是一个“臂”在推,一个“臂”在拉,共同完成电流输出任务。
当输出高电平时,也就是下级负载门输入高电平时,输出端的电流将是下级门从本级电源经VT3拉出。
这样一来,输出高低电平时,VT3 一路和VT5 一路将交替工作,从而减低了功耗,提高了每个管的承受能力。
又由于不论走哪一路,管子导通电阻都很小,使RC常数很小,转变速度很快。
因此,推拉式输出级既提高电路的负载能力,又提高开关速度。
关于推挽输出和开漏输出,最后用一幅最简单的图形来概括:该图中左边的便是推挽输出模式,其中比较器输出高电平时下面的PNP三极管截止,而上面NPN三极管导通,输出电平VS+;当比较器输出低电平时则恰恰相反,PNP三极管导通,输出和地相连,为低电平。
右边的则可以理解为开漏输出形式,需要接上拉。
浮空输入:对于浮空输入,一直没找到很权威的解释,只好从以下图中去理解了对于复用功能输入,端口可以配置成任意输入模式或者复用功能输出模式.对于复用功能输出,端口必须配置成复用功能输出对于双向复用功能,端口必须配置成复用功能输出stm32的部分IO端口的复用功能可以重新映射成另外的复用功能.stm32具有GPIO锁定机制,即锁定GPIO配置,下次复位前不能再修改.当LSE振荡器关闭时,OSC32_IN和OSC32_OUT可以用作通用IO PC14和PC15.当进入待机模式或者备份域由Vbat供电,PC14,PC15功能丢失,该两个IO口线设置为模拟输入功能. OSC_IN和OSC_OUT可以重新映射为GPIO PD0,PD1.注意PD0,PD1用于输出地时候仅能用于50MHz输出模式.注意:PC13,PC14,PC15只能用于2MHz的输出模式,,最多只能带30pf的负载,并且同时只能使用一个引脚!!!!!!!!。
io的多路复用机制

io的多路复用机制IO的多路复用机制是一种高效的网络编程技术,它能够在单线程下同时处理多个IO任务,提高系统的并发性能。
下面将详细介绍IO 的多路复用机制及其应用。
一、什么是IO的多路复用机制IO的多路复用机制是指通过一个线程来监听多个IO事件,并且在有IO事件发生时进行响应的机制。
它的主要原理是利用操作系统提供的系统调用,如select、poll、epoll等,来监听多个IO事件的状态变化。
当有IO事件就绪时,通过系统调用返回的事件集合来确定是哪些IO事件就绪,并进行相应的处理。
二、为什么需要IO的多路复用机制在传统的IO模型中,每个IO任务通常需要一个线程来处理,当IO 任务数量较大时,会导致线程数量激增,造成系统资源的浪费和线程调度的开销。
而采用IO的多路复用机制后,只需要一个线程来监听多个IO事件,大大减少了线程的数量和系统开销,提高了系统的并发性能。
三、IO的多路复用机制的应用1. 服务器编程:在服务器编程中,经常需要处理多个客户端的连接请求。
使用IO的多路复用机制可以通过一个线程监听多个客户端的连接请求,并在有连接请求到来时进行处理。
2. 并发网络编程:在并发网络编程中,通常需要同时处理多个网络请求。
使用IO的多路复用机制可以在单线程下同时处理多个网络请求,提高系统的并发性能。
3. 文件传输:在文件传输中,通常需要同时读写多个文件。
使用IO 的多路复用机制可以在单线程下同时处理多个文件的读写操作,提高文件传输的效率。
四、IO的多路复用机制的优点1. 提高系统的并发性能:通过一个线程同时监听多个IO事件,减少了线程的数量和系统开销,提高了系统的并发性能。
2. 减少了线程切换的开销:由于采用了单线程的方式来处理多个IO 事件,减少了线程的切换开销,提高了系统的响应速度。
3. 简化了程序的设计:采用IO的多路复用机制可以将多个IO任务放在一个线程中处理,简化了程序的设计和维护。
五、IO的多路复用机制的局限性1. 对于大量的IO任务,单个线程可能无法处理,需要采用多线程或线程池来进行处理。
STM32功能引脚端口复用和重映射

STM32功能引脚端口复用和重映射
在STM32系列微控制器中,每个引脚都有一个默认的功能。
通过端口复用,我们可以将一个引脚的默认功能改变为其他的功能。
每个引脚都有一个对应的功能选择字,可以通过设置这个字来实现不同的功能。
引脚的功能可以是GPIO输入输出、模拟输入输出、定时器输入输出、串行通信等等。
端口复用功能使我们可以在同一个引脚上实现多种不同功能的选择。
比如,一个IO引脚默认是用作GPIO输入输出的,可以通过端口复用将其改为定时器的输入或输出引脚,实现定时器功能。
在一些情况下,系统的引脚数量有限,无法满足需求,此时就可以使用引脚重映射来实现更多的功能。
引脚重映射是将一个引脚的默认功能映射到其他引脚上,可以实现多个引脚共享一个功能。
引脚重映射需要特定的硬件支持,不是所有引脚都支持重映射。
可以通过引脚映射寄存器来设置引脚重映射。
引脚重映射的功能让系统设计更加灵活和可扩展。
在一个引脚只能实现一个功能的情况下,通过重映射可以将多个引脚的功能映射到一个引脚上,实现多个功能的共享。
端口复用和重映射的具体实现方式和寄存器设置是根据不同型号的STM32微控制器而有所不同的。
在开发过程中,需要查阅相关的文档和手册,了解具体的端口复用和重映射的功能和设置方法。
总之,STM32微控制器的功能引脚可以通过端口复用和重映射实现多种不同的功能。
端口复用可以改变引脚的默认功能,而重映射可以实现多个引脚共享一个功能。
这些功能增强了系统的灵活性和可扩展性。
在实际
应用中,需要根据具体需求选择适当的引脚复用和重映射方式,以满足系统的需求。
单片机IO分时复用技巧

单片机IO分时复用技巧单片机的多个外部设备可以共用单片机I/O口线来实现控制、数据传送或信号接收,这种方法称为复用。
复用的基本原理是单片机错时交替对设备进行控制、检测或数据收发,即“分时复用”。
为了保证分时复用成功,最基本的要求是单片机控制某个设备时,复用端口的电平变化不应影响其他设备。
因此,每个被控制设备都应该有“片选”功能,能够通过“片选”关闭或接通与单片机I/O的联络。
在某些情况下,并不是真正意义上的“片选”,例如可以使用“写”线来区分数据的目标芯片。
2)控制线复用控制线复用是指将多个设备的控制线连接在一起,通过单片机对控制线进行分时控制,从而实现多个设备的控制。
这种方法可以减少控制线的数量,但需要在编程时对控制线进行精细的控制,以避免干扰其他设备。
3)技巧性减少输出线和信号线通过技巧性减少输出线和信号线,可以实现更有效的复用。
例如,可以通过使用移位寄存器来减少数据输出线的数量。
此外,还可以使用多路复用器来减少信号线的数量。
4)隔离控制复用法隔离控制复用法是指将多个设备的控制信号通过隔离器进行隔离,从而实现多个设备的复用。
这种方法可以减少控制线的数量,但需要使用额外的隔离器。
5)抗干扰措施在进行复用时,需要注意抗干扰措施。
例如,可以使用滤波电路来减少干扰,或者使用光耦隔离器来隔离干扰。
6)不使用8255的完整接线表(超级复用)通过以上方法,可以实现不使用8255的完整接线表,从而实现超级复用。
在实际应用中,可以根据需要选择不同的复用方法,以达到最佳的效果。
1.8位数码管LED、LED、4X4键盘、部分传感器信号可以复用到P0口。
2.8位数码管LED、LED的CS1、CS2可以复用。
3.可以减少不必要的信号线,如步进电机模块左右限位信号只需一个,直流电机模块正反转可利用定时器实现,LCD只需写入数据时将读/写控制线接为只写模式。
4.利用光电耦合模块,端控制(片选)作用,将信号复用到P0口,省去8255.5.使用光电耦合模块隔离复用P0口时,需要注意抗干扰措施,如在发射极公共端接上拉电阻。
很全的51单片机IO端口详解(带图)

80C51的I/O端口结构及应用特性一,I/O端口的结构1,锁存器加引脚的典型结构80C51的I/O端口都有内部总线实现操作控制。
P0-P3四个I/O 口都可以做普通I/O口,因此,要求具有输出锁存功能。
内部总线有事分时操作,因此每个I/O端口都有相应的锁存器。
然而I/O端口又是外部的输入/输出通道,必须有相应的引脚,故形成了I/O端口的锁存器加引脚的典型结构。
2,I/O口的复用功能(1)I/O口的总线复用。
80C51在使用并行总线扩展时,P0口可作为数据总线口和低8位地址总线口,这是,P0为三态双向口。
P0口输出总线的地址数据信号,P2口输出高8位地址信号。
(2)I/O口的功能复用。
I/O口的P3为功能复用的I/O端口。
端口有复用输出的控制端;引脚也有复用输入的控制端。
3,准双向结构P0,P1,P2,P3口做普通I/O口使用时,都是准双向口结构。
准双向口的典型结构见P1口位结构图。
准双向口的输入操作和输出操作本质不同,输入操作时读引脚状态;输出操作时对口锁存器的写入操作。
有口锁存器和引脚电路可知:当有内部总线对只1或只0时,锁存器的0、1状态立即反应到引脚上。
但是输入操作(读引脚)时,如果口锁存器的状态为0,引脚被嵌位在0状态,导致无法读出引脚的高电平输入。
二,I/O端口的应用特性1,引脚的自动识别。
无论P0,P2口的总线复用,还是P3口的功能复用,内部资源会自动选择,不需要通过指令的状态选择。
2,口锁存器的读、该、写操作。
许多涉及到I/O端口的操作,只是涉及口锁存器的读出、修改、写入的操作。
这些指令都是一些逻辑运算指令、置位/清除指令、条件转移指令以及将I/O口作为目的地址的操作指令。
3,读引脚的操作指令。
如果某个I/O口被指定为源操作数,则为读引脚的操作指令。
例如,执行MOV A,P1时,P1口的引脚状态传送到累加器中,执行MOV P1,A是,指令则将累加器的内容传送到P1口锁存器中。
4,准双向口的使用。
单片机不连续的io合并

单片机不连续的io合并单片机不连续的IO合并。
在单片机系统设计中,IO(输入/输出)端口的合并是一个常见的问题。
特别是当需要将多个不连续的IO信号合并到一个单一的端口时,工程师们需要找到一种有效的解决方案。
首先,让我们来看一下为什么需要将不连续的IO信号合并。
在一些应用中,由于硬件限制或者设计需求,多个IO信号可能分散在不同的端口上,但是需要将它们整合到一个单一的端口上进行处理。
这种情况下,工程师们需要设计一种方案来实现IO信号的合并。
一种常见的解决方案是使用编码器或者解码器芯片。
编码器可以将多个IO信号编码成一个二进制数据,然后通过单一的端口传输到单片机上。
而解码器则可以将接收到的数据解码成多个IO信号。
这种方法可以有效地实现IO信号的合并和分解,但是需要额外的硬件支持,并且增加了系统的复杂性和成本。
另一种解决方案是使用数字信号处理技术。
通过对不连续的IO信号进行数字化处理,可以将它们合并成一个数字数据流,然后在单片机内部进行解析和处理。
这种方法不需要额外的硬件支持,但是需要工程师具备较高的数字信号处理能力和编程技能。
除此之外,还有一些其他的方法可以实现IO信号的合并,比如使用多路复用器、分时复用器等器件。
这些方法各有优劣,工程师们需要根据具体的应用需求和系统设计来选择合适的方案。
总的来说,单片机不连续的IO合并是一个常见的问题,但是通过合适的技术和方法,工程师们可以有效地解决这个问题,实现IO信号的合并和处理。
这对于单片机系统设计和应用具有重要的意义。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
IO端口复用简介I/O多路复用(multiplexing):本质是通过一种机制(系统内核缓冲I/O数据),让单个进程可以监视多个文件描述符,一旦某个描述符就绪(一般是读就绪或写就绪),能够通知程序进行相应的读写操作。
适用场景:高并发的服务器端。
应对并发,常见的思维是创建多线程,每个线程管理一个并发操作,但是弊端很明显,就是多线程需要上下文切换,这个切换的消耗太大,当连接的客户端很多的时候弊端就很突出了。
所示使用单线程的多路复用。
几种方式1.s electLinux提供的select相关函数接口如下:#include <sys/select.h>#include <sys/time.h>int select(int max_fd, fd_set *readset, fd_set *wri teset, fd_set *exceptset, struct timeval *timeout) FD_ZERO(int fd, fd_set* fds) /* 清空集合 */FD_SET(int fd, fd_set* fds) /* 将给定的描述符加入集合 */FD_ISSET(int fd, fd_set* fds) /* 将给定的描述符从文件中删除 */FD_CLR(int fd, fd_set* fds) /* 判断指定描述符是否在集合中 */接口解释:1:select函数的返回值就绪描述符的数目,超时时返回0,出错返回-1。
2:第一个参数max_fd指待测试的fd个数,它的值是待测试的最大文件描述符加1,文件描述符从0开始到max_fd-1都将被测试。
3:中间三个参数readset、writeset和exceptset指定要让内核测试读、写和异常条件的fd集合,如果不需要测试的可以设置为NULL。
代码演示:sockfd=socket(AF_INET,SOCK_STREAM,0);memset(&addr,0,sizeof(addr));addr.sin_family=AF_INET;addr.sin_port=htons(2000);addr.sin_addr.s_addr=IN ADDR_ANY;bind(sockfd,(struct sockaddr*)&addr,sizeof(addr)); listen(sockfd,5);fd_set rset;int max = 0;int fds[5];for(int i=0;i<5;i++){memset(&client,O,sizeof(client);addrlen=sizeof(client);fds[i]=accept(sockfd,(struct sockaddr*)&client,&addrlen);if(fds[i]>max)max=fds[i];}while(1){FD_ZERO(&rset);for(int i=0;i<5;i++){FD_SET(fds[i],&rset);}puts("round again");select(max+1,&rset,NULL,NULL,NULL);for(int i=0;i<5;i++){if(FD_ISSET(fds[i],&rset)){memset(buffer,0,MAXBUF);read(fds[i],buffer,MAXBUF);puts(buffer);}}}这是一段使用select的端口复用的简单代码。
代码定义一个监听5个客户端的select模型。
从代码中可以看出几个问题:1:FD_ZERO(&rset);for(int i=0;i<5;i++){FD_SET(fds[i],&rset);}每次while循环都要需要重复调用FD_ZERO进行清除,并在FD_SET加入句柄。
2:for(int i=0;i<5;i++){if(FD_ISSET(fds[i],&rset)){memset(buffer,0,MAXBUF);read(fds[i],buffer,MAXBUF);puts(buffer);}}每次读取数据都需要遍历所有句柄,所以就有O(n)的消耗。
3:select模型设计时有最大的上线值1024,可在源码中查看到。
想要更高的并发的话就需要采用多线程了。
4:执行select函数时,存在着用户态和内核态的切换,需要把句柄从内核态切换到用户态。
数量少的时候感知不强烈,高并发的时候能有明显的感觉。
以上4点也就是select模型的缺点,总结如下:1:有上限要求(1024),更多的话就需要多线程了;2:FDSET不能重用,每次都需要FDZERO;3:获取句柄需要从用户态拷贝成内核态,开销大;4:获取消息的形式是遍历。
需要循环获取。
时间复杂度O(n)。
相交于传统的套接字select也存在其优点:1:效率高。
2:跨平台性好,几乎支持所有平台。
2.pollpoll的机制与select类似,与select在本质上没有多大差别,管理多个描述符也是进行轮询,根据描述符的状态进行处理,但是poll没有最大文件描述符数量的限制。
#include <poll.h>int poll(struct pollfd fds[], nfds_t nfds, int timeout);typedef struct pollfd {int fd; /* 需要被检测或选择的文件描述符 */short events; /* 对文件描述符fd 上感兴趣的事件 */short revents; /* 文件描述符fd 上当前实际发生的事件 */} pollfd_t;接口解释:1:poll()函数返回fds集合中就绪的读、写,或出错的描述符数量,返回0表示超时,返回-1表示出错;2:fds是一个struct pollfd类型的数组,用于存放需要检测其状态的socket描述符,并且调用poll函数之后fds数组不会被清空;3:nfds记录数组fds中描述符的总数量;4:timeout是调用poll函数阻塞的超时时间,单位毫秒;5:一个pollfd结构体表示一个被监视的文件描述符,通过传递fds[]指示 poll() 监视多个文件描述符。
其中,结构体的events域是监视该文件描述符的事件掩码,由用户来设置这个域,结构体的revents域是文件描述符的操作结果事件掩码,内核在调用返回时设置这个域。
events域中请求的任何事件都可能在revent s域中返回。
合法的事件如下:POLLIN 有数据可读POLLRDNORM 有普通数据可读POLLRDBAND 有优先数据可读POLLPRI 有紧迫数据可读POLLOUT 写数据不会导致阻塞POLLWRNORM 写普通数据不会导致阻塞POLLWRBAND 写优先数据不会导致阻塞POLLMSGSIGPOLL 消息可用当需要监听多个事件时,使用POLLIN | POLLRDNORM设置 events 域;当poll 调用之后检测某事件是否发生时,fds[i].revents & POLLIN进行判断。
代码演示:pollfd pollds[5];for(int i=0;i<5;i++){memset(&client,0,sizeof(client));addrlen=sizeof(client);pollfds[i].fd=accept(sockfd,(structsockaddr*)&client,&addrlen);pollfds[i].events=POLLIN;}sleep(1);while(1){puts("round again");poll(pollfds,5,50000);for(int i=0;i<5;i++){if(pollfds[i].revents&POLLIND){pollfds[i].revents=0;memset(buffer,0,MAX BUF);read(pollfds[i].fd,buffer,MAXBUF);puts(buffer);}}}通过代码可看到,poll模型相较于 select的改进在于使用了自定义的结构pollfd 来存储数据,对比select模型可以观察到几个不同的变化点:1:不再存在上限1024的限定。
2:pollfd直接存储句柄和事件,所以无需再次重复重置句柄poll的优势主要是解决了select模型的前两项缺点1:无上线限制2:无需频繁的遍历重置读取句柄。
3.epollepoll在Linux2.6内核正式提出,是基于事件驱动的I/O方式Linux中提供的epoll相关函数接口如下:#include <sys/epoll.h>int epoll_create(int size);int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);epoll_create函数创建一个epoll句柄,参数size表明内核要监听的描述符数量(参数可忽略,无意义)。
调用成功时返回一个epoll句柄描述符,失败时返回-1。
epoll_ctl函数注册要监听的事件类型。
四个参数解释如下:epfd表示epoll句柄;op表示fd操作类型:EPOLL_CTL_ADD(注册新的fd到epfd中),EPOLL_CTL_MOD(修改已注册的fd的监听事件),EPOLL_CTL_DEL(从epfd 中删除一个fd)fd是要监听的描述符;event表示要监听的事件epoll_event结构体定义如下:struct epoll_event {__uint32_t events; /* Epoll events */epoll_data_t data; /* User data variable */ };typedef union epoll_data {void *ptr;int fd;__uint32_t u32;__uint64_t u64;} epoll_data_t;epoll_wait函数等待事件的就绪,成功时返回就绪的事件数目(有1个就直接返回1,有5个就返回5,自身会进行置位,把有消息的排序到前面),调用失败时返回 -1,等待超时返回 0。