精华内容
下载资源
问答
  • 以下编码方式有助提高使用Graphics的绘图速度: 只建立一个图形对象 (或只使用... 主要思路:最小化重画图象。例如,当光标拖过图象时,不需要把整个图重新画一遍。只需要重画光标之前经过的地方绘图过程中...
    以下编码方式有助提高使用Graphics的绘图速度:
    • 只建立一个图形对象 (或只使用OnPaint中的 PaintEventArgs)。
    • 把所有绘图工作先画到不显示的位图上,再一次性把位图显示出来。
    • 只重画变化的部分图象。
    • 尽可能在相同的区域上画相同大小的图象。
    主要思路:最小化地重画图象。
    例如,当光标拖过图象时,不需要把整个图重新画一遍。只需要重画光标之前经过的地方

     绘图过程中的速度和屏闪是我们需要注意的问题,
    比如移动一个窗口的时候,很可能出现闪烁现象,怎么样减少类似的情况呢?

    希望大家根据自己的经验,给出一些解决的办法regular_smile.gif
    ####################################################################################

    原因一:
    如果熟悉显卡原理的话,调用GDI函数向屏幕输出的时候并不是立刻就显示在屏幕
    上只是写到了显存里,而显卡每隔一段时间把显存的内容输出到屏幕上,这就是刷新周期。

    一般显卡的刷新周期是 1/80秒左右,具体数字可以自己设置的。

    这样问题就来了,一般画图都是先画背景色,然后再把内容画上去,如果这两次操作不在同一个
    刷新周期内完成,那么给人的视觉感受就是,先看到只有背景色的图像,然后看到画上内容的图像,
    这样就会感觉闪烁了。

    解决方法:尽量快的输出图像,使输出在一个刷新周期内完成,如果输出内容很多比较慢,那么采用
    内存缓冲的方法,先把要输出的内容在内存准备好,然后一次输出到显存。要知道一次API调用一般可以
    在一个刷新周期内完成。

    对于GDI,用创建内存DC的方法就可以了

    原因二:

    复杂的界面有多层窗口组成,当windows在窗口改变大小的时候是先重画父窗口,然后重画子窗口,子父
    窗口重画的过程一般无法在一个刷新周期内完成,所以会呈现闪烁。

    我们知道父窗口上被子窗口挡住的部分其实没必要重画的

    解决方法:给窗口加个风格 WS_CLIPCHILDREN ,这样父窗口上被子窗口挡住的部分就不会重画了。

    如果同级窗口之间有重叠,那么需要再加上 WS_CLIPSIBLINGS 风格

    原因三:

    有时候需要在窗口上使用一些控件,比如IE,当你的窗口改变大小的时候IE会闪烁,即使你有了WS_CLIPCHILDREN
    也没用。原因在于窗口的类风格有CS_HREDRAW 或者 CS_VREDRAW,这两个风格表示窗口在宽度或者高度变化的时候
    重画,但是这样就会引起IE闪烁

    解决方法:注册窗口类的时候不要使用这两个风格,如果窗口需要在改变大小的时候重画,那么可以在WM_SIZE的时候
    调用RedrawWindow。

    原因四:

    界面上窗口很多,而且改变大小时很多窗口都要移动和改变大小,如果使用MoveWindow或者SetWindowPos两个API来
    改变窗口的大小和位置,由于他们是等待窗口重画完成后才返回,所以过程很慢,这样视觉效果就可能会闪烁。

    解决方法:

    使用以下API来处理窗口移动,BeginDeferWindowPos, DeferWindowPos,EndDeferWindowPos
    先调用 BeginDeferWindowPos 设定需要移动的窗口的个数
    使用DeferWindowPos,来移动窗口,这个API并不真的造成窗口移动
    EndDeferWindowPos 一次性完成所有窗口的大小和位置的改变。

    有个地方要特别注意,要仔细计算清楚要移动多少个窗口,BeginDeferWindowPos设定
    的个数一定要和实际的个数一致,否则在Win9x下,如果实际移动的窗口数多于调用BeginDeferWindowPos
    时设定的个数,可能会造成系统崩溃。在Windows NT系列下不会有这样的问题。

    转载于:https://www.cnblogs.com/jht/archive/2005/07/27/201275.html

    展开全文
  • 这些手段能够在一定程度上保证防静电腕带等防护措施的有效性,但是却不能在作业过程当中对防静电措施的有效性进行及时、动态检查,也不能在措施失效时及时给出提示。电子企业的生产线具有工位多、场地大、分布广...

    5006c89f85fbcfd40da91ff5c986e0c8.png

    随着近年来电子企业对ESD的危害的深入认识,主流电子工厂普遍在静电敏感工位采取了防静电措施,并引入了防静电监控仪等点检设备,有的还和门禁组成防静电门禁系统。这些手段能够在一定程度上保证防静电腕带等防护措施的有效性,但是却不能在作业过程当中对防静电措施的有效性进行及时地、动态地检查,也不能在措施失效时及时给出提示。

    4925945867f92d1e93f4845800a29f6d.png

    电子企业的生产线具有工位多、场地大、分布广的特点,所以通过网络把“集线控制器”、“接地监控器”、“腕带”、“数据转换器”、“计算机”等设备连接起来,组成一个完整的静电监控网络系统,在系统软件的控制下,实现真正意义上的实时监控、数据储存、以及动态显示等功能。

    一、防静电监控仪的款式

    1、一路防静电手腕带监控产品,支持单回路防静电手腕带。

    2、两路防静电手腕带监控产品,支持双回路防静电手腕带和无线通讯,并实时监测人体对地回路电阻。

    3、设备防静电监控仪产品,检测设备是否和实际大地接触良好,并实时检测接地回路的电阻值。

    设备防静电监控仪SP-SBJD01,是一款实时检测设备是否和实际大地接触良好的仪器,并且可以检测接地回路的电阻值(0~500Ω),进一步监测设备地线是否老化等问题,杜绝了设备因静电发生的安全事故。

    二、设备防静电监控仪-通讯模式

    e8688b832806be92ba72758c92d5c35a.png

    设备防静电监控仪是用RS485有线和RF433无线两种通信模式与上位机进行实时通信,显示端和客户端实时监控生产现场设备的接地情况与阻值等参数;设备防静电监控仪设有两路阻值测量,可同时监测两台生产设备的静电状态;两路预留输出接口可以驱动外接警灯装置;内置蜂鸣器与状态指示灯在检测到异常时发出报警信号。最大限度的保障员工的人身安全和企业的财产安全。

    设备防静电监控仪-产品介绍

    4300cf688372df15a74c4e68b02d2674.png

    0509c282e042aafc13844869a684f826.png

    设备防静电监控仪-接口描述

    4d02b9543737f8fac02386f06a7f18cd.png

    6a15bbb95ab6d45f8db0f17b95b947fb.png

    e6c753509fc7093def851b3987c1a711.png

    010859fc79d22314235aed700041475f.png

    三、设备防静电监控仪使用方法

    1、 INx接到检测设备上;

    2、 GND接到大地上;

    3、 RS485接口AB线接到上位机;

    4、12V以及OUT1/OUT2选择接到外部报警装置;

    5、使用无线通信时, 插上外部RF433天线,并且设置相应信道参数。

    四、设备防静电监控仪状态说明

    1、设备检测接大地正常时,蜂鸣器不报警,PASS1和PASS2指示灯亮,RS485读取检测状态为0x00 (正常状态),且有电阻值。

    2、当设备接地(GND)断开时, 蜂鸣器持续报警(地线断开报警),PASS1和PASS2指示灯快速闪烁。RS485读取状态为0x02 (地线断开状态)。

    3、当设备接线(INx)断开时,蜂鸣器间歇报警(设备断开报警),PASS1或PASS2指示灯慢速闪烁。RS485读取状态为0x01 (设备断开状态)。

    4 、外部输出接口(OUT1/OUT2) ,可根据需要是否外接。

    设备防静电监控仪-产品实拍

    8ed2a39e885b466338a72690062898c2.png

    f92404a3eb80417cb4b307d5789e4975.png

    297b1f47f37b27df46559b1be243457f.png

    设备防静电监控仪-系统架构

    789a6281868884928de4474be6c02198.png

    设备防静电监控仪-应用场景

    9ee1715efa88f7c53dc409a2fe6b86ea.png

    设备防静电监控仪是对企业的防静电设备、人员进行实时监控、数据储存、以及动态显示的数字化管理工具。系统由管理软件、现场显示屏和ESD防静电监控仪组成。通过设备防静电监控仪对防静电手腕带和生产设备的实时监控,由RS485有线或RF433无线把数据传输给管理软件存储、并实时发送至现场显示屏,让现场管理人员时刻精准了解现场的静电防护情况。解决长期以来工厂里对静电监控和数据采集记录困难的问题。

    展开全文
  • 家长怎样一年级小孩评语 1、你明亮的眼睛闪烁着智慧的光芒,小巧的嘴巴发出悦耳的字音。你声音甜美,书读得很有感情。你能说会道,尊敬老师,学习比较认真,成绩优良。老师希望你继续努力,争取更大的进步。 2、瞧...
  • 第二个试验:用单片机点亮...怎样才能让灯不断地闪烁呢?实际上就是要灯亮一段时间,再灭一段时间,也就是说要P10不断地输出高和低电平。怎样实现这个要求呢?请考虑用下面的指令是否可行:SETB P1.0CLR P1.0……这是不

    第二个试验:用单片机点亮一个闪烁的发光管

    一次我们的程序实在是没什么用,要灯亮还要重写一下片子,下面我们要让灯不断地闪烁,这就有一定的实用价值了,比如可以把它当成汽车上的一个信号灯用了。怎样才能让灯不断地闪烁呢?实际上就是要灯亮一段时间,再灭一段时间,也就是说要P10不断地输出高和低电平。怎样实现这个要求呢?请考虑用下面的指令是否可行:

    SETB P1.0

    CLR P1.0

    ……

    这是不行的,有两个问题,第一,计算机执行指令的时间很快,执行完SETB P10后,灯是灭了,但在极短时间(微秒级)后,计算机又执行了CLR P10指令,灯又亮了,所以根本分辨不出灯曾灭过。第二,在执行完CLR P10后,不会再去执行SETB P10指令,所以以后再也没有机会让灭了。

      为了解决这两个问题,我们可以做如下设想,第一,在执行完SETB P10后,延时一段时间(几秒或零点几秒)再执行第二条指令,就可以分辨出灯曾灭过了。第二在执行完第二条指令后,让计算机再去执行第一条指令,不断地在原地兜圈,我们称之为"循环",这样就可以完成任务了。

    以下先给出程序(后面括号中的数字是为了便于讲解而写的,实际不用输入):

    ;主程序:

    LOOP: SETB P1.0     ;(1)

        LCALL DELAY   ;(2)

        CLR P1.0     ;(3)

        LCALL DELAY   ;(4)

        AJMP LOOP    ;(5)

    ;以下子程序

    DELAY: MOV R7,#250  ;(6)

    D1: MOV R6,#250    ;(7)

    D2: DJNZ R6,D2    ;(8)

      DJNZ R7,D1     ;(9)

      RET         ;(10)

      END         ;(11)

    按上面的设想分析一下前面的五条指令。

      第一条是让灯灭,第二条应当是延时,第三条是让灯亮,第四条和第二条一模一样,也是延时,第五条应当是转去执行第一条指令。第二和第四条实现的原理稍后谈,先看第五条,LJMP是一条指令,意思是转移,往什么地方转移呢?后面跟的是LOOP,看一下,什么地方还有LOOP,对了,在第一条指令的前面有一个LOOP,所以很直观地,我们可以认识到,它要转到第一条指令处。这个第一条指令前面的LOOP被称之为标号,它的用途就是给这一行起一个名字,便于使用。是否一定要给它起名叫LOOP呢?当然不是,起什么名字,完全由编程序的人决定,可以称它为A,X等等,当然,这时,第五条指令LJMP后面的名字也得跟着改了。

      第二条和第四条指令的用途是延时,它是怎样实现的呢?指令的形式是LCALL,这条指令称为调用子程序指令,看一下指令后面跟的是什么,DELAY,找一下DELAY,在第六条指令的前面,显然,这也是一个标号。这条指令的作用是这样的:当执行LCALL指令时,程序就转到LCALL后面的标号所标定的程序处执行,如果在执行指令的过程中遇到RET指令,则程序就返回到LCALL指令的下面的一条指令继续执行,从第六行开始的指令中,可以看到确实有RET指令。在执行第二条指令后,将转去执行第6条指令,而在执行完6,7,8,9条指令后将遇到第10条令:RET,执行该条指令后,程序将回来执行第三条指令,即将P10清零,使灯亮,然后又是第四条指令,执行第四条指令就是转去执行第6,7,8,9,10条指令,然后回来执行第5条指令,第5条指令就是让程序回到第1条开始执行,如此周而复始,灯就在不断地亮、灭了。

      在标号DELAY标志的这一行到RET这一行中的所有程序,这是一段延时程序,大概延时零点几秒,至于具体的时间,以后我们再学习如何计算。 程序的最后一行是END,这不是一条指令,它只是告诉我们程序到此结束,它被称为"伪指令"。

    二、单片机内部结构分析:

      为了知道延时程序是如何工作的,我们必需首先了解延时程序中出现的一些符号, 就从R1开始,R1被称之为工作寄存器。什么是工作寄存器呢?让我们从现实生活中来找找答案。如果出一道数学题:123+567,让你回答结果是多少,你会马上答出是690,再看下面一道题:123+567+562,要让你要上回答,就不这么容易了吧?我们会怎样做呢?如果有张纸,就容易了,我们先算出123+567=690,把690写在纸上,然后再算690+562得到结果是1552。这其中1552是我们想要的结果,而690并非我们所要的结果,但是为了得到最终结果,我们又不得不先算出690,并记下来,这其实是一个中间结果,计算机中做运算和这个类似,为了要得到最终结果,往往要做很多步的中间结果,这些中间结果要有个地方放才行,把它们放哪呢?放在前面提到过的ROM中可以吗?显然不行,因为计算机要将结果写进去,而ROM是不可以写的,所以在单片机中另有一个区域称为RAM区(RAM是随机存取存储器的英文缩写),它可以将数据写进去。

      特别地,在MCS-51单片机中,将RAM中分出一块区域,称为工作寄存器区。

    以下是它的a51文件:我们把它的名字叫作002.A51

    LOOP: SETB P1.0
    LCALL DELAY
    CLR P1.0
    LCALL DELAY
    AJMP LOOP
    DELAY: MOV R7,#250
    D1:MOV R6,#250
    D2:DJNZ R6,D2
    DJNZ R7,D1
    RET
    END

     
    展开全文
  • 斩波型运放提供较低的失调电压,同时也极大减少了1 / f(闪烁)噪声。它是怎么做到的?这篇文章就来讨论这个主题。
  • 怎样给小学生写评语 评语最初用在对学生的综合评价上,期末时班主任在学生守则上写上几句评语作为一个学期来对学生的综合评价;下面是有小学生评语,欢迎参阅。小学生评语 1、你明亮的眼睛闪烁着智慧的光芒,小巧的...
  • 而他勇敢选择了坚持,因为他有一副铿铿锵锵的骨骼,他有一条不灭的灵魂!所以,他战胜了黑夜。无情上的火屈服在他的脚下,他迎来了光明。他挺直的腰板,闪烁上的光明,向世界宣告他的成功,每一一个读此书的人都应...
  • 到底怎样编写Verilog代码——FPGA入门(一)

    千次阅读 多人点赞 2020-07-26 11:44:43
    OutlineFPGA简介Verilog是什么数字电路的通用结构怎样使用Verilog实现电路应用例子:Verilog实现LED闪烁 FPGA简介 本科时期我们在数字电路课堂上做过很多关于数字电路的实验,各种74系列芯片,通过一把一把的杜邦线...

    FPGA简介

    本科时期我们在数字电路课堂上做过很多关于数字电路的实验,各种74系列芯片,通过一把一把的杜邦线连接起来,如果有一根线连错了,电路就不能正常工作,检查电路连接的时候真的是让人头皮发麻。使用分立元件设计数字电路不但复杂容易出错,而且电路的速度慢、可靠性不高。

    FPGA的出现就使得数字电路的设计与实现变得更为简单,它把常用的组合逻辑电路和时序逻辑电路等资源大量地堆在芯片内部,逻辑资源之间通过可编程通断的连线连接在一起,这样就可以通过控制逻辑资源之间的连线来构成相应的电路。用户在设计好数字电路后输入到EDA软件中,软件自动编译、综合、布局布线,形成网表文件,最终下载到FPGA芯片配置相应连线的通断,就形成了实现特定功能的电路。

    那么FPGA具体是通过什么原理实现可编程的组合逻辑电路和时序逻辑电路的呢?不同的FPGA有不同的结构,但是它们的基本原理都是一致的,我们知道存储器是可以实现组合逻辑电路的,存储器的地址端口可以作为逻辑变量,而存储器的数据输出就是逻辑函数Y,通过向存储器写入不同的数据就能实现不同的逻辑函数,这样就实现了组合逻辑的可编程。FPGA内部一般是通过小块的RAM以及数据选择器来实现可编程的组合逻辑电路,而通过D触发器实现时序逻辑电路(其他类型的触发器如JK触发器、T触发器等都可由D触发器和组合逻辑电路结合起来实现)。

    Verilog是什么

    接下来的问题就是怎样把自己设计的数字电路通过FPGA实现,这里就要引入硬件描述语言(HDL, Hardware Description Language),数字电路可以使用文本语言来描述,这种文本语言就是硬件描述语言,Verilog HDL就是一种硬件描述语言。从上述的分析中可以得出,编写Verilog代码的过程并不是编程,而是把已经设计好的数字电路转换成文本语言的形式,当然有很多有经验的高手,可以跳过设计数字电路的步骤,能做到“心中有电路”。很多刚刚接触FPGA的初学者,一上来就抱着一本Verilog语法书硬啃,容易误入歧途,正确的学习方法应该是先学好数字电路的基础以及关于FPGA的一些基本概念,在这个基础上再学习Verilog语法。

    数字电路的通用结构

    FPGA数字逻辑设计与传统数字逻辑设计的区别

    很多人不会用Verilog实现自己想要的电路功能,并不是因为不懂Verilog语法,而是不会设计数字电路,“心中无电路”。确实,在本科我们都学过数字电路,接触过一些数字电路的设计方法。但是由于EDA软件的存在,FPGA数字逻辑设计与传统的数字逻辑设计是有一定的区别的,很多步骤可以自动化实现,但是也有一些地方需要特别注意。所以说FPGA数字逻辑设计与传统的数字逻辑设计所关注的重点是不同的。For example,传统数字逻辑设计中设计组合逻辑需要需要费很多精力,要手动化简逻辑函数、必须要使用某种固定组合逻辑功能的芯片来实现电路等等,这些不方便的地方在FPGA数字逻辑设计中是不存在的。FPGA数字逻辑设计中,开发者更多地是关注寄存器传输级(RTL, Register Transfer Level)的电路设计,而且电路可以灵活自由配置,不需要使用功能被固定死的器件,拐弯抹角地实现想要的电路功能。

    数字电路一般模型

    在数字电路课堂上,我们学过同步状态机的一般模型,如图1.这个模型其实就是数字电路的通用模型,图1中包含状态存储器、下一状态逻辑和状态译码器三个模块,当时钟上升沿到达时,状态存储器(实际上就是触发器或寄存器)就将下一状态逻辑的输出存储到寄存器内部,之前下一状态就变成了现态,而从图中可以看出。下一状态又是由现态和输入决定的(输入在有些情况下不存在),也就是已知现态(和输入)就决定了下一状态是什么。这样,状态存储器可以在时钟的控制下,输出一系列状态编码波形,状态编码通过状态译码就得到了输出。

    乍一看这种结构实现的功能没什么大用,或者应用领域非常之窄,但实际上恰恰相反,任何的数字逻辑电路功能都可以由这种结构实现,这种结构具有完备性

    摩尔状态机模型

    图1. 摩尔状态机模型

    这个模型的价值就在于无论实现什么功能的电路、无论有多复杂的电路,最终都可以转化为这种形式(之后我会举几个简单例子说明这种结构的用途),也就是说如果能用Verilog描述这种电路,就可以使用Verilog实现任意的电路功能。实际上,这种电路模型可以非常方便地用硬件描述语言来实现.

    怎样使用Verilog实现电路

    在图2中,我使用电路的形式重新画出了数字电路的一般模型,这里就可以看出怎样使用Verilog描述这一模型。如图2所示,电路中包含两个组合逻辑电路——下一状态逻辑和状态译码器;以及一个时序逻辑电路——D触发器,这里的D触发器是n位的D触发器,也就是一次能够存储n位二进制数据,这在分立元件组成的数字电路中需要使用n个D触发器来实现,但是在使用Verilog的FPGA数字逻辑设计中,从1位到n位只是改一个数字而已。

    在这里插入图片描述

    图2. 摩尔状态机电路实现

    接下来我将使用Verilog完成一个具体实例——16进制计数器,并体现出如何套用图2中的数字电路的一般结构。首先,要实现计数器,就要有具备存储功能的器件,这当然就是图2中的寄存器来实现;要实现16进制的计数器,需要至少4位二进制数字才能表示16个状态,因此要使用4位D触发器作为状态寄存器。首先声明一下顶层模块的端口以及内部寄存器:
    module counter(clk, rst, counter);
    //外部端口声明
    	input clk, rst;
    	output reg [3:0] counter;		//counter代表寄存器的现态
    //内部端口声明
    	reg [3:0] counter_n;			//counter_n代表寄存器的下一状态
    

    下面是状态寄存器的实现代码:

    //状态寄存器的实现
    always @(posedge clk, negedge rst) begin
    	if(!rst)
    		counter <= 4'd0;		//如果复位端口为低电平则时钟上升沿到达后现态变为0
    	else
    		counter <= counter_n;		//如果复位端口为高电平则时钟上升沿到达后现态等于下一状态
    end
    

    之后我们会看到无论多么复杂的电路,状态寄存器的代码几乎是一模一样的,上述代码就像模板一样,只有寄存器的位数和变量名称有变化,另外如果是高电平复位,那么应该去掉rst前面的!非号,其他的内容不应该有任何的变化这里要明确非常重要的一点:硬件描述语言的写法是非常非常固定的。 在我习惯使用的Notepad++编辑器中,我用FingerText插件将这一段代码做成了代码段,只需要输入slc再敲Tab键就可以自动输入实现状态寄存器的这段代码。

    状态寄存器编写完成后,就要考虑下一状态逻辑应该实现怎样的逻辑功能,也就是下一状态等于谁的问题,组合逻辑电路很大程度上决定了整个电路的功能。我们要设计的是加法计数器,计数器的输出应该是从0到15,然后再回到0,因此下一状态逻辑要分两种情况:一是当现态小于15时,此时次态(下一状态)等于现态加1;二是当现态等于15时,此时次态(下一状态)等于0。

    //下一状态逻辑的实现
    always @(*) begin				//敏感变量列表里填*,代表让编译器自动寻找敏感变量
    	if(counter == 4'd15)
    		counter_n = 4'd0;		//当现态为15时,下一状态为0
    	else
    		counter_n = counter + 4'd1;	//当现态不等于15时,下一状态等于现态加1
    end
    

    与状态寄存器相比,下一状态逻辑(组合逻辑电路)的写法就要灵活很多,大概有两种写法,一种是用always语句编写,使用always语句时,always内部的变量必须是reg类型的。always语句内部可以使用行为级建模,用ifelse来描述组合逻辑,也可以用case语句像真值表一样把所有输入和对应的输出罗列出来。另外一种写法是使用assign语句,assign语句用于数据流建模,就是使用逻辑函数或者运算符来定义组合逻辑电路。

    到这里一个完整的计数器例子就已经完成了,这个例子中不需要状态译码,因为它只是简单的计数,并且在实际中,也可以将状态译码去掉,直接用下一状态逻辑实现需要的状态编码。下面是计数器的完整代码:

    module counter(clk, rst, counter);
    //外部端口声明
     	input clk, rst;
     	output reg [3:0] counter;  		//counter代表寄存器的现态
    //内部端口声明
     	reg [3:0] counter_n;   			//counter_n代表寄存器的下一状态
    
    //状态寄存器的实现
    always @(posedge clk, negedge rst) begin
     	if(!rst)
     		counter <= 4'd0;  		//如果复位端口为低电平则时钟上升沿到达后现态变为0
     	else
      		counter <= counter_n;  		//如果复位端口为高电平则时钟上升沿到达后现态等于下一状态
    end
    
    //下一状态逻辑的实现
    always @(*) begin   				 //敏感变量列表里填*,代表让编译器自动寻找敏感变量	
    	if(counter == 4'd15)
    		counter_n = 4'd0; 		 //当现态为15时,下一状态为0
    	else
    		counter_n = counter + 4'd1; 	//当现态不等于15时,下一状态等于现态加1
    end
    endmodule
    

    应用例子:Verilog实现LED闪烁

    电路原理

    在这一部分我将使用Verilog实现硬件领域的Hello World——LED灯闪烁,这个例子会比之前的计数器更加深入。现在假设输入FPGA芯片的时钟为16Hz(实际上不会是这么低的频率,这里仅仅是为了举例),我们打算让LED小灯每隔1s切换一次亮灭。这里我们很自然就产生了一种想法,那就是使用计数器构成的分频器把16Hz的时钟变为1Hz的时钟,然后把1Hz的接到T触发器上,T触发器的输出就会每隔1s切换一次高低电平。如图32所示。


    在这里插入图片描述

    图3. 异步时序电路实现LED闪烁

    图3中所示的电路从原理上讲是没问题的,而且用74系列的芯片也完全能够实现,但是对于FPGA来说,这个电路有一个大问题,那就是它是一个异步时序电路。当电路实际上是异步时序电路时,布局布线器仍然会默认电路是同步时序电路,并且按照同步时序电路来进行时序优化,这样一来,最终的电路就有很大概率会出现问题。实际上,实用的数字电路基本上都是同步时序电路,因为同步时序电路设计简单,易于分析,不容易出现bug,而且对于同步时序电路的时序分析已经很成熟。

    那么怎样使用同步时序电路来实现LED闪烁呢?我们通过观察会发现,实际上分频得到的1Hz的时钟信号并没有必要产生,我们可以通过下一状态逻辑实现n分频使能。如图4所示。
    在这里插入图片描述

    图4. 同步时序电路实现LED闪烁

    图4中红色方框所示的组合逻辑电路决定了对应寄存器的下一状态逻辑,与之前的计数器中的下一状态组合逻辑不同 ,它有两个输入,一个是寄存器的现态,另外一个是我们之前设计的16进制计数器的计数值。为了实现每个1s切换一次LED亮灭,红色方框中的组合逻辑应该实现这样的功能:当计数器的计数值等于15时,次态等于现态取反;当计数值不等于15是次态等于现态。这样,只有计数值达到15时寄存器的高低电平才会跳变。下面就来编写该电路对应的Verilog代码。
    代码实现

    先把之前写的16进制计数器原封不动的照搬过来:

    module LED(clk, rst, led);
    //外部端口声明
    	input clk, rst;
    	output reg led;			//LED灯现态
    //内部端口声明
    	reg [3:0] counter;		//计数器现态
    	reg [3:0] counter_n;		//计数器次态
    	reg led_n			//LED灯次态
    	
    //计数器的寄存器实现
    	always @(posedge clk or negedge rst) begin
    		if(!rst)
    			counter <= 4'd0;
    		else
    			counter <= counter_n;
    	end
    	
    //计数器的下一状态逻辑实现
    	always @(*) begin
    		if(counter == 4'd15)
    			counter_n = 4'd0;
    		else
    			counter_n = counter + 4'd1;
    	end
    

    接下来是LED寄存器的实现,与计数器中的寄存器代码完全一样,只是变量名和位数不一样:

    //LED寄存器
    	always @(posedge clk  or negedge rst) begin
    		if(!rst)
    			led <= 1'b0;
    		else
    			led <= led_n;
    	end
    

    LED下一状态逻辑:

    //LED寄存器下一状态逻辑
    	always @(*) begin
    		if(counter == 4'd15)
    			led_n = ~led;		//如果计数器的计数值为15,则次态等于现态取反
    		else
    			led_n = led;		//如果计数器的计数值不等于15,则次态等于现态
    	end
    endmodule
    

    总结

    本文从底层电路的角度讲述了编写Verilog代码的思路,虽然学好FPGA并不只是编写好RTL代码,要完成更加复杂的功能应该善于使用IP核,但是不管怎么说,会编写RTL代码对理解底层电路的原理有很大的帮助,不然很难解决项目中遇到的问题。

    展开全文
  • 广告是这样的,照片上,一家三口其乐融融在餐厅为女儿庆生,蛋糕上的烛光闪烁,三人脸上洋溢着喜悦……幸福的氛围让人不觉向往,然则所配的文案是:一家三口的日子再精打细算,女儿的生日也要过得像模像样。...
  • 你是不是有过这样的经历:在某一天的早上你突然发现网络性能急剧下降,网络服务不能正常提供,服务器访问速度极慢甚至不能访问,网络交换机端口指示灯疯狂地闪烁、网络出口处的路由器已经处于满负荷的工作状态、...
  • 他们紧张期待着课程的开始,眼里闪烁着对知识的渴望。01PART A由光协帅气的技术部副部长——许鹏师兄为我们讲解C语言基础知识。PART B带了电脑的会员根据上课内容在电脑上完成学长刚刚布置的小作业,没有带电脑的...
  • 我曾久久遥望着星空,在闪烁的群星中一遍遍寻找答案,也常常眺望远山,从那黛青色的山脉中想象青春的色彩;我还不止一次凝视着待开的花朵,希望从花开得声音里听到青春的节律。青春究竟是什么,我带着这个疑问走过...
  • 怎样才能让灯持续地闪烁呢?实际上就是要灯亮一段时间,再灭一段时间,也就是说要P10持续地输出高和低电平。怎样实现这个要求呢?请考虑用下面的指令是否可行:SETBP1.0CLRP1.0……这是不行的,有两个问题,第一,...
  • 怎样才能让灯不断地闪烁呢?实际上就是要灯亮一段时间,再灭一段时间,也就是说要P10不断地输出高和低电平。怎样实现这个要求呢?请考虑用下面的指令是否可行: SETB P10 CLR P10 ……  这是不行的,有两个...
  • 怎样才能让灯不断地闪烁呢?要灯亮一段时间,再灭一段时间,也就是说要P1口不断地输出高和低电平。 编程思路: 在执行完SETB P1后,延时一段时间(几秒或零点几秒)再执行第二条指令,就可以分辨出灯曾灭过了。执行...
  • MFC双缓存画图

    2013-07-13 15:45:46
    在使用MFC画图时,使用Invalidate()函数重画客户区,尤其是使用频繁的时候,我们可以感觉到整个客户区在不停地闪烁, 导致我们的界面的效果特别差,那么怎样能防止这一现象发生呢?我们可以有以下几种方法: ...
  • MFC双缓存学习记录

    2020-09-28 11:17:38
    在使用MFC画图时,使用Invalidate()函数重画客户区,尤其是使用频繁的时候,我们可以感觉到整个客户区在不停地闪烁, 导致我们的界面的效果特别差,那么怎样能防止这一现象发生呢?我们可以有以下几种方法: 局部...
  •  2、老师,您是海洋,我是贝壳,是您给了我斑斓的色彩……我当怎样地感谢您! 3、老师,这个光彩夺目的名称,将像一颗灿烂的明星,永远高悬在我们的胸中。 4、老师,您好比一对伟大的翅膀,安插在我们的身上,带...
  • 我当怎样地感谢您! 老师,在今天我们身上散发的智慧光芒里,依然闪烁着您当年点燃的火花! 没有您的慷慨奉献,哪有我收获的今天。十二万分地感谢您,敬爱的老师。 相逢是首歌,歌中有你有我,分别是明天的路,思念...
  • mfc双缓存画图

    2013-06-25 14:51:42
    在使用MFC画图时,使用Invalidate()函数重画客户区,尤其是使用频繁的时候,我们可以感觉到整个客户区在不停地闪烁, 导致我们的界面的效果特别差,那么怎样能防止这一现象发生呢?我们可以有以下几种方法: ...
  • 《Arduino编程从零开始》使用大量的程序范例一步步、手把手教读者怎样为一块Arduino板进行编程,进而实现想要的功能,从让Arduino板载LED以各种不同的方式来闪烁,一直到通过附加扩展板实现更...
  • 夏天话题作文高二 关于夏天的高二...那些闪烁的灯光让我睁不开眼睛,耳朵被喧闹充斥。我该怎么表达我的心情,要用怎样的方式传达我的不想离开。可是我一句话也没说,看着别人合照咧开的笑脸发愣,发愣。 在白衬衫上...
  •  毕业给老师赠言1 老师,您是海洋,我是贝壳,是您给了我斑斓的色彩……我当怎样地感谢您! 没有您的慷慨奉献,哪有我收获的今天。十二万分地感谢您,敬爱的老师。 老师,在今天我们身上散发的智慧光芒里,依然...
  • 关于夏天的高二作文5篇分享 关于夏天的高二...那些闪烁的灯光让我睁不开眼睛,耳朵被喧闹充斥。我该怎么表达我的心情,要用怎样的方式传达我的不想离开。可是我一句话也没说,看着别人合照咧开的笑脸。 在白衬衫上....
  • 大学老师毕业赠言.doc

    2021-01-15 15:18:18
    大学老师毕业赠言 假如我能搏击蓝天,那是您给了我腾飞的翅膀;... 老师,您是海洋,我是贝壳,是您给了我斑斓的色彩……我当怎样地感谢您! 真空、坚定、谦逊、朴素――这是您教给我唱的歌,这是?..
  • 如果说每个孩子都是一颗小星星,我愿用真诚、热情为他们撑起一片挚爱的晴空,让他们各自闪烁出最灿烂、最动人的光辉!为了让班级充满活力与创新,为了能更好塑造孩子们的心灵,让他们得到全面的发展,也为了使新...

空空如也

空空如也

1 2 3 4 5 ... 8
收藏数 159
精华内容 63
关键字:

怎样地闪烁