第5章 CHAPTER 5 I/O端口扩展 没有足够的I/O引脚是单片机系统设计的瓶颈,本章利用8255A与移位寄存器实现I/O端口扩展。 5.1可编程并行接口8255A 5.1.1基本特性 8255A为可编程并行I/O接口芯片,具有3个8位并行I/O端口(A口、B口、C口),其中C口可分为2个4位并行I/O口使用,并具有按位复位/置位功能,兼容TTL/CMOS电平。 8255A地址线A1和A0与系统地址线A1A0连接,实现对8255A内部PA、PB、PC和控制端口的寻址,端口编址见表51。 表518255A端口编址 CSRDWRA1A0选 择 端 口传 送 方 向 00100读A端口PA→数据总线 00101读B端口PB→数据总线 00110读C端口PC→数据总线 01000写A端口PA←数据总线 01001写B端口PB←数据总线 01010写C端口PC←数据总线 01011写控制端口控制端口←数据总线 8255A具有3种工作方式。 方式0: 基本I/O方式,适用于端口A、端口B和端口C。 方式1: 选通I/O方式,适用于端口A和端口B。 方式2: 双向I/O方式,适用于端口A。 8255A定义工作方式控制字以设定8255A工作方式,定义见图51。 图518255A工作方式控制字定义 8255A定义端口C置位/复位控制字,对C口中的任意一位进行置位或者复位操作,定义见图52。 图52C口置位/复位控制字 5.1.2拨码开关与显示接口 1. 原理图 利用8255扩展8位输入和2个8位输出接口(见图53),定义PA口和PC口为工作方式0输出,定义PB口为工作方式0输入。拨码开关连接8255A的PB端口,8个LED指示条连接PA端口,指示拨码开关状态。2位7段LED显示器(BCD码输入)连接PC端口,以十六进制形式显示当前拨码值。 以3.1节的设计模块为主控单元,8255A片选信号连接系统地址译码信号Y1,8255A的PA口、PB口、PC口以及控制口地址见表52。 表528255A内部端口编址 CS(Y1)A15~A12A11~A2A1A0端 口 地 址 00001未用 00PA口: 1000H 01PB口: 1001H 10PC口: 1002H 11控制口: 1003H 图53拨码开关与显示接口 2. 参考程序 #include "reg51.h" #include #define P1A8255 XBYTE[0x1000] //PA地址定义 #define P1B8255 XBYTE[0x1001] //PB地址定义 #define P1C8255 XBYTE[0x1002] //PC地址定义 #define P1COM8255 XBYTE[0x1003] //控制口地址定义 void vDelay(unsigned int uiT ) { while(uiT--) ; } void main() { unsigned char ucD; P1COM8255=0x82; //定义PA、PC工作方式0输出,PB工作方式0输入 while(1) { ucD=P1B8255; //读拨码开关 P1A8255=ucD; //LED条显示 P1C8255=ucD; //数码显示 } } 5.1.3打印机接口 并行打印机接口标准Centronics规定了打印机接口的信号定义和数据传输时序。 1. 接口标准 完整的Centronics标准定义了36芯打印机接口,信号线定义见表53。 表53Centronics并行打印机接口标准 引脚号信号I/O功能引脚号信号I/O功能 1STB输入数据选通 13SLCT 输出 正常工作 2 D1 输入 数据线 14 AUTO 输入 自动走纸 3 D2 输入 数据线 16 逻辑地 4 D3 输入 数据线 17 机架地 5 D4 输入 数据线 19~30 地 6 D5 输入 数据线 31 INT 输入 复位 7 D6 输入 数据线 32 ERROR 输出 脱机出错 8 D7 输入 数据线 33 地 9 D8 输入 数据线 35 +5V 电源 10 ACK 输出 准备就绪 36 SLCTIN 出 工作允许 11 BUSY 输出 打印机忙 15/18/34 NC 未用 12 PE 输出 缺纸 表53中的输入和输出是相对打印机而言的,输入为控制信号线,输出为打印机状态线。 Centronics标准打印机接口数据传输时序见图54。 图54Centronics标准打印机接口数据传输时序 当CPU打印数据时,首先查询信号BUSY,当BUSY=0时,表明打印机处于不忙状态,将数据通过数据总线输出给接口,然后输出数据选通脉冲信号STB,将数据送入打印机内部数据锁存器。打印机在STB信号的上升沿将BUSY置1,表明打印机正在处理数据,不能接收新的数据。待输入数据处理完成,打印机输出ACK信号,表明打印机可以接收下一个数据。同时,在ACK下降沿,使BUSY复位,撤销忙状态标志,一个数据传输过程结束。 2. 接口电路 以3.1节的设计模块为主控单元,用1片8255A设计查询方式打印机接口电路见图55,8255A片选信号CS连接地址译码器输出信号Y1,8255A端口编址见表54。 图558255A打印机接口电路 端口A设置为方式0输出,输出打印数据,端口C高4位设置为输出方式,由PC7提供选通信号STB,端口C低4位设置为输入方式,由PC2接收打印机状态信号BUSY。 表548255A内部端口编址 CS(Y1) A15~A12A11~A2A1A0端 口 地 址 00001未用 00PA口: 1000H 01PB口: 1001H 10PC口: 1002H 11控制口: 1003H 3. 参考程序 # include # define COM8255 XBYTE[0x1003] # define PA8255 XBYTE[0x1000] # define PB8255 XBYTE[0x1001] # define PC8255 XBYTE[0x1002] void vPrinter(unsigned char *ucD) { while(*ucD!=’\0’) { while(0x04 & PC8255); //查询BUSY标志,等待打印机空闲状态PC2 PA8255=*ucD; //输出字符 COM8255=0X0E;COM8255=0X0E; //产生STB脉冲信号 COM8255=0X0F;COM8255=0X0F; ucD++; } } void main() { unsigned char Data[8]="WELCOME!"; COM8255=0x81; //设置A口方式0,输出;C口高4位输出,低4位输入 vPrinter(Data); //打印字符串 } 5.1.4键盘编码芯片74C922 1. 74C922 74C922为16键解码芯片,封装与引脚见图56。 图5674C922封装与引脚 74C922内部振荡器完成4×4键盘矩阵扫描、消抖和编码,矩阵键盘的4行分别连接74C922的Y1~Y4,4列分别连接X1~X4。有按键按下时,DA引脚输出高电平,同时封锁其他按键,片内锁存器保持当前按键的4位编码。74C922的键盘接口如图57所示。 2. 接口电路 键盘编码输出连接8255A的PB端口的PB0~PB3,DA连接INT0,在INT0中断处理程序中读按键编码,并在8255A的PA端口和PC端口显示。按键采用Proteus 的16键小键盘,其原理见图58。 图5774C922按键接口 图584×4矩阵键盘原理图 3. 参考程序 #include "reg51.h" #include #define uchar unsigned char #define uint unsigned int #define P1A8255 XBYTE[0x1000] //PA地址定义 #define P1B8255 XBYTE[0x1001] //PB地址定义 #define P1C8255 XBYTE[0x1002] //PC地址定义 #define P1COM8255 XBYTE[0x1003] //控制口地址定义 void vDelay(unsigned int uiT ) { while(uiT--) ; } void EINT0() interrupt 0 { uchar ucD; ucD=P1B8255; //读PB口 P1A8255=ucD;//PA、PC口输出 P1C8255=ucD; // } void delayms(uint j) { while (j--); } void main() { unsignedchar ucD; IE=0x81; //INT0中断允许 IT0=1; P1COM8255=0x82; //设定PA、PC为方式0输出,PB方式0输入 while(1); } 5.2移位寄存器扩展并行输入接口 5.2.1CD4014扩展并行输入接口 1. CD4014 CD4014为8位并入串出移位寄存器,可编程实现并行8位二进制数的锁存和移位,可级联,引脚定义及功能见图59。 图59CD4014引脚 引脚定义及功能:  D[7..0]——8位数据并行输入端。  SIN——串行数据输入端,用于多片CD4014级联。  CLK——时钟输入,用于串行移位和并行数据置位,上升沿有效。  P/——并/串选择,P/=1,并行置位工作方式,在CLK上升沿,将并行数据置入锁存。P/=0,串行移位工作方式。  Q7、Q6、Q5——移位寄存器高3位输出端。 2. 原理图 用2片CD4014级联,实现并行输入接口电路见图510。 信号定义及功能:  SCLK——串行移位/并行锁存时钟。  P/——工作模式选择,P/=0,串行移位工作方式; P/=1,并行数据置入方式,在CLK上升沿将并行数据D15~D0置入。  SERD——串行数据输出端。  DI[15..0]——并行数据输入端。  SIN——串行输入,CD4014级联引脚。 3. 工作过程 串行端口设置为工作方式0,即同步移位寄存器工作方式,TXD(P3.1)连接SCLK,输出移位脉冲,RXD(P3.0)连接SERD,接收来自CD4014的串行数据。 (1) P/=1,并行数据锁存。 (2) P/=0,移位模式,在CLK移位脉冲下,并行数据转化为串行数据从SERD输出。 4. 参考程序 #include #include sbit PL=P3^7; sbit PCLK=P3^1; void vDelay(unsigned int uiT) { 图510并行输入接口电路 while(uiT--); } void main() { unsigned char ucD=0,i; while(1) { PL=1; PCLK=0; PCLK=1; //并行数据锁存 PL=0; //串行移位工作方式 SCON=0x00; REN=1; while(!RI); ucD=SBUF; RI=0; P1=~ucD; vDelay(1000); while(!RI); ucD=SBUF; RI=0; P2=~ucD; } } 5.2.274HC165扩展并行输入接口 1. 74HC165 74HC165为8位并入串出移位寄存器,可编程实现并行8位二进制数的锁存和移位,可级联,其引脚见图511。 图51174HC165引脚 引脚定义及功能:  D[7..0]——8位并行输入端。  SI——串行数据输入端,用于多片级联。  CLK——时钟脉冲输入,用于串行移位,上升沿有效。  SH/LD——移位/置数端,SH/LD=1,移位工作方式,在CLK上升沿,串行移位; SH/LD=0,将并行数据置入,并行数据置入与时钟无关。  QH——串行数据输出。  QH——串行数据反相输出。  INH——时钟禁止端。 2. 原理图 用2片74HC165级联,实现16位并行输入接口,原理电路见图512。 图51216位并行输入接口电路(74HC165) 信号定义及功能:  CS——接口模块片选信号,输入,低有效。  CLK——串行移位/并行锁存时钟,输入。  S——工作模式选择,S=1,串行移位工作方式; S=0,并行数据置入方式,在CLK上升沿将并行数据置入。  SO——串行数据输出端。  DI[15..0]——16位并行数据输入端。 3. 工作过程 在CS有效情况下, S=0,2×8位并行数据锁存。 S=1,移位模式,在CLK移位脉冲下,16位并行数据转化为串行数据从SO输出。 4. Proteus仿真 功能: 用74HC165实现16位开关输入。 1) 同步移位寄存器工作方式 该模块可工作于MCS51串口工作方式0(同步移位寄存器工作方式),只需初始化串口为工作方式0,即可按串口接收模式读取数据,程序设计简单,但占用系统串口,工作原理见图513。 图513同步移位寄存器工作方式 (1) 信号定义。  CS: 直接接地,即INH=0,时钟允许。  CLK: 连接TXD,方式0时,产生移位脉冲。  SO: 连接RXD,同步方式接收串行数据。  S/: 连接AT89C51的P1.7,作为工作方式控制引脚,S/=0,并行数据锁存,S/=1,串行移位发送。 (2) 参考程序。 #include "reg51.h" #include /////////控制位定义/////// sbit SL=P1^7; sbit SLCLK=P3^1; //TXD void vDelay(unsigned int uiT ) { while(uiT--) ; } /////////读16位按键状态/// void main() { unsigned char ucData[2]; //存放按键状态 SL=1; SCON=0x00; //初始化串口为工作方式0,即移位寄存器方式 ucData[0]=SBUF; //读低8位键值 ucData[1]=SBUF; //读高8位键值 } 2) 模拟同步移位寄存器工作方式 为节省串口资源,可采用模拟串行工作方式0的方式,即采用3个I/O引脚,连接见图514。 引脚定义及功能: P2.2——控制74LS165工作模式,P2.2=0,锁存模式,P2.2=1,移位寄存器模式。 P2.1——模拟产生移位脉冲信号。 P2.0——串行数据输入端。 CS——直接接地,即INH=0,时钟允许。 5. 参考程序 在程序中实现串并转换,在CPU中得到16位并行数据,在P1和P3显示。 #include #include #define NOP()_nop_() sbitCLK= P2^1; sbitIN_PL= P2^2; sbitIN_Dat = P2^0; unsigned char ReHC74165(void) { unsigned char i,ucD; ucD=0; 图514模拟同步移位寄存器工作方式 for(i=0; i<8; i++) { ucD=ucD<<1; if(IN_Dat==1)ucD=ucD+1; CLK=0; NOP(); CLK=1; } return ucD; } void main() { while(1) { IN_PL=0; NOP(); IN_PL=1;NOP(); P1=ReHC74165(); //送两位七段LED显示器显示,BCD码 P3=ReHC74165(); //送两位七段LED显示器显示,BCD码 } } 5.3移位寄存器扩展并行输出接口 5.3.174HC164扩展并行输出接口 1. 74HC164 74HC164为串入并出移位寄存器,可级联,其引脚见图515。 图51574HC164引脚 引脚定义及功能:  Q[7..0]——8位并行输出。  A、B——串行数据输入。  MR——数据清零。  CP——移位时钟。 数据通过两个输入端(A和B)之一串行输入,任一端可用作高电平使能,控制另一端的输入。 2. 原理图 4片74HC164扩展输出接口,原理图见图516。 在图516中,信号定义如下:  DAT: 接收来自单片机串行数据。  SCLK: 移位时钟。 4片74HC164通过Q7级联,输入引脚A与B并接,作为串行数据输入端。利用P1.1产生移位脉冲,串行数据从P1.0输出。 3. 参考程序 #include #include 图516并行输出接口电路(74HC164) sbit DAT=P1^0; sbit CLK=P1^1; void vDelay(unsigned int uiT) { while(uiT--); } void vSendByte(unsigned char ucD) { unsigned char i; for(i=0;i<8;i++) { CLK=0;DAT=ucD&0x01;CLK=1; ucD=ucD>>1; } } void main() { unsigned char i; vSendByte(0x01); vSendByte(0x02); vSendByte(0x03); vSendByte(0x04); while(1); } 5.3.274HC595并行输出接口 1. 74HC595 1位串入8位并出移位寄存器,可级联,其引脚见图517。 图51774HC595引脚 引脚定义及功能:  Q[7..0]——8位并行输出。  Q7’——级联输出。  DS——串行数据输入。  MR——低电平时将74LS595数据清零。  SH_CP——移位时钟,在上升沿将数据移位,下降沿寄存器数据保持。  ST_CP——锁存时钟。  OE——输出使能。 2. 原理图 2片74HC595扩展16位并行输出接口电路见图518。 图518并行输出接口电路(74HC595) 在图518中,  OE——输出使能信号,接地。  MR——复位端,接高电平。  DS(U2)——单片机串行数据输入,接P3.4。  SH_CP——移位时钟,接P3.6。  ST_CP——锁存时钟,接P3.5。  Q0~Q7——并行输出。  SR——74HC595级联。 3. 参考程序 #include #include sbit SRCLK=P3^6; sbit RCLK=P3^5; sbit SER=P3^4; void Hc595SendByte(unsigned char dat); void Delay(unsigned int ) ; void main() { Hc595SendByte(0x55); Hc595SendByte(0xaa); while(1); } void Hc595SendByte(unsigned char dat) { unsigned char i; SRCLK = 1; RCLK = 1; for(i=0;i<8;i++) //发送8位数 { SER = dat >> 7; //从最高位开始发送 dat <<= 1; SRCLK = 0; //发送时序 _nop_(); _nop_(); SRCLK = 1; } RCLK = 0;_nop_(); _nop_(); RCLK = 1; } void Delay(unsigned int uiT) { while(uiT--); }