双向IO口.doc

合集下载

双向IO口与准双向IO口的区别

双向IO口与准双向IO口的区别

单片机P0‎口是双相口‎,而P1P2‎P3是准双‎相口。

举个例子:相信大家都‎理解准妈妈‎,就是怀孕的‎女人,当然这里也‎是这样的,就不是真正‎的双相口了‎。

为什么P0‎是双向口,这里的差别‎是什么呢?最主要原因‎是:P0没有上‎拉电阻,所以当P0‎最IO口的‎时候一定要‎加上上拉电‎阻,否则的话,你输出的1‎就是无效了‎,这样T2截‎止了,那么P0都‎就是呈现高‎阻状态了。

下图分别是‎P0,P1P2P‎3的读写数‎据,红线表示输‎出,蓝线表示输‎入(读引脚)还有一个就‎是读锁存器‎的,没画出来。

在读引脚的‎时候,有一点注意‎:每当读引脚‎的时候要确‎保场效应管‎T2是截止‎的,否则的话1‎(高电平)外部数据读‎不出来,T2会把它‎拉低,所以通过M‎O V PX,FFH,把T2截止‎,就完美了。

在单片机学‎习、开发和应用‎中,IO口的配‎置对功能的‎实现起着重‎要的作用,下面介绍常‎见的四种配‎置,而现在很多‎单片机都兼‎有这四种配‎置,可供选择。

一.准双向口配‎置如下图,当IO输出‎为高电平时‎,其驱动能力‎很弱,外部负载很‎容易将其拉‎至低电平。

当IO 输出‎为低电平时‎,其驱动能力‎很强,可吸收相当‎大的电流。

准双向口有‎三个上拉晶‎体管,一个“极弱上拉”,当端锁存器‎为逻辑“1”时打开,当端口悬空‎时,“极弱上拉”将端口上拉‎至高电平。

第二个上拉‎晶体管为“弱上拉”,当端口锁存‎器为逻辑“1”且端口本身‎也为“1”时打开,此上拉提供‎的电流,使准双向口‎输出为“1”。

如果此时端‎口被外部装‎置拉到逻辑‎“0”时,通过施密特‎触发器,控制“弱上拉”关闭,而“极弱上拉”维持开状态‎,为了把这个‎端口拉低,外部装置必‎须有足够的‎灌电流能力‎,使管脚上的‎电压,降到门槛电‎以下。

第三个上拉‎晶体管为“强上拉”,当端口锁存‎器由“0”跳变到“1”时,这个上拉用‎来加快端口‎由逻辑“0”到逻辑“1”的转换速度‎。

