精华内容
下载资源
问答
  • 计算机组成:IO

    2021-07-17 06:09:40
    一、概述IO 编址I/O 与内存统一编址:与主存单元地址完全一样的格式,无需专门安排专门的 I/O 指令I/O 独立编址:CPU 通过专门的 I/O 指令来访问 I/O 地址空间,I/O 设备有一套完全不同于主存地址格式的地址编码,...

    一、概述

    20cc5ad27bf1c1bb4b1edd4bb4cda405.png

    IO 编址

    I/O 与内存统一编址:与主存单元地址完全一样的格式,无需专门安排专门的 I/O 指令

    I/O 独立编址:CPU 通过专门的 I/O 指令来访问 I/O 地址空间,I/O 设备有一套完全不同于主存地址格式的地址编码,称为设备号(码)​

    二、IO 设备

    键盘

    e638a3cbde40da56db192bbb22d5a217.png

    内部结构:矩阵排列,间开关在内部按照 n × m 的矩阵排列,行列交叉点上放置键开关

    88fe35af38e7c31d468415c0991b3cd8.png

    扫描方式

    无编码键盘:通过软件对键盘定期扫描来检查有无按键,并由程序查表产生编码

    编码键盘:由硬件确认按下的键并自动产生相应的编码

    显示器

    性能指标

    分辨率:显示器所能表示的像素个数

    灰度级

    黑白显示器:像素点的亮暗级差

    彩色显示器:像素点的颜色种类,一般为 64 ~ 256 级

    扫描方式(老式荧光屏幕)

    随机扫描:电子束在荧光品上按照所显示的图形或字符形状位置移动,不必扫描全部屏幕

    光栅扫描:电子束周期性扫描全屏,电子束通过需要西安市的信息位置时,点亮像素点,不需要的地方则消隐

    CRT 字符显示器

    远古级显示设备,通过了解它了解显示器的设计思路:

    f6537c8a7f3c8d4fb4b5331eceae3583.png

    字符显示原理:点阵法

    5fed49da4b05f445a7d956c187a08472.png

    VRAM:显示存储器,存放整屏字符是 ASCII 码信息。VRAM 地址 = 字符所在行号 × 一行字符数 + 列号

    高位:屏幕行号(排号)

    低位:屏幕列号

    ROM:字符发生器,把字符点阵用二进制编码矩阵表示,存入 ROM,显示时根据字符的 ASCII 码将点阵信息从 ROM 中读出

    高位: ASCII 码

    低位:字符点阵的行号

    66b4bf774f07a58ae0e3531ed96bb7df.png

    显示定时控制:提供 CRT 屏幕刷新过程中的定时信号

    c3c0578d889728cba286c59fad2c55cc.png

    点振荡器:产生点时钟,控制视频信号输出

    点计数器:产生字符时钟,控制一位寄存器加载

    字计数器:产生行时钟,控制水平消隐和水平同步

    行计数器:产生排时钟,计数值作为 ROM 低位地址,控制字符行间隔消隐

    排计数器:计数值作为 VRAM 高位地址,控制垂直回扫和垂直同步

    例题

    621acfa690f79ad408806607ae579c27.png

    CRT 图形显示器

    将整个屏幕的每个像素信息窜在视频存储器中,显示时依次取出像素信息,控制电子束逐行逐点显示:

    7f2df5a172feae854c26fd08d21b44f8.png

    打印机

    介绍一种比较简单的打印设备——点阵针式打印机,和 CRT 字符显示器一个套路:

    393cdc01e48823b2f2c8e1ececd8c76c.png

    三、IO 接口

    2b61222ff7e826e7816e86bd77f4a72f.png

    数据传输方式

    并行传输

    55b41467f2a0dc4af0dc457925191ee2.png

    串行传输

    同步

    f84b86efbaae2a4fb289511711f903c1.png

    异步

    15dca4c9f7ca8d5dcdf1c14ca246139f.png

    控制方式

    程序查询(轮询)

    9269c52a962455e7b2a3af4104ee26f2.png

    举例

    1fb2d544e9bb81cf2d104f9a6a672c49.png

    0996ed1a919d3b7ec36f465cfedc179e.png

    程序中断

    8e17e39a92fda71f7bce7bde9ad2252e.png

    举例

    15bc2f335bcdb2ee7a5bf275eedaaa65.png

    893ddded9e19d6c94ba1eed91fd9d120.png

    中断嵌套

    中断的嵌套处理收以下两个量的影响

    优先级:中断的响应次序,仅允许优先级别低的中断嵌套优先级别高的中断

    屏蔽字:中断的处理次序,设置屏蔽字可改变中断的优先级

    b446a7ae114d2f14bdc7fa37531708f4.png

    e098b08c4fe463a1720492d986ee95e6.png

    DMA

    DMA,Direct memory Access,直接存储器访问,是在高速 IO 设备进行直接、自动、批量数据传送,从而减少 CPU 干预的 IO 控制方式,适合连续大规模数据传输。

    5d887aadfe101aaa27cda2a88dd4bfc2.png

    工作流程

    预处理:CPU 运行一段程序向 DMA 控制器送命令和传送的初始参数

    数据传送:在 DMA 控制器的控制下,IO 与主存交换数据

    后处理:CPU 相应 DMA 中断后,通过中断服务程序进行 DMA 结束工作

    996f3f8db311f7d55bea99654f6b78b7.png

    1bb9b88a0108b9f4ad97f0d6ff70f101.png

    展开全文
  • 目录硬知识IO 扩展芯片 TCA6416ATAC6416A 的寄存器IO 输入寄存器IO 输出寄存器IO 反相寄存器IO 方向寄存器TCA6416A 的操作TCA6416A 写数据TCA6416A 读数据TCA6416A 的 IO 输入寄存器硬件布局示例程序TCA6416A.cTCA...

    普中51-单核-A2
    STC89C52
    MSP430G2553 Launchpad 扩展板
    Keil uVision V5.29.0.0
    PK51 Prof.Developers Kit Version:9.60.0.0
    上位机:Vofa+ 1.3.10


           摘自《Launchpad口袋实验平台(指导书)》、《AY-G2PL KIT_用户手册》

    硬知识

           对于低速的 IO,可以通过串行转并行的方法扩展。1 片 I2C 接口控制的 IO 扩展芯片 TCA6416A可为 单片机额外扩展出 16 个双向 IO。
           扩展输出口的方法其实就是将串行数据转为并行数据输出,串入并出移位寄存器加一个锁存器就可以将串行转并行输出(也就是扩展了 IO 口),比如 74 系列通用数字逻辑器件74HC595,可以任意级联扩展输出口。
           串行转并行的代价就是速度会变慢,理论上,1 串转 16 并输出,速度至少要降 16 倍。假如普通 IO 翻转电平的速度是 1MHz,转 16 并输出后,速度将降为 62.5kHz。这个速度对于很多应用已绰绰有余,比如和人有关的输入输出设备(键盘、段式 LCD/LED 驱动、点阵LCD/LED 驱动等)。
           扩展输入口的方法类似,只不过使用的是并入串出的移位寄存器。

    IO 扩展芯片 TCA6416A

           类似 74HC595 的串并转换芯片虽然廉价,但是它只能扩展输出口,不能同时扩展出双向IO 口。而TCA6416A则是基于 I2C 控制的双向 IO 扩展芯片。
    在这里插入图片描述

    1. TCA6416A 可以扩展出 16 个双向 IO 口,为了与单片机原生的 IO 区别,图中TCA6416A 扩展出的 IO 标注为 IO00-IO07,IO10-IO17。
    2. ADDR 引脚是 I2C 设备的地址引脚,通过接地或 VCC 可设置为两个不同的地址,换句话说,1 组 I2C 总线上可挂两片 TCA6416A(ADDR 引脚分别接地和接 VCC)。
    3. /INT 引脚是专门为扩展输入引脚设计的,相当于单片机的外部中断。当扩展 IO 设为输入模式,且输入电平变化时,/INT 引脚便会触发下降沿中断,单片机的 IO 再去检测/INT 的下降沿,触发真正的单片机中断。单片机通过 I2C 协议查看 TCA6416A 的相关寄存器,便知晓是哪个 IO 被按下。
    4. /RESET 引脚地位相当于单片机的复位引脚,为了节约单片机为数不多的 IO口,这里仿照单片机的上电复位电路用 R2 和 C6 给 TCA6416 也设计了上电复位电路。
    5. SDA、SCL 和/INT 引脚必须外接上拉电阻(R31/32/33)。
    6. 电源 VCC 和地 GND 之间接电容 C5(100nF,标柱为 104)进行去耦,起到“有病治病无病强身”的作用。

    TAC6416A 的寄存器

           首先我们把 TCA6416A 扩展出的 16 个普通 IO 口,理解为成单片机的 P0 和 P1 口,CPU对 IO 口的读写实际上都是通过寄存器这个中介进行的。其次,参考图 12.3 的移位寄存器原理,扩展出的 IO 也是无法位操作的,读写都必须多位同时进行。TAC6416A 的寄存器设计其实很好理解,共 4 组寄存器,我们不妨先分析一下需要哪 4 组。

    1. 需要 16 位的 Input Port Registers 来存储 16 个 IO 的输入状态,相当于单片机中的PxIN。
    2. 需要 16 位的 Output Port Registers 来存储 16 个 IO 的输入状态,相当于单片机中的PxOUT。
    3. 需要 16 位的 Configuration Registers 来存储 IO 的输入输出方向,相当于单片机中的PxDIR。
    4. 需要 16 位的 Polarity Inversion Registers 来存储是否对 IO1/0 取反操作,这个功能在单片机中没有。

           CPU 对于 IO 口的操作有置 1,置 0 和取反三种,单片机可以通过先读出 IO 状态,再做异或逻辑的办法实现取反。但是在 TCA6416A 中,就必须先用 I2C 协议读 Input Port Registers ,CPU 运算后,再用 I2C 写 Output Port Registers ,这个时间非常长。所以TCA6416A 直接就集成了硬件 IO 电平翻转电路,相当于“复杂指令集”了一回。
           实际的 TCA6416A 寄存器,使用 TCA6416A 的过程就是配置这几个寄存器。

    IO 输入寄存器

    在这里插入图片描述

    IO 输出寄存器

    在这里插入图片描述

    IO 反相寄存器

    在这里插入图片描述

    IO 方向寄存器

    在这里插入图片描述

    TCA6416A 的操作

    TCA6416A 写数据

           对 TCA6416A 来说,可能要写 3 种数据,IO 输出电平寄存器,IO 方向寄存器,IO 电平极性翻转寄存器,3 个寄存器都影响实际的 IO 输出,所以这 3 者的地位是完全平等的,写的方法也一样。
           如图 12.9 所示为 TCA6416A 的写寄存器操作时序图。原说明书中将写 IO 与写寄存器分开画图,其实这完全没有必要,写 IO 的本质还是写寄存器。一次完整的写寄存器分 4 部分:

    1. 从机地址:从机地址的前 6 位固定为 010000,为什么不定成 000000 呢?这是因为如果每种类型的 I2C 从机设备都从 000000 起始的话,那地址就区分不开了,所以每种 I2C 设备都会跳开一段地址赋值。第 7 位是真正的地址,只有两种可能。第 8 位用于表示读操作还是写操作。
    2. 命令字:这 8 位实际就是选择写哪个寄存器。高 5 位固定,用低 3 位表示 8 种寄存器。
    3. 寄存器 0:先写寄存器 0,高位在前,低位在后。
    4. 寄存器 1:后写寄存器 1。

    在这里插入图片描述

    TCA6416A 读数据

           单片机在真正读 TCA6416A 数据前,需要写命令告诉 TCA6416A 是操作哪个寄存器。然后才是真正的读数据。写命令需要 2 字节,从机地址+命令。读数据需要 3 个字节,从机地址+低位数据+高位数据。
    在这里插入图片描述

    TCA6416A 的 IO 输入寄存器

           如图 12.11 所示为读 IO 输入寄存器的“读数据”操作时序图部分(即为图 12.10 的后半部分,不包括写命令部分)。为了把个各种异常情况下的现象都描述清楚,图 12.11 做的非常复杂。
           只需注意,图中 IO 电平共变化了 5 次,而实际被单片机读到的却是两次锁存 IO 电平时刻对应的数据 Data1 和数据 Data4。
    在这里插入图片描述
           为了模拟普通 IO 的输入中断,TAC6416A 启用了一个类似的/INT 中断来提示输入 IO 有变化。但是由于 IO 输入的变化速度可能远高于读 IO 输入寄存器的速度,所以,TAC6416A的中断和单片机的 IO 外部中断还不太一样。输入 IO 的变化可以触发/INT 产生下降沿变成低电平,但是/INT 要等 I2C 的应答位才能恢复高电平(重新具备中断能力)。也就是说,TCA6416A 的/INT 中断无法响应快速变化的输入信号,当然我们也可以不用中断的方法判断IO 输入,定时扫描的方法同样适用于 TCA6416A。

    硬件布局

    在这里插入图片描述
    如图所示,扩展出 16 个 IO 口中,8 个作为输出口用于控制 8 个 LED,4 个作为输
    出口用于控制 LCD 驱动器(这个另行介绍),4 个作为输入口用于识别 4 个机械按键。
    在这里插入图片描述
    下图所示为 8 个 LED 以及 4 个机械按键在扩展板中的位置
    在这里插入图片描述

    示例程序

           stdint.h【51单片机快速入门指南】1:基础知识和工程创建
           软件I2C程序见【51单片机快速入门指南】4: 软件 I2C

    TCA6416A.c

    /*
     * TCA6416A.c
     *
     *  Created on: 2013-4-6
     *      Author: Administrator
     */
    #include "./Software_I2C/Software_I2C.h"
    
    #define		TCA6416A_ADDR	0x20	/*从机TCA6416A的7位地址*/
    
    //-----控制寄存器定义-----
    #define		In_CMD0			0x00	//读取管脚输入状态寄存器;只读
    #define		In_CMD1			0x01
    #define		Out_CMD0		0x02	//控制管脚输出状态寄存器;R/W
    #define		Out_CMD1		0x03
    #define		PIVS_CMD0		0x04	//反向控制管脚输出状态寄存器;R/W
    #define		PIVS_CMD1		0x05
    #define		CFG_CMD0		0x06	//管脚方向控制:1:In;0::Out。
    #define		CFG_CMD1		0x07
    
    volatile unsigned int TCA6416A_InputBuffer=0;
    unsigned char pinW0 = 0xff;						//用于缓存已写入相应管脚的状态信息,此操作避免读回TCA6416A中当前寄存器的值
    unsigned char pinW1 = 0xff;						//用于缓存已写入相应管脚的状态信息,此操作避免读回TCA6416A中当前寄存器的值
    
    void Delay_ms(int i);
    
    /******************************************************************************************************
     * 名       称:TCA6416A_Init()
     ******************************************************************************************************/
    void TCA6416A_Init(void)
    {
    	unsigned char conf;
    	Delay_ms(5);						//TCA6416的复位时间比单片机长,延迟确保可靠复位
    	//----根据扩展板的引脚使用,将按键所在管脚初始化为输入,其余管脚初始化为输出
    	conf = 0x00;						//  0 0 0 0_0 0 0 0  (LED0~LED7)
    	i2c_mem_write(TCA6416A_ADDR, CFG_CMD0, &conf, 1);	
    
    	conf = 0x0f;						//  0 0 0 0_1 1 1 1 (按键)
    	i2c_mem_write(TCA6416A_ADDR, CFG_CMD1, &conf, 1);	
    
    	//----上电先将管脚输出为高(此操作对输入管脚无效)
    	conf = 0xff;						// 某位置1,输出为高,0为低
    	i2c_mem_write(TCA6416A_ADDR, Out_CMD0, &conf, 1);
    
    	conf = 0xff;						
    	i2c_mem_write(TCA6416A_ADDR, Out_CMD1, &conf, 1);
    }
    
    /******************************************************************************************************
     * 名       称:PinOUT()
     ******************************************************************************************************/
    void PinOUT(unsigned char pin,unsigned char status)
    {
    	if(pin<=7)												//所选管脚为pin0~pin7 ,刷新所要操作的输出缓存pinW0 状态
    	{
    		if(status == 0)
    			pinW0 &= ~(1<<pin);
    		else
    			pinW0 |= 1<<pin;			
    		i2c_mem_write(TCA6416A_ADDR, Out_CMD0, &pinW0, 1);	// 将更新后的数据包,写入芯片寄存器
    
    	}
    	else if(pin>=10 && pin<=17)								//所选管脚为pin10~pin17 ,刷新所要操作的输出缓存pinW1 状态
    	{
    		if(status == 0)
    			pinW1 &= ~(1<<(pin%10));
    		else
    			pinW1 |= 1<<(pin%10);
    		i2c_mem_write(TCA6416A_ADDR, Out_CMD1, &pinW1, 1);	// 将更新后的数据包,写入芯片寄存器
    	}
    }
    
    /******************************************************************************************************
     * 名       称:PinIN()
     ******************************************************************************************************/
    unsigned char PinIN(unsigned char pin)
    {
    	unsigned char temp[2];
    	i2c_mem_read(TCA6416A_ADDR, In_CMD0, temp, 2);					// 读取按键所在管脚信息
    
    	TCA6416A_InputBuffer = (((unsigned int)temp[1])<<8)|temp[0];
    	if(pin<=7)												
    	{
    		if(temp[0] & (1<<pin))
    			return 1;
    		else
    			return 0;
    	}
    	else if(pin>=10 && pin<=17)							
    	{
    		if(temp[1] & (1<<(pin%10)))
    			return 1;
    		else
    			return 0;
    	}
    }
    
    /******************************************************************************************************
     * 名       称:PinToggle()
     ******************************************************************************************************/
    void PinToggle(unsigned char pin)
    {
    	unsigned char status;
    	if(pin<=7)												//所选管脚为pin0~pin7 ,刷新所要操作的输出缓存pinW0 状态
    	{
    		status = !(pinW0 & (1<<pin));
    		if(status)
    			pinW0 |= 1<<pin;
    		else
    			pinW0 &= ~(1<<pin);
    		i2c_mem_write(TCA6416A_ADDR, Out_CMD0, &pinW0, 1);	// 将更新后的数据包,写入芯片寄存器
    
    	}
    	else if(pin>=10 && pin<=17)								//所选管脚为pin10~pin17 ,刷新所要操作的输出缓存pinW1 状态
    	{
    		status = !(pinW1 & (1<<(pin%10)));
    		if(status)
    			pinW1 |= 1<<(pin%10);
    		else
    			pinW1 &= ~(1<<(pin%10));
    		i2c_mem_write(TCA6416A_ADDR, Out_CMD1, &pinW1, 1);	// 将更新后的数据包,写入芯片寄存器
    	}
    }
    

    TCA6416A.h

    /*
     * TCA6416A.h
     *
     *  Created on: 2013-4-6
     *      Author: Administrator
     */
    
    #ifndef TCA6416A_H_
    #define TCA6416A_H_
    
    extern unsigned char PinIN(unsigned char pin);
    extern void PinOUT(unsigned char pin,unsigned char status);
    extern void PinToggle(unsigned char pin);
    extern void TCA6416A_Init();
    extern volatile unsigned int TCA6416A_InputBuffer;
    
    #endif /* TCA6416A_H_ */
    
    

    测试程序

    一个LED闪烁,另一个LED由KEY控制翻转。

    main.c

    #include <STC89C5xRC.H>
    #include "intrins.h"
    #include "stdint.h"
    #include "TCA6416A.h"
    
    void Delay1ms()		//@11.0592MHz
    {
    	unsigned char i, j;
    
    	_nop_();
    	i = 2;
    	j = 199;
    	do
    	{
    		while (--j);
    	} while (--i);
    }
    
    
    
    void Delay_ms(int i)
    {
    	while(i--)
    		Delay1ms();
    }
    
    void main(void)
    {
    	uint16_t delay_count = 0;
    
    	TCA6416A_Init();
    
    	while(1)
    	{	
    		if(!PinIN(10))
    		{
    			Delay_ms(20);
    			if(!PinIN(10))
    			{
    				PinToggle(1);
    				while(!PinIN(10));
    			}
    		}
    		if(++delay_count == 500)
    		{
    			PinToggle(7);
    			delay_count = 0;
    		}
    		Delay_ms(1);
    	}
    }
    
    
    

    实验现象

    在这里插入图片描述

    展开全文
  • FPGA 是现场可编程门阵列的缩写,它是在PAL,GAL 及 ...同时,由于 FPGA 经常要和外部存储器及 CPU 进行数据输入输出交换,而利用双向端口的设计来进行数据交换可以成倍地节省各自的引脚资源。 双向端口顾名思义是一种...

    FPGA 是现场可编程门阵列的缩写,它是在PAL,GAL 及 EPLD 等可编程器件的基础上发展起来的。FPGA 具有速度快、密度高、功耗小的特点。采用 FPGA 芯片进行专用集成电路设计,既可以解决定制电路缺乏灵活性的不足,又可以通过相关的软硬件环境掌握芯片的最终功能,提高一次设计的成功率,所以,目前 FPGA 在电子设计中已被广泛使用。同时,由于 FPGA 经常要和外部存储器及 CPU 进行数据输入输出交换,而利用双向端口的设计来进行数据交换可以成倍地节省各自的引脚资源。

       双向端口顾名思义是一种既可以作为输入端口接收数据,也可以作为输出端口发出数据,它对数据的操作是双向的。比如某个设计需要一个 16 位的数据输入口和一个16 位的数据输出口,并且数据输入和输出不会同时发生。如果数据输入口和输出口分别设计则需要32根数据线,而用双向端口来设计,则只需要16 根数据线,这样就节省了16 根数据线引脚。由于现在的大多数资料对双向端口的设计介绍很少,本文给出 FPGA 中双向端口的设计原理和方法,以及仿真和初始化双向端口的方法,同时选用Xilinx的Spartan2E 芯片进行实际应用。

    1、 FPGA 中双向端口的设计原理和Verilog硬件语言程序设计

        首先介绍双向端口在 FPGA 内部硬件资源是怎样实现的。在 FPGA 中它是通过对三态门控制来实现双向端口的,比如在 Xilinx 的Spartan2E 中的图例(如图1 所示):

    图1 双向端口的硬件图

        当z=0 时,上面输出的管子开通,此时数据可以从上面的管子中输出,这时双向端口就作为输出口;当z=1 时,上面的管子被置为高阻态,数据不能从上面的管子输出,此时数据只可以从下面的管子由外向内输入,这时的双向端口是输入口。限于篇幅,我们做一个简单的模型来说明双向端口的设计。下面我们用 Verilog 硬件语言进行双向端口的程序设计,为了看出双向端口分别作为输入端口和输出端口的功能,我们的模块分别定义一个数据输入口 din 和一个数据输出口 dout,一个三态门选通信号 z,触发时钟 clk,还有双向端口 dinout。我们设数据为8 位宽。图2为该模块图:

    图2 定义的模块图

        输入口din 定义:input [7:0] din;当双向端口 dinout作为输出口时,我们从 din 端口输入数据到模块中,让数据从dinout口出来。

        输出口 dout定义:output [7:0] dout;当双向端口dinout作为输入口时,我们让数据从dinout口输入,从输出口dout输出。

        双向端口dinout定义:inout[7:0] dinout;

    三态门选通信号z:input z;

        当z=1 时,把三态门置为高阻态,这时 dinout 作为输入口用;当z=0 时,开通三态门,这时 dinout 作为输出口用。

         三态门控制语句为: assign dinout=(!z)?din_reg:8'bz;

         总的完整程序如下: (关键是理清din,dout,dinout三者的关系)

    module dinout(din,z,clk,dout,dinout);

    input [7:0] din;

    input z;

    input clk;

    output[7:0] dout;

    inout [7:0] dinout;

    reg [7:0] dout;

    reg [7:0] din_reg;

    asign dinout= (!z)?din_reg:8'bz; //由Z来决定何时为输入,何时为输出;为0为输出,为1为输入;din_reg作为输出的跳板;

    always @ (posedge clk)

    begin

    if(!z)

       din_reg=din;  //当z=0时,作为输出口,数据流向:din-->din_reg--->dinout;

    else

       dout=dinout; //当z=1时,作为输入口,数据流向:dinout-->dout;即:数据直接流入,间接流出;

    end

       Endmodule

    下面我们对上述程序进行时序仿真。这里我们选用的 FPGA 芯片为 Xilinx 的 Spartan2E 系列,型号为 xc2s300e-7pq208,在ISE Foundation6.1 软件中综合及布局布线,并用 Modelsim Simulator进行时序仿真。

       当双向端口dinout作为输出口时,我们不需要对它进行初始化,只要开通三态门。

       我们设定在200ns后,让数据10,11,12,13,14,15,16,17,18,19,20 依次从 din 口输入,然后用20ns的采样时钟从dinout口输出。

        它的测试仿真顶层模块为

    `timescale 1ns/1ps

    module dinoutest();

    reg [7:0] din;

    reg z;

    reg clk;

    wire [7:0] dout;

    wire [7:0] dinout;

    integer i;

    dinout uut(

    .din(din),

    .z(z),

    .clk(clk),

    .dout(dout),

    .dinout(dinout)

    );

    always #10clk=~clk;

    initial begin

       din = 0;

       z = 0;   //让双向口作为输出口;

       clk = 0;

       # 200 din=10;

       for(i=0;i

          #20 din=din+1;

       end

    endmodule

    从din 输入口输入到模块中的数据。

    当双向端口dinout作为输入口时,我们需要对它进行初始化赋值,此时关闭三态门。而对双向端口的初始化赋值,如果把它跟一般的输入口一样直接赋值给它,则会出错,因为在定义它的时候是wire型了,而不是reg 型。在许多 Verilog 书籍和参考资料中,有关双向端口的初始化赋值介绍的很少。这里需要用到一个force 命令,用来给dinout 输入赋值。我们设定在200ns 后,让数据20,19,18,17,16,15,14,13,12,11,10 从dinout口输入模块,然后用 20ns的采样时钟从输出口 dout输出。以下是它的仿真顶层模块

    `timescale 1ns/1ps

    module dinoutest();

    reg [7:0]din;

    reg z;

    reg clk;

    wire [7:0] dout;

    wire [7:0] dinout;

    integer i;

    dinoutuut(

    .din(din),

    .z(z),

    .clk(clk),

    .dout(dout),

    .dinout(dinout)  //将双向口作为输入口时,要用wire型输入;

    ); 

    always #10clk= ~clk;

    initial begin

    z = 1;

    clk = 0;

    force dinout=20;  //对reg型可以直接赋值,但是对wire型需要force强制赋值;

    # 200 for (i=0;i

    #20 force dinout=dinout-1;

    end

    endmodule

    可以看出这时双向端口 dinout作为输入口,数据从dinout口输入模块,然后从输出口dout完整地输出来。

    这种双向端口设计方法已被我们用到目前开发的一个多通道图象捕获和显示控制系统中。在该系统中,FPGA 接收从两个图像传感器传来的数字视频信号,然后根据CPU的命令对这两路视频信号进行四种显示模式的组合操作。FPGA 将处理好的信号存到外部存储器中。如果LCD显示信号来了, FPGA 从外部存储器中取数据给LCD显示。如果CPU 想要对某一帧图像数据进行图象识别操作,可以经过 FPGA 从外部存储器中把该帧图象数据取下来。其中 LCD 的时钟频率为 6M,FPGA 对外部存储器及 CPU 数据操作的时钟频率为 24M,并且LCD显示操作优先级最高。在这个系统中用到了两个双向端口,一个是FPGA 与CPU的数据交换, 另一个是FPGA与外部存储器之间的数据交换,他们都是16 位的数据交换,由于用了双向端口,节省了32个引脚资源,同时优化了器件的选择和整体设计,降低了成本。

    展开全文
  • 图2 提高输入信号电平 图3 输入端保护电路 为了防止外界尖峰干扰和静电影响损坏输入引脚,可以在输入端增加防脉冲的二极管,形成电阻双向保护电路,如图3所示。二极管D1、D2、 D3的正向导通压降UF≈0.7 V,反向击穿...

    关注+星标公众,不错过精彩内容

    092aa196ca76dac2b7e71cb3cc1e0b49.gif

    编排 | strongerHuang

    微信公众号 | 嵌入式专栏

    随着微电子技术和计算机技术的发展,原来以强电和电器为主、功能简单的电气设备发展成为强、弱电结合,具有数字化特点、功能完善的新型微电子设备。

    在很多场合,已经出现了越来越多的单片机产品代替传统的电气控制产品。单片机其控制功能通过软件指令来实现,其硬件配置也可变、易变。因此,一旦生产过程有所变动,就不必重新设计线路连线安装,有利于产品的更新换代和订单式生产。

    传统电气设备采用的各种控制信号,必须转换到与单片机输入/输出口相匹配的数字信号。用户设备须输入到单片机的各种控制信号,如限位开关、 操作按钮、选择开关、行程开关以及其他一些传感器输出的开关量等,通过输入电路转换成单片机能够接收和处理的信号。输出电路则应将单片机送出的弱电控制信 号转换、放大到现场需要的强输出信号,以驱动功率管、电磁阀和继电器、接触器、电动机等被控制设备的执行元件,能方便实际控制系统使用。

    针对电气控制产品的特点,本文讨论了几种单片机I/O的常用驱动和隔离电路的设计方法,对合理地设计电气控制系统,提高电路的接口能力,增强系统稳定性和抗干扰能力有实际指导意义。

    输入电路设计

    一般输入信号最终会以开关形式输入到单片机中,以工程经验来看,开关输入的控制指令有效状态采用低电平比采用高电平效果要好得多,如图1所示。当按下开关S1时,发出的指令信号为低电平,而平时不按下开关S1时,输出到单片机上的电平则为高电平。该方式具有较强的耐噪声能力。

    6754e045dfdf5c726467c872059f8f55.png

    图1 开关信号输入

    若考虑到由于TTL电平电压较低,在长线传输中容易受到外界干扰,可以将输入信号提高到+24 V,在单片机入口处将高电压信号转换成TTL信号。这种高电压传送方式不仅提高了耐噪声能力,而且使开关的触点接触良好,运行可靠,如图2所示。其 中,D1为保护二极管,反向电压≥50 V。

    3ea433f13b7dc46dd44063e7d61090c0.png

    图2 提高输入信号电平

    376bfc08acc3338744b3c75b4f5d705b.png

    图3 输入端保护电路

    为了防止外界尖峰干扰和静电影响损坏输入引脚,可以在输入端增加防脉冲的二极管,形成电阻双向保护电路,如图3所示。二极管D1、D2、 D3的正向导通压降UF≈0.7 V,反向击穿电压UBR≈30 V,无论输入端出现何种极性的破坏电压,保护电路都能把该电压的幅度限制在输入端所能承受的范围之内。即:VI~VCC出现正脉冲时,D1正向导 通;VI~VCC出现负脉冲时,D2反向击穿;VI与地之间出现正脉冲时,D3反向击穿;VI与地之间出现负脉冲时,D3正向导通,二极管起钳位保护作用。缓冲电阻RS约为1.5~2.5 kΩ,与输入电容C构成积分电路,对外界感应电压延迟一段时间。若干扰电压的存在时间小于τ,则输入端承受的有效电压将远低于其幅度;若时间较长,则D1 导通,电流在RS上形成一定的压降,从而减小输入电压值。

    此外,一种常用的输入方式是采用光耦隔离电路。如图4所示,R为输入限流电阻,使光耦中的发光二极管电流限制在10~20 mA。输入端靠光信号耦合,在电气上做到了完全隔离。

    同时,发光二极管的正向阻抗值较低,而外界干扰源的内阻一般较高,根据分压原理,干扰源能馈送到输入 端的干扰噪声很小,不会产生地线干扰或其他串扰,增强了电路的抗干扰能力。

    15cb27e2ed0129102b28f34865f569c1.png

    图4 输入端光耦隔离

    在满足功能的前提下,提高单片机输入端可靠性最简单的方案是:在输入端与地之间并联一只电容来吸收干扰脉冲,或串联一只金属薄膜电阻来限制流入端口的峰值电流。

    输出电路设计

    单片机输出端口受驱动能力的限制,一般情况下均需专用的接口芯片。其输出虽因控制对象的不同而千差万别,但一般情况下均满足对输出电压、电流、开关频率、波形上升下降速率和隔离抗干扰的要求。在此讨论几种典型的单片机输出端到功率端的电路实现方法。

    1.直接耦合

    在采用直接耦合的输出电路中,要避免出现图5所示的电路。

    e844b85439b7b78ab2f048dc95170def.png

    图5 错误的输出电路

    T1截止、T2导通期间,为了对T2提供足够的基极电流,R2的阻值必须很小。因为T2处于射极跟随器方式工作,因此为了减少T2损耗,必须将集射间电压降控制在较小范围内。

    这样集基间电压也很小,电阻R2阻值很小才能提供足够的基极电流。R2阻值过大,会大幅度增加T2压降,引起T2发热严重。而在T2截止期间,T1必须导通,高压+15 V全部降在电阻R2上,产生很大的电流,显然是不合理的。

    另外,T1的导通将使单片机高电平输出被拉低至接近地电位,引起输出端不稳定。T2基极被T1拉 到地电位,若其后接的是感性负载,由于绕组反电势的作用,T2的发射极可能存在高电平,容易引起T2管基射结反向击穿。

    图6为一直接耦合输出电路,由T1和T2组成耦合电路来推动T3。T1导通时,在R3、R4的串联电路中产生电流,在R3上的分压大于T2 晶体管的基射结压降,促使T2导通,T2提供了功率管T3的基极电流,使T3变为导通状态。当T1输入为低电平时,T1截止,R3上压降为零,T2截止, 最终T3截止。R5的作用在于:一方面作为T2集电极的一个负载,另一方面T2截止时,T3基极所储存的电荷可以通过电阻R3迅速释放,加快T3的截止速度,有利于减小损耗。

    70d5ef9888a41d3a391fb35d5a882980.png

    图6 直接耦合输出电路

    2.TTL或CMOS器件耦合

    若单片机通过TTL或CMOS芯片输出,一般均采用集电极开路的器件,如图7(a)所示。集电极开路器件通过集电极负载电阻R1接至+15 V电源,提升了驱动电压。但要注意的是,这种电路的开关速度低,若用其直接驱动功率管,则当后续电路具有电感性负载时,由于功率管的相位关系,会影响波形 上升时间,造成功率管动态损耗增大。

    为了改善开关速度,可采用2种改进形式输出电路,如图7(b)和图7(c)所示。图7(b)是能快速开通的改进电路,当TTL输出高电平 时,输出点通过晶体管T1获得电压和电流,充电能力提高,从而加快开通速度,同时也降低了集电极开路TTL器件上的功耗。图7(c)为推挽式的改进电路, 采用这种电路不但可提高开通时的速度,而且也可提高关断时的速度。输出晶体管T1是作为射极跟随器工作的,不会出现饱和,因而不影响输出开关频率。

    c1de97653632aed1b845a17890b62eae.png

    图7 TTL或CMOS器件输出电路

    3.脉冲变压器耦合

    脉冲变压器是典型的电磁隔离元件,单片机输出的开关信号转换成一种频率很高的载波信号,经脉冲变压器耦合到输出级。由于脉冲变压器原、副边线圈间没有电路连接,所以输出是电平浮动的信号,可以直接与功率管等强电元件耦合,如图8所示。

    d619c96e69927af90d7aefec5582431b.png

    图8 脉冲变压器输出电路

    这种电路必须有一个脉冲源,脉冲源的频率是载波频率,应至少比单片机输出频率高10倍以上。脉冲源的输出脉冲送入控制门G,单片机输出信号 由另一端输入G门。当单片机输出高电平时,G门打开,输出脉冲进入变压器,变压器的副线圈输出与原边相同频率的脉冲,通过二极管D1、D2检波后经滤波还 原成开关信号,送入功率管。当单片机输出低电平时,G门关闭,脉冲源不能通过G门进入变压器,变压器无输出。

    这里,变压器既传递信号,又传送能量,提高了脉冲源的频率,有利于减轻变压器的体重。由于变压器可通过调整电感量、原副边匝数等来适应不同 推动功率的要求,所以应用起来比较灵活。更重要的是,变压器原副边线圈之间没有电的联系,副线圈输出信号可以跟随功率元件的电压而浮动,不受其电源大小的 影响。

    当单片机输出较高频率的脉冲信号时,可以不采用脉冲源和G门,对变压器原副边电路作适当调整即可。

    4.光电耦合

    光电耦合可以传输线性信号,也可以传输开关信号,在输出级应用时主要用来传递开关信号。

    如图9所示,单片机输出控制信号经缓冲器7407放大后送入光耦。R2为光耦输出晶体管的负载电阻,它的选取应保证:在光耦导通时,其输出晶体管可靠饱和;而在光耦截止时,T1可靠饱和。但由于光耦响应速度慢使开关延迟时间加长,限制了其使用频率。

    32665647d7b4a7c48331aaf79e9a9f9a.png

    图9 光耦输出电路

    结语

    单片机接口技术在很多资料中均有详细的介绍,但在对大量电气控制产品的改造和设计中,经常会碰到用接口芯片所无法解决的问题(如驱动电流大、开关速度慢、抗干扰差等),因此必须寻求另一种电路解决方案。

    上述几种输入/输出电路通过广泛的应用表明,其对合理、可靠地实现单片机电气控制系统具有较高的工程实用价值。

    声明:本文素材来源网络,版权归原作者所有。如涉及作品版权问题,请与我联系删除。

    ------------ END ------------

    后台回复『单片机』『嵌入式软硬件综合内容』阅读更多相关文章。

    欢迎关注我的公众号回复“加群”按规则加入技术交流群,回复“1024”查看更多内容。

    欢迎关注我的视频号:

    44ee69107b9e47672fa91fd7a2df910a.png

    点击“阅读原文”查看更多分享,欢迎点分享、收藏、点赞、在看。

    展开全文
  • JAVA IOJAVA NIO JAVA IO 阻塞 IO 模型 最传统的一种 IO 模型,即在读写数据过程中会发生阻塞现象。当用户线程发出 IO 请求之后,内核会去查看数据是否就绪,如果没有就绪就会等待数据就绪,而用户线程就会处于...
  • 基于IO-Link接口的温湿度传感器设计石磊1,2,孙凯明1,2,王刚2【摘要】摘要:简述具有能与IO-Link主机通讯的IO-Link接口的温度和湿度传感器的设计,并描述了基于IO-Link协议和物理接口的硬件和固件原理,同时讨论了...
  • Linux IO模型

    2021-09-26 16:23:15
    IO模型 关键概念 一些概念 1. 内核空间、用户空间 操作系统的核心是内核,独立于其他应用程序,可以访问底层会保护的硬件,Linux为了防止用户进程直接操作内核,将虚拟地址空间,分成了用户空间和内核空间,用户...
  • 引言JDK1.4中引入了NIO,即New IO,目的在于提高IO速度。特别注意JavaNIO不全然是非堵塞式IO(No-Blocking IO),由于当中部分通道(如FileChannel)仅仅能运行在堵塞模式下,而其它的通道能够在堵塞式和非堵塞式之间...
  • IO模型浅析

    2021-02-23 17:06:51
    简介 IO模型分类 服务器端编程经常需要构造高性能的IO模型,常见的IO模型有四种: (1)同步阻塞IO(Blocking IO):即传统的IO模型...(4)异步IO(Asynchronous IO):即经典的Proactor设计模式,也称为异步非阻塞IO
  • IO流&Servlet&SpringMVC

    2021-07-22 19:23:08
    IO流&装饰器模式IO流的特性(方向,单位,功能)常用的IO流接口及类型(类名,功能)延申装饰器模式适配器模式Socket&ServerSocketBIO/NIO/AIOServlet&SpringMVCXML(良构,合法) IO流的特性(方向,...
  • grpc双向

    2021-02-01 04:14:57
    简介grpc是一个高性能、开源和通用的 RPC 框架,面向移动和 ... 其中 C 版本支持 C, C++, Node.js, Python, Ruby, Objective-C, PHP 和 C# 支持.gRPC 基于 HTTP/2 标准设计,带来诸如双向流、流控、头部压缩、单 T...
  • Java NIO与IO的区别和比较导读J2SE1.4以上版本中发布了全新的I/O类库。本文将通过一些实例来简单介绍NIO库提供的一些新特性:非阻塞I/O,字符转换,缓冲以及通道。一. 介绍NIONIO包(java.nio.*)引入了四个关键的抽象...
  • 存储器和IO扩展实验,计算机组成原理科 技 学 院课程设计实验报告( 2014--2015年度第一学期)名 称: 计算机组成原理综合实验题 目: 存储器和I/O扩展实验院 系: 信息工程系班 级:学 号:学生姓名:指导教师: 李梅 ...
  • 基于JAVA超市自助购物系统的设计与实现

    千次阅读 多人点赞 2021-08-03 20:34:06
    一、设计需求 基于RFID的自动识别技术,通过无线射频方式实时获得磁卡对超市物品的电子标签进行读取,然后将数据通过网络传输至服务器,在应用层开发一个管理系统,对超市物品信息、店内消费等各种行为进行管理和...
  • Socket socket IP+Port 一台计算机(一个IP地址)最多65535个port socket是两端的 是四元组 只要满足可以唯一确认,区分每一个socket对应关系即可 ip:port + ip:port 网络上两个程序通过一个双向的通信连接实现数据...
  • 很多同学想知道企业在招聘Java工程师时会提问哪些问题,千锋广州Java培训老师汇总历届学员求职经验并与企业沟通之后总结出《Java面试宝典》,涵盖Java基础、设计模式以及Java框架等考察点,一码当先,学员月薪过万...
  • 定义I/O Ports信息每个完整的FPGA设计必然包含I/O Ports定义与配置环节。I/O Ports包含了FPGA内部信号、管脚、PCB之间的连接关系。常用的设计方法有两种:1. RTL工程:完成了RTL设计后,打开一个设计(如综合后设计)...
  • Java中IO——NIO

    2021-03-15 01:34:54
    一、引入当引入一些新功能的时候,那说明之前的设计可能还需要完善。1、阻塞式在传统的IO输入输出中,如果我们从流中去读数据,而数据源中没有数据时,程序就会阻塞该线程。阻塞式线程的一种基本状态,可以理解成...
  • java IO编程详解

    2021-04-09 22:29:16
    java IO编程详解 一、Socket 1. Sock概述 Socket,套接字就是两台主机之间逻辑连接的端点。TCP/IP协议是传输层协议,主要解决数据如何在网络中传输,而HTTP协议是应用层协议,主要解决如何包装数据。Socket是通信的...
  • 了解Redis底层关于IO多路复用的epoll实现原理前,先介绍关于IO模型,内存与磁盘交互方式、同步IO、异步IO,有助于对多路复用更好的理解。 用户空间与内核空间 User space 是用户程序的运行空间,Kernel space 是...
  • 一位输出:流水灯 电路功能分析 这里首先了解一位是指单片机指利用一组IO口进行操作,那么对应在最小系统基础上完成与8 个发光二极管的驱动电路设计;另外需要编写测试程序,实现循环点亮8 个灯,时间间隔约1 秒。 ...
  • 这些,都是 IO 模式的特征。本篇说明了 IO 三种模式,以及简单提及了 NIO 的三大核心组件。二、IO 模式的特征1、阻塞与非阻塞阻塞:数据没有传过来时,读会一直阻塞直到有数据传过来;当缓冲区被写满时,写操作也被...
  • Java阻塞IO与非阻塞IO

    2021-02-11 06:15:12
    IO:IO 是主存和外部设备 ( 硬盘、终端和网络等 ) 拷贝数据的过程。 IO 是操作系统的底层功能实现,底层通过 I/O 指令进行完成。阻塞与非阻塞:一辆从 A 开往 B 的公共汽车上,路上有很多点可能会有人下车。司机不知道...
  • 在Linux下编写服务端程序时,一个必须考虑的问题就是程序的IO,要根据使用场景选择合适的IO模型,特备是对于IO密集型的应用,合适的IO模型显得尤为重要。
  • Java语言中链表和双向链表链表是一种重要的数据结构,在程序设计中占有很重要的地位。C语言和C++语言中是用指针来实现链表结构的,由于Java语言不提供指针,所以有人认为在Java语言中不能实现链表,其实不然,Java...
  • 一 、单片机IO实验

    2021-03-23 12:28:10
    一、 单片机IO实验 ​ 自律 学习 坚强 ,拒绝迷茫。 作者:行走的皮卡丘 时间:2020/03/23 喜欢就去追,这个红灯等不到,说不定下一个红灯等到了,嘻嘻!...2、I/O 口三、设计步骤:【实验程序设计】【PROT
  • 从0开始学java IO

    2021-03-20 14:58:44
    从0开始学java IOIO 发展BIO设计思想核心类SocketIO 流BIO实例 -- 多人聊天室客户端服务端双阻塞客户端阻塞服务端并发客户端阻塞服务端复用线程并发客户端并发服务端复用线程并发NIOBIO VS NIO设计思想核心类...
  • 前言前面两篇文章(Java NIO之理解I/O模型(一)、Java NIO之理解I/O模型(二))介绍了,IO的机制,以及几种IO模型的内容,还有涉及到的设计模式。这次要写一些更贴近实际一些的内容了,终于要说到了Java中的各种IO了。我...
  • MySQL数据库双向同步

    2021-01-21 06:49:59
    然后进入mysql用show slave status 或show master status 查看同步情况 3、 双向同步 master端的设置 [mysqld]: log-bin server-id = 1 sql-bin-update-same 同步模式 ,在mysql5以上的版本都不需要这句,否则会...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 41,331
精华内容 16,532
关键字:

双向io设计