Verilog的双向IO口的实现 (

Verilog的双向IO口的实现 (

最近有一个项目要用到FPGA,还要用硬件描述语言综合出一个双向IO口用作地址数据总线。

一直没能够实现,在实验过程中遇到了或这或那的问题,终于在今天有所突破!能够正确的读写CAN控制芯片SJA1000的测试寄存器。

在试验中也总结了一些东西,如下:1、Inout口,一般要放在最顶层的V文件中,我试验过放到下面的v文件中,没能够成功(更正一下:inout并非一定要在最顶层,也可以在底层设置。

具体可参见黑金开发板建模篇实验13 DS1302实时时钟驱动。

)。

2、在一个module中,可以将输出定义为reg型,然后直接与要驱动module的wire型输入相连,没有问题。

3、在调试程序的过程中,尽量借助于工具,如quartus内部的Signal Tap。

之前一直不会使用,现在也在慢慢学习。

用来模拟的是intel模式的总线读写其时序图如下:代码包括下面的及部分:can_top.vmodule can_top(CLK,RSTn,Row_scan,Column_scan,can_pin,can_ALE,can_WR,can_RD,can_CS,can_dir,can_rst_out);input CLK;input RSTn;output [7:0] Row_scan;output [1:0] Column_scan;inout [7:0] can_pin;output can_ALE;output can_WR;output can_RD;output can_CS;output can_dir;output can_rst_out;wire [7:0] data_in;wire rmd;wire wmd;wire [7:0] adr;wire [7:0] data_tx;wire [7:0] data_rx;wire rd_flag;wire wr_flag;trans_control U3(.CLK(CLK),.RSTn(RSTn),.data_in(data_in),.Row_scan(Row_scan),.Column_scan(Column_scan) );wire can_rst;can_ctr U1(.CLK(CLK),.RSTn(RSTn),.rd_flag(rd_flag),.wr_flag(wr_flag),.data_rx(data_rx),.data_display(data_in), .rmd(rmd),.wmd(wmd),.adr(adr),.data_tx(data_tx),.can_rst(can_rst));can_op U2(.CLK(CLK),.RSTn(RSTn),.can_rst_in(can_rst),.rmd(rmd),.wmd(wmd),.adr(adr),.data_tx(data_tx),.can_in(can_in_temp),.en_out(en_out),.can_out(can_out),.read_cmd(read_cmd),.data_rx(data_rx),.can_ALE(can_ALE),.can_WR(can_WR),.can_RD(can_RD),.can_CS(can_CS),.can_dir(can_dir),.rd_flag(rd_flag),.wr_flag(wr_flag),.can_rst_out(can_rst_out));wire en_out;wire [7:0] can_out;// wire [7:0] can_in;reg [7:0] can_in_temp;wire read_cmd;always @ ( posedge CLK or negedge RSTn )beginif(!RSTn)can_in_temp<=8'b1000_1001;elsebeginif(read_cmd==1'b1)can_in_temp <= can_pin;endend// assign can_in = can_in_temp;assign can_pin = (en_out==1'b1)?can_out:8'bZZZZZZZZ; //双向口设置endmodulecan_ctr.vmodule can_ctr(CLK,RSTn,rd_flag,wr_flag,data_rx,data_display,rmd,wmd,adr,data_tx,can_rst);input CLK;input RSTn;input rd_flag;input wr_flag;input [7:0] data_rx;output [7:0] data_display;output rmd;output wmd;output [7:0] adr;output [7:0] data_tx;output can_rst;reg [7:0] data_display_temp;reg rmd_temp;reg wmd_temp;reg [7:0] adr_temp;reg [7:0] data_tx_temp;reg can_rst_temp;reg rst_flag;parameter TS = 26'd29_999_999; parameter T1S = 26'd49_999_999;always @ ( posedge CLK or negedge RSTn )beginif(!RSTn)begincan_rst_temp<=1'b1;rst_flag<=1'b1;endelse if (Count_Sec==26'd100 && rst_flag == 1'b1) begincan_rst_temp<=1'b0;rst_flag<=1'b0;endendalways @ ( posedge CLK or negedge RSTn )beginif(!RSTn)beginrmd_temp<=1'b0;wmd_temp<=1'b0;adr_temp<=8'b0000_0000;data_display_temp<= 8'b1000_1000;data_tx_temp<=8'b0000_0000;endelsebeginif (Count_Sec==TS)beginwmd_temp<=1'b1;adr_temp<=8'b0001_0000;data_tx_temp<=8'b0001_0010;endif (Count_Sec==T1S)beginrmd_temp<=1'b1;adr_temp<=8'b0001_0000; //读测试寄存器endif (wr_flag==1'b1)beginwmd_temp<=1'b0;endif (rd_flag==1'b1)beginrmd_temp<=1'b0;data_display_temp<= data_rx;endendendreg [25:0]Count_Sec;always @ ( posedge CLK or negedge RSTn ) if( !RSTn )Count_Sec <= 26'd0;else if( Count_Sec == T1S )Count_Sec <= 26'd0;elseCount_Sec <= Count_Sec + 1'b1;assign data_display=data_display_temp; assign rmd=rmd_temp;assign wmd=wmd_temp;assign adr=adr_temp;assign data_tx=data_tx_temp;assign can_rst=can_rst_temp;endmodulecan_op.vmodule can_op(CLK,RSTn,can_rst_in,rmd,wmd,adr,data_tx,can_in,en_out,can_out,read_cmd,data_rx,can_ALE,can_WR,can_RD,can_CS,can_dir,rd_flag,wr_flag,can_rst_out);input CLK;input RSTn;input can_rst_in;input rmd;input wmd;input [7:0]adr;input [7:0]data_tx;input [7:0]can_in;output en_out;output [7:0] can_out;output read_cmd;output [7:0]data_rx;output can_ALE;output can_WR;output can_RD;output can_CS;output can_dir;output rd_flag;output wr_flag;output can_rst_out;reg [7:0] can_out_temp;reg en_out_temp; //这两个变量来组成双向口输出控制reg read_cmd_temp;reg [7:0] data_rx_temp;reg can_ALE_temp;reg can_WR_temp;reg can_RD_temp;reg can_CS_temp;reg can_dir_temp;reg rd_flag_temp;reg wr_flag_temp;reg [3:0] count;always @ ( posedge CLK or negedge RSTn ) beginif ( !RSTn )beginrd_flag_temp<=1'b0;wr_flag_temp<=1'b0;can_WR_temp<=1'b1;can_RD_temp<=1'b1;can_CS_temp<=1'b1;can_dir_temp<=1'b0;data_rx_temp<=8'd221;count<= 4'd0;en_out_temp<=1'b1;can_out_temp<=8'd0;read_cmd_temp<=1'b0;endelsebeginif (rmd)begincase(count)4'd0,4'd1,4'd6: count<= count+1'b1; 4'd2:begincan_out_temp<= adr;en_out_temp<=1'b1;can_ALE_temp<= 1'b1;count<= count+1'b1;end4'd3:begincan_ALE_temp<=1'b0;count<= count+1'b1;end4'd4:begincan_CS_temp<= 1'b0;count<= count+1'b1;en_out_temp<=1'b0;end4'd5:begincan_RD_temp<= 1'b0;can_dir_temp=1'b1;count<= count+1'b1;end4'd7:beginread_cmd_temp<=1'b1;count<= count+1'b1;end4'd8:begincount<= count+1'b1;read_cmd_temp<=1'b0;end4'd9:begindata_rx_temp <= can_in;can_RD_temp<= 1'b1;count<= count+1'b1;can_dir_temp <= 1'b0;en_out_temp<=1'b1;end4'd10:begincan_CS_temp<= 1'b1;count<= count+1'b1;rd_flag_temp<=1'b1;end4'd11:begincount<=4'd0;rd_flag_temp<=1'b0;endendcaseendif (wmd)begincase(count)4'd0,4'd1: count<= count+1'b1; 4'd2:begincan_out_temp<= adr;en_out_temp<=1'b1;can_ALE_temp<= 1'b1;count<= count+1'b1;end4'd3:begincan_ALE_temp<=1'b0;count<= count+1'b1;end4'd4:begincan_CS_temp<= 1'b0;count<= count+1'b1;end4'd5:begincan_WR_temp<= 1'b0;count<= count+1'b1;end4'd6:begincan_out_temp<= data_tx;count<= count+1'b1; end4'd7:begincount<= count+1'b1;end4'd8:begincan_WR_temp<= 1'b1;count<= count+1'b1;end4'd9:begincan_CS_temp<= 1'b1;can_ALE_temp<=1'b1;count<= count+1'b1;wr_flag_temp<=1'b1;end4'd10:begincount<= 1'b0;wr_flag_temp<=1'b0; endendcaseendendendassign data_rx=data_rx_temp;assign can_ALE=can_ALE_temp;assign can_WR=can_WR_temp;assign can_RD=can_RD_temp;assign can_CS=can_CS_temp;assign can_dir=can_dir_temp;assign wr_flag=wr_flag_temp;assign rd_flag=rd_flag_temp;assign can_rst_out=can_rst_in;assign can_out=can_out_temp;assign en_out=en_out_temp;assign read_cmd=read_cmd_temp;endmoduletrans_control.v 这个与下面两个v文件是用来将接收到的数据显示到数码管上module trans_control(CLK,RSTn,data_in,Row_scan,Column_scan);input CLK;input RSTn;input [7:0] data_in;output [7:0] Row_scan;output [1:0] Column_scan;wire [7:0] data1_temp;wire [7:0] data2_temp;trans_module U1(.CLK (CLK),.RSTn (RSTn),.data_in (data_in),.out_data1 (data1_temp), .out_data2 (data2_temp) );scan_module U2(.CLK (CLK),.RSTn (RSTn),.scan_data1 (data1_temp), .scan_data2 (data2_temp), .Row_scan (Row_scan),.Column_scan (Column_scan) );endmoduletrans_module.vmodule trans_module(CLK,RSTn,data_in,out_data1,out_data2);input CLK;input RSTn;input [7:0] data_in;output [7:0] out_data1; output [7:0] out_data2;reg [7:0] out_data1_temp; reg [7:0] out_data2_temp;reg [3:0] temp1;reg [3:0] temp2;parameter _0 = 8'b1100_0000, _1 = 8'b1111_1001, _2 = 8'b1010_0100, _3 = 8'b1011_0000, _4 = 8'b1001_1001, _5 = 8'b1001_0010, _6 = 8'b1000_0010, _7 = 8'b1111_1000, _8 = 8'b1000_0000,_9 = 8'b1001_0000, _A = 8'b1000_1000, _B = 8'b1000_0011,_C = 8'b1100_0110, _D = 8'b1010_0001, _E = 8'b1000_0100,_F = 8'b1000_1110;always @ ( posedge CLK or negedge RSTn )if( !RSTn )beginout_data1_temp<= 8'b1100_0000;out_data2_temp<= 8'b1100_0000;temp1 <= 4'd0;temp2 <= 4'd0;endelsebegintemp1 <= data_in[3:0];temp2 <= data_in[7:4];case(temp1)4'h0 : out_data1_temp <= _0;4'h1 : out_data1_temp <= _1;4'h2 : out_data1_temp <= _2;4'h3 : out_data1_temp <= _3;4'h4 : out_data1_temp <= _4;4'h5 : out_data1_temp <= _5;4'h6 : out_data1_temp <= _6;4'h7 : out_data1_temp <= _7;4'h8 : out_data1_temp <= _8;4'h9 : out_data1_temp <= _9;4'hA : out_data1_temp <= _A;4'hB : out_data1_temp <= _B;4'hC : out_data1_temp <= _C;4'hD : out_data1_temp <= _D;4'hE : out_data1_temp <= _E;4'hF : out_data1_temp <= _F;endcasecase(temp2)4'h0 : out_data2_temp <= _0;4'h1 : out_data2_temp <= _1;4'h2 : out_data2_temp <= _2;4'h3 : out_data2_temp <= _3;4'h4 : out_data2_temp <= _4;4'h5 : out_data2_temp <= _5;4'h6 : out_data2_temp <= _6;4'h7 : out_data2_temp <= _7;4'h8 : out_data2_temp <= _8;4'h9 : out_data2_temp <= _9;4'hA : out_data2_temp <= _A;4'hB : out_data2_temp <= _B;4'hC : out_data2_temp <= _C;4'hD : out_data2_temp <= _D;4'hE : out_data2_temp <= _E;4'hF : out_data2_temp <= _F;endcaseendassign out_data1 = out_data1_temp;assign out_data2 = out_data2_temp;endmodulescan_module.vmodule scan_module(CLK,RSTn,scan_data1,scan_data2,Column_scan,Row_scan);input CLK;input RSTn;input [7:0] scan_data1;input [7:0] scan_data2;output [7:0] Row_scan;output [1:0] Column_scan;parameter T10MS = 19'd499_999;//50M*0.01-1=499_999reg [18:0]Count1;always @ ( posedge CLK or negedge RSTn )if( !RSTn )Count1 <= 19'd0;else if( Count1 == T10MS )Count1 <= 19'd0;elseCount1 <= Count1 + 19'b1;reg [1:0]t;always @ ( posedge CLK or negedge RSTn )if( !RSTn )t <= 2'd0;else if( t == 2'd2 )t <= 2'd0;else if( Count1 == T10MS )t <= t + 1'b1;reg [7:0] Row_scan_temp;reg [1:0] Column_scan_temp;always @ ( posedge CLK or negedge RSTn )if( !RSTn )beginColumn_scan_temp <= 2'b01;Row_scan_temp <= 8'hd0;endelse if( Count1 == T10MS )case( t )2'd0 : begin Column_scan_temp <= 2'b01; Row_scan_temp <= scan_data1; end 2'd1 : begin Column_scan_temp <= 2'b10; Row_scan_temp <= scan_data2; end endcaseassign Column_scan = Column_scan_temp;assign Row_scan = Row_scan_temp;endmodule代码就这些,还有TCL引脚说明#------------------GLOBAL--------------------#set_global_assignment -name RESERVE_ALL_UNUSED_PINS "AS INPUT TRI-STATED" set_global_assignment -name ENABLE_INIT_DONE_OUTPUT OFF#复位引脚set_location_assignment PIN_M1 -to RSTn#时钟引脚set_location_assignment PIN_R9 -to CLK#数码管对应的引脚set_location_assignment PIN_M8 -to Row_scan[0]set_location_assignment PIN_L7 -to Row_scan[1]set_location_assignment PIN_P9 -to Row_scan[2]set_location_assignment PIN_N9 -to Row_scan[3]set_location_assignment PIN_M9 -to Row_scan[4]set_location_assignment PIN_M10 -to Row_scan[5]set_location_assignment PIN_P11 -to Row_scan[6]set_location_assignment PIN_N11 -to Row_scan[7]set_location_assignment PIN_N8 -to Column_scan[0]set_location_assignment PIN_P8 -to Column_scan[1]#CAN控制信号对应引脚set_location_assignment PIN_R1 -to can_pin[0]set_location_assignment PIN_R3 -to can_pin[1]set_location_assignment PIN_L3 -to can_pin[2]set_location_assignment PIN_K5 -to can_pin[3]set_location_assignment PIN_P3 -to can_pin[4]set_location_assignment PIN_L8 -to can_pin[5]set_location_assignment PIN_N5 -to can_pin[6]set_location_assignment PIN_K6 -to can_pin[7]set_location_assignment PIN_L6 -to can_ALEset_location_assignment PIN_T3 -to can_WRset_location_assignment PIN_L4 -to can_RDset_location_assignment PIN_N3 -to can_CSset_location_assignment PIN_T2 -to can_dirset_location_assignment PIN_P2 -to can_rst_out。

单片机IO端口工作原理(P0端口,漏极开路,推挽,上拉电阻,准双向口)

单片机IO端口工作原理(P0端口,漏极开路,推挽,上拉电阻,准双向口)

单片机IO端口工作原理(P0端口,漏极开路,推挽,上拉电阻,准双向口)一、P0端口的结构及工作原理P0端口8位中的一位结构图见下图:输入缓冲器:在P0口中,有两个三态的缓冲器,三态门有三个状态,即在其的输出端可以是高电平、低电平,同时还有一种就是高阻状态。

图中有一个是读锁存器的缓冲器,也就是说,要读取D锁存器输出端Q的数据,那就得使读锁存器的这个缓冲器的三态控制端(上图中标号为‘读锁存器’端)有效。

图中另一个是读引脚的缓冲器,要读取P0.X引脚上的数据,也要使标号为‘读引脚’的这个三态缓冲器的控制端有效,引脚上的数据才会传输到我们单片机的内部数据总线上。

D锁存器:一个触发器可以保存一位的二进制数(即具有保持功能),在51单片机的32根I/O口线中都是用一个D触发器来构成锁存器的。

图中的锁存器,D 端是数据输入端,CP是控制端(也就是时序控制信号输入端),Q是输出端,Q 非是反向输出端。

对于D触发器来讲,当D输入端有一个输入信号,如果这时控制端CP没有信号(也就是时序脉冲没有到来),这时输入端D的数据是无法传输到输出端Q及反向输出端Q非的。

如果时序控制端CP的时序脉冲一旦到了,这时D端输入的数据就会传输到Q及Q非端。

数据传送过来后,当CP时序控制端的时序信号消失了,这时,输出端还会保持着上次输入端D的数据(即把上次的数据锁存起来了)。

如果下一个时序控制脉冲信号来了,这时D端的数据才再次传送到Q端,从而改变Q端的状态。

多路开关:在51单片机中,当内部的存储器够用(也就是不需要外扩展存储器时,这里讲的存储器包括数据存储器及程序存储器)时,P0口可以作为通用的输入输出端口(即I/O)使用,对于8031(内部没有ROM)的单片机或者编写的程序超过了单片机内部的存储器容量,需要外扩存储器时,P0口就作为‘地址/数据’总线使用。

那么这个多路选择开关就是用于选择是做为普通I/O口使用还是作为‘数据/地址’总线使用的选择开关了。

单片机IO端口工作原理(P0端口,漏极开路,推挽,上拉电阻,准双向口)

单片机IO端口工作原理(P0端口,漏极开路,推挽,上拉电阻,准双向口)

单片机IO端口工作原理(P0端口,漏极开路,推挽,上拉电阻,准双向口)一、P0端口的结构及工作原理P0端口8位中的一位结构图见下图:输入缓冲器:在P0口中,有两个三态的缓冲器,三态门有三个状态,即在其的输出端可以是高电平、低电平,同时还有一种就是高阻状态。

图中有一个是读锁存器的缓冲器,也就是说,要读取D锁存器输出端Q的数据,那就得使读锁存器的这个缓冲器的三态控制端(上图中标号为‘读锁存器’端)有效。

图中另一个是读引脚的缓冲器,要读取P0.X引脚上的数据,也要使标号为‘读引脚’的这个三态缓冲器的控制端有效,引脚上的数据才会传输到我们单片机的内部数据总线上。

D锁存器:一个触发器可以保存一位的二进制数(即具有保持功能),在51单片机的32根I/O口线中都是用一个D触发器来构成锁存器的。

图中的锁存器,D 端是数据输入端,CP是控制端(也就是时序控制信号输入端),Q是输出端,Q 非是反向输出端。

对于D触发器来讲,当D输入端有一个输入信号,如果这时控制端CP没有信号(也就是时序脉冲没有到来),这时输入端D的数据是无法传输到输出端Q及反向输出端Q非的。

如果时序控制端CP的时序脉冲一旦到了,这时D端输入的数据就会传输到Q及Q非端。

数据传送过来后,当CP时序控制端的时序信号消失了,这时,输出端还会保持着上次输入端D的数据(即把上次的数据锁存起来了)。

如果下一个时序控制脉冲信号来了,这时D端的数据才再次传送到Q端,从而改变Q端的状态。

多路开关:在51单片机中,当内部的存储器够用(也就是不需要外扩展存储器时,这里讲的存储器包括数据存储器及程序存储器)时,P0口可以作为通用的输入输出端口(即I/O)使用,对于8031(内部没有ROM)的单片机或者编写的程序超过了单片机内部的存储器容量,需要外扩存储器时,P0口就作为‘地址/数据’总线使用。

那么这个多路选择开关就是用于选择是做为普通I/O口使用还是作为‘数据/地址’总线使用的选择开关了。

准双向io口构成原理

准双向io口构成原理

准双向io口构成原理准双向IO口是指可以在输入和输出之间切换的IO口。

在单片机中,IO口是非常重要的,它可以连接外部设备,实现数据的输入和输出。

准双向IO口的构成原理是通过控制寄存器来实现输入和输出的切换。

在单片机中,每个IO口都有一个对应的寄存器,称为控制寄存器。

控制寄存器中的位可以控制IO口的输入和输出状态。

当控制寄存器中的某一位被设置为1时,IO口就被设置为输出状态,可以向外部设备输出数据;当控制寄存器中的某一位被设置为0时,IO口就被设置为输入状态,可以从外部设备读取数据。

准双向IO口的实现原理是通过控制寄存器中的位来实现输入和输出的切换。

当需要将IO口设置为输出状态时,将控制寄存器中对应的位设置为1;当需要将IO口设置为输入状态时,将控制寄存器中对应的位设置为0。

这样就可以实现在输入和输出之间的切换。

准双向IO口的优点是可以节省IO口的数量,同时也可以减少外部设备的数量。

在某些应用中,需要同时进行输入和输出操作,如果使用普通的IO口,就需要使用两个IO口,一个用于输入,一个用于输出。

而使用准双向IO口,只需要一个IO口就可以实现输入和输出的切换,可以节省IO口的数量,减少外部设备的数量。

准双向IO口的应用非常广泛,例如在数字电路中,可以使用准双向IO口来实现数据的输入和输出;在控制系统中,可以使用准双向IO口来控制外部设备的状态;在通信系统中,可以使用准双向IO口来实现数据的传输和接收。

总之,准双向IO口是一种非常实用的IO口类型,它可以实现输入和输出的切换,节省IO口的数量,减少外部设备的数量,应用非常广泛。

在单片机的开发中,需要根据具体的应用场景选择合适的IO口类型,以实现最佳的性能和功能。

单片机IO口推挽、开漏输出、准双向IO详解

单片机IO口推挽、开漏输出、准双向IO详解

单片机IO口推挽、开漏输出、准双向IO详解加入论坛的方式:在公众号对话框内,输入数字“1”,即可进入论坛,无需注册,就是这么简单。

诚邀您的加入。

在学单片机和选用逻辑器件的时候我们常别人说这款芯片是推挽输出驱动能力强,这个引脚是开漏输出需要加上拉电阻。

是不是有时候感觉一头雾水?今天就详解一下推挽和开漏,以后你买芯片的时候就可以和别人大声理论了。

1. 什么是推挽输出推挽输出既可以输出低电平,也可以输出高电平,可以直接驱动功耗不大的数字器件。

2. 推挽输出电路的结构推挽电路是由两个三极管或MOSFET,以推挽方式存在于电路中,电路工作时,两只对称的开关管每次只有一个导通,所以导通损耗小、效率高、既提高电路的负载能力,又提高开关速度。

其示意结构如下图所示:1. 当内部输出1电平时,上边的MOS管导通同时下边的MOS管截至,IO口输出高电平;2. 当内部输出0电平时,上边的MOS管截至同时下边的MOS管导通,IO口输出低电平;3. 什么是开漏输出开漏输出只能输出低电平,如果要输出高电平必须通过上拉电阻才能实现。

就类似于三极管的集电极输出。

4. 开漏输出电路的结构如上图:1. 内部输出1时MOS管截止,输出与地断开,这时候IO口其实是没有驱动能力的,需要外部连接上拉电阻才能输出高电平,才能驱动数字器件;2. 内部输出0时MOS管导通,输出低电平,所以开漏能输出低电平;5. 准双向IO在学51单片机的时候老师告诉我们,51单片机的IO口是准双向的,什么是准双向的?示意如下:其结构类似于开漏输出,只不过是把上拉电阻集成到了单片机内部。

6. IO口如何应用对于推挽输出的IO口可以直接输出高低电平驱动功耗较小的数字器件,但对于开漏输出的话必须要在外部接上拉电阻才行。

比如说LPC11C14单片机的片上I2C资源就是开漏输出的,如果要使用这两个引脚做输出就必须加上拉电阻,如下图所示:进入论坛的方式:在公众号对话框内,输入数字“1”,即可进入论坛,无需注册,就是这么简单。

FPGA中双向端口IO的研究

FPGA中双向端口IO的研究

图1双向端口的硬件图当z=0时,上面输出的管子开通,此时数据可以从上面的管子中输出,这时双向端口就作为输出口;当z =1时,上面的管子被置为高阻态,数据不能从上面的管子输出,此时数据只可以从下面的管子由外向内输入,这时的双向端口是输入口。

限于篇幅,我们做一个简单的模型来说明双向端口的设计。

下面我们用V e r i l o g 硬件语言进行双向端口的程序设计,为了看出双向端口分别作为输!"入端口和输出端口的功能,我们的模块分别定义一个数据输入口d i n 和一个数据输出口d o u t ,一个三态门选通信号z ,触发时钟c l k ,还有双向端口d i -n o u t。

我们设数据为8位宽。

图2为该模块图:图2定义的模块图输入口d i n 定义:i n pu t [7:0]d i n ;当双向端口d i n o u t 作为输出口时,我们从d i n 端口输入数据到模块中,让数据从d i n o u t 口出来。

输出口d o u t 定义:o u t pu t [7:0]d o u t ;当双向端口d i n o u t 作为输入口时,我们让数据从d i n o u t 口输入,从输出口d o u t 输出。

双向端口di n o u t 定义:i n o u t [7:0]d i n o u t ; 三态门选通信号z :i n p u t z ; 当z=1时,把三态门置为高阻态,这时d i n o u t 作为输入口用;当z =0时,开通三态门,这时d i n o u t 作为输出口用。

三态门控制语句为:a s s i g nd i n o u t =(!z )?d i n _r e g :8'b z ; 总的完整程序如下:mo d u l e d i n o u t (d i n ,z ,c l k ,d o u t ,d i n o u t ); i n p u t [7:0]d i n ; i n pu t z ; i n pu t c l k ; o u t pu t [7:0]d o u t ;i n o u t [7:0]d i n o u t ; r e g [7:0]d o u t ; r e g [7:0]d i n _r e g; a s s i g nd i n o u t =(!z )?d i n _r e g:8'b z ; a l w a y s @(p o s e d g e c l k ) b e gi n i f (!z)d i n _r e g =d i n ;e l s ed o u t =d i n o u t ;e n dEn d m o d u l e 2 仿真及初始化双向端口下面我们对上述程序进行时序仿真。

单片机的几种IO口配置

单片机的几种IO口配置


准双向口有三个上拉晶体管,一个“极弱上拉”,当端锁存器为逻辑“1”时打 开,当端口悬空时,“极弱上拉”将端口上拉至高电平。
第二个上拉晶体管为“弱上拉”,当端口锁存器为逻辑“1”且端口本身也为“1” 时打开,此上拉提供的电流,使准双向口输出为“1”。如果此时端口被外部装 置拉到逻辑“0”时,通过施密特触发器,控制“弱上拉”关闭,而“极弱上拉” 维持开状态,为了把这个端口拉低,外部装置必须有足够的灌电流能力,使管脚 上的电压,降到门槛电以下。
开漏输出配置与准又向口相似,但内部没有上拉电阻。有很好的电气兼容性,外 部接上拉电阻到 3V 电源,就能和 3V 逻辑器件连接。外部接上拉电阻到 5V 电源, 就要以和 5V 器件连接。
需要说明的是以上四种配置均可以作为输入,也就是都可以检测端的逻辑状态, 但其特性不同,不是每种配置都可以直接接按键。
四.仅为输入配置(高阻配置) 这种配置不能输出电流,也不能有收电流,只能作为输入数据使用。
以上四种配置各有其特点,在使用中应根据其特点灵活运用。 准双向口的最大特点是既可以作为输入,也可以作为输出,不需要通过控制切换。 推挽输出的特点是,无论输也高电平还是低电平都有较大的驱动能力,在输也高 电平时,也能直接点亮 LED,这在准双向口中是不能办到的。这种配置不宜作为 输入,因为这需要外部设备有很强的拉电流的能胃。 仅为输入配置的特点是端口只能作为输入使用,可以获得很高的输入阻抗,在有 模拟比较器或 ADC 的端口中用得较多。
单片机的几种 IO 口配置
在单片机学习、开发和应用中,IO 口的配置对功能的实现起着重要的作用,下 面介绍常见的四种配置,而现在很多单片机都兼有这四种配置,可供选择。
一.准双向口配置
如下图,当 IO 输出为高电平时,其驱动能力很弱,外部负载很容易将其拉至低 电平。当 IO 输出为低电平时,其驱动能力很强,可吸收相当大的电流。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

:准双向一般只能用于数字输入输出,输入时为弱上拉状态(约50K上拉),端口只有两种状态:高或低。

2:双向除用于数字输入输出外还可用于模拟输入输出,模拟输入时端口通过方向控制设置成为高阻输入状态。

双向端口有三种状态:高、低或高阻。

3:初始状态和复位状态下准双向口为1,双向口为高阻状态.有带些比较器的单片机,比较器的输入端只能做在双向口,不能做在准双向口.所以软件设计的第一步就是对 I/O 口的设置.
标准51内核单片机的IO口,P0口则为双向三态输入输出口,P1\P2\P3是准双向IO口,没有方向控制,做输入时需要先往端口数据寄存器写1才行(也可看作此时为输出,端口输出高电平)。

对单片机的控制,其实就是对I/O口的控制,无论单片机对外界进行何种控制,或接受外部的何种控制,都是通过I/O口进行的。

51单片机总共有P0、P1、P2、P3四个8位双向输入输出端口,每个端口都有锁存器、输出驱动器和输入缓冲器。

4个I/O端口都能作输入输出口用,其中P0和P2通常用于对外部存储器的访问。

51系列单片机有4个I/O端口,每个端口都是8位准双向口,共占32根引脚。

每个端口都包括一个锁存器(即专用寄存器P0~P3)、一个输出驱动器和输入缓冲器。

通常把4个端口笼统地表示为P0~P3。

在无片外扩展存储器的系统中,这4个端口的每一位都可以作为准双向通用I/O 端口使用。

在具有片外扩展存储器的系统中,P2口作为高8位地址线,P0口分时作为低8位地址线和双向数据总线。

51单片机4个I/O端口线路设计的非常巧妙,学习I/O端口逻辑电路,不但有利于正确合理地使用端口,而且会给设计单片机外围逻辑电路有所启发。

下面简单介绍一下输入/输出端口结构。

1.P0口和P2的结构
1.1 P0口的结构:下图为P0口的某位P0.n(n=0~7)结构图,它由一个输出锁存器、两个三态输入缓冲器和输出驱动电路及控制电路组成。

从图中可以看出,P0口既可以作为I/O用,也可以作为地址/数据线用。

.2 P0口作为普通I/O口:
①输出时,CPU发出控制电平“0”封锁“与”门,将输出上拉场效应管T1截止,同时使多路开关MUX把锁存器与输出驱动场效应管T2栅极接通。

故内部总线与P0口同相。

由于输出驱动级是漏极开路电路,若驱动NMOS或其它拉流负载时,需要外接上拉电阻。

P0的输出级可驱动8个LSTTL负载。

②输入时----分读引脚或读锁存器
读引脚:由传送指令(MOV)实现;
下面一个缓冲器用于读端口引脚数据,当执行一条由端口输入的指令时,读脉冲把该三态缓冲器打开,这样端口引脚上的数据经过缓冲器读入到内部总线。

读锁存器:有些指令如:ANL P0,A称为“读-改-写”
指令,需要读锁存器。

上面一个缓冲器用于读端口锁存器数据。

**原因:如果此时该端口的负载恰是一个晶体管基极,且原端口输出值为1,那么导通了的PN结会把端口引脚高电平拉低;若此时直接读端口引脚信号,将会把原输出的“1”电平误读为“0”电平。

现采用读输出锁存器代替读引脚,图中,上面的三态缓冲器就为读锁存器Q端信号而设,读输出锁存器可避免上述可能发生的错误。

**
说明:

P0口必须接上拉电阻;

在读信号之前数据之前,先要向相应的锁存器做写1操作的I/O口称为准双向口;

三态输入缓冲器的作用:

(ANL P0,A)
准双向口:
从图中可以看出,在读入端口数据时,由于输出驱动FET并接在引脚上,如果T2导通,就会将输入的高电平拉成低电平,产生误读。

所以在端口进行输入操作前,应先向端口锁存器写“1”,使T2截止,引脚处于悬浮状态,变为高阻抗
输入。

这就是所谓的准双向口。

2、P0作为地址/数据总线
在系统扩展时,P0端口作为地址/数据总线使用时,分为:
(1) P0引脚输出地址/数据信息: CPU发出控制电平“1”,打开“与”门,又使多路开关MUX把CPU的地址/数据总线与T2栅极反相接通,输出地址或数据。

由图上可以看出,上下两个FET处于反相,构成了推拉式的输出电路,其负载能
力大大增强。

P0作为地址/数据总线----真正的双向口
(2)P0引脚输出地址/输入数据:
输入信号是从引脚通过输入缓冲器进入内部总线。

此时,CPU自动使MUX向下,并向P0口写“1”,“读引脚”控制信号有效,下面的缓冲器打开,外部数据读
入内部总线。

二、P2的内部结构
2.1 .P2口作为普通I/O口:CPU发出控制电平“0”,使多路开关MUX倒向锁
存器
输出Q端,构成一个准双向口。

其功能与P1相同。

2.2 .P2口作为地址总线:在系统扩展片外程序存储器扩展数据存储器且容量超过256B (用MOVX @DPTR指令)时,CPU发出控制电平“1”,使多路开关MUX 倒内部地址线。

此时,P2输出高8位地址。

三.P1口、P3口的内部结构
①P1口的一位的结构
它由一个输出锁存器、两个三态输入缓冲器和输出驱动电路组成----准双向口。

②P3的内部结构
一、作为通用I/O口与P1口类似----准双向口(W=1)
二、P3第二功能(Q=1)
此时引脚部分输入(Q=1、W=1) ,部分输出(Q=1、W输出) 。

P3第二功能各引脚功能定义:
P3.0:RXD串行口输入
P3.1:TXD串行口输出
P3.2:INT0外部中断0输入
P3.3:INT1外部中断1输入
P3.4:T0定时器0外部输入
P3.5:T1定时器1外部输入
P3.6:WR外部写控制
P3.7:RD外部读控制
综上所述:当P0作为I/O口使用时,特别是作为输出时,输出级属于开漏电路,必须外接上拉电阻才会有高电平输出;如果作为输入,必须先向相应的锁存器写“1”,才不会影响输入电平。

当CPU内部控制信号为“1”时,P0口作为地址/数据总线使用,这时,P0口就无法再作为I/O口使用了。

P1、P2 和P3 口为准双向口, 在内部差别不大, 但使用功能有所不同。

P1口是用户专用 8 位准双向I/O口, 具有通用输入/输出功能, 每一位都能独立地设定为输入或输出。

当有输出方式变为输入方式时, 该位的锁存器必须写入“1”, 然后才能进入输入操作。

P2口是 8 位准双向I/O口。

外接I/O设备时, 可作为扩展系统的地址总线, 输出高8位地址, 与P0 口一起组成 16 位地址总线。

对于 8031 而言, P2 口一般只作为地址总线使用, 而不作为I/O线直接与外部设备相连。

相关文档
最新文档