精华内容
下载资源
问答
  • 边沿触发

    2014-04-28 15:01:00
    我们即将发明的新型触发器叫做“边沿触发”的D触发器,因为它只在CP脉冲的边沿触发边沿触发的触发器,实际上还分“上升沿D触发器”和“下降沿D触发器”。  下面只讲前一种,即上升沿D触发器,要制作一个上升沿...

      现在,我们希望CP一直为0或者一直为1的期间都不会触发,只在CP从低到高,或者从高到低变化的瞬间触发。我们即将发明的新型触发器叫做“边沿触发”的D触发器,因为它只在CP脉冲的边沿触发。边沿触发的触发器,实际上还分“上升沿D触发器”和“下降沿D触发器”。

      下面只讲前一种,即上升沿D触发器,要制作一个上升沿D触发器,其实很简单,它的秘密在于,可以像下图那样,将两个D触发器首尾相连。

      这个大触发器实际上由两个小的D触发器首尾相连而成,前一个触发器的输出是后一个触发器的输入。而且,这两个触发器永远不会同时工作,因为两个触发器的控制脉冲的值是相反的。

      如果你想在这个电路里保存一个比特,必须先使控制端为0。这时,左边的触发器CP=1,它可以把任何药保存的比特吃进肚子里,并且立即传送给右边的触发器。但是,很遗憾,右边的触发器不工作。

      现在,如果控制器从0跳变到1,说时迟那时快,一起都颠倒了,左边的触发器拒绝再吃掉任何比特,右边的触发器一下子活跃起来,把左边那个触发器的输出保存起来。换句话说,直到这个时候,比特才算是被这个大触发器保存了。

      此后,如果控制端从1又回到0,即下降沿,左边的触发器苏醒过来,但右边的触发器却开始休眠,但它仍有能力维持原先的输出不变。也就是说,控制脉冲的下将沿不会改变这个大触发器的内容。

      同样是之前的脉冲图示,在这个边沿触发器最终保存的值为:1

      上面这个二合一的大触发器,不管控制端是0、1还是从1到0的下降沿,它都不能保存比特,除非一种情况,那就是从0到1的跳变,即上升沿。为了便于表示,上升沿D触发器的符合如下图。

     

    展开全文
  • 水平触发(level trigger,LT)与边沿触发(edge trigger,ET) 水平触发与边缘触发的区别: 水平触发:只要缓冲区有数据就会一直触发 边沿触发:只有在缓冲区增加数据的那一刻才会触发 下面举一个例子说明这...

    epoll有两种触发方式

    水平触发(level trigger,LT)与 边沿触发(edge trigger,ET)

    水平触发与边缘触发的区别:

    水平触发:只要缓冲区有数据就会一直触发

    边沿触发:只有在缓冲区增加数据的那一刻才会触发

    下面举一个例子说明这两者的区别

    /* 使用边沿触发 */
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <sys/epoll.h>
    
    int main(int argc, char *argv[])
    {
        int epfd, nfds;
        struct epoll_event event, events[10];
        int i;
    		
        epfd = epoll_create(10);
        event.data.fd = 0; /* 监听标准输入 */
        event.events = EPOLLIN | EPOLLET; /* 读监听、边缘触发 */
        //event.events = EPOLLIN; /* 读监听、边缘触发 */
        epoll_ctl(epfd, EPOLL_CTL_ADD, 0, &event);
    	
        while (1) 
        {
    
            
            nfds = epoll_wait(epfd, events, 10, -1); /* 放回就绪的描述符数量 */
    		
            for (i = 0; i < nfds; i++) 
            {
                if (events[i].data.fd == 0) 
                {
                    printf("hello world\n");
                }
            }
        }
    	
    	return 0;
    }

    此程序的运行效果,只有当往缓冲区写入数据时才会打印。(注意:由于没有将数据从缓冲区读取,所以此时缓冲区一直有数据)

    如果将 event.events = EPOLLIN | EPOLLET(边沿触发) 改为 event.events = EPOLLIN(水平触发) ,则一旦输入数据,就会循环打印

    这是因为输入数据后,并没有将其从缓冲区读取出来,此时epoll是水平触发,一直检测到缓冲区有数据,所以就一直循环打印

    以上就是水平触发和边沿触发的区别

    下面解释为什么使用边缘触发必须使用非阻塞

    在设置边缘触发时,因为每次发消息只会触发一次(不管缓存区是否还留有数据),所以必须把数据一次性读取出来,否则会影响下一次消息

    下面的代码实现的是监听文件描述符,每次固定读取5个字节

    先看下面这段代码

    int main(int argc, char *argv[])
    {
        int epfd, nfds;
        int i;
        struct epoll_event event, events[10];
        char buf[5];
        int flag;
    	
        epfd = epoll_create(10);
        event.data.fd = 0; /* 监听标准输入 */
        event.events = EPOLLIN | EPOLLET; /* 读监听、边缘触发 */
        //event.events = EPOLLIN; /* 读监听、边缘触发 */
        epoll_ctl(epfd, EPOLL_CTL_ADD, 0, &event);
    
    #if 0
    	flag = fcntl(0, F_GETFL);
    	fcntl(0, F_SETFL, flag | O_NONBLOCK);
    #endif	
     
        while (1)
        {
            int i;
            int num = 0;
            char c;
    		
            nfds = epoll_wait(epfd, events, 5, -1); /* 返回就绪的文件描述符 */
    		
            for (i = 0; i < nfds; ++i) 
            {
                if (events[i].data.fd == STDIN_FILENO) 
                {
                    for(i = 0; i < 5; i++)
                    {
                        buf[i] = getc(stdin);
                        if(buf[i] == -1)
                            break;
                    }
    
                    printf("hello world\n");
                }
                
            }
        }
    	
        return 0;
    }

    这段代码的目的是,使用边沿触发,每次触发读取5个字节,此时getc函数是阻塞读取,这就会引起一个问题,当缓存中的数据小于5时,就会在这里阻塞等待,导致无法处理其他IO,这是非常错误的行为,在并发的服务器中,会导致服务器阻塞,无法处理其他客户端

    正确的处理方法是将读取的文件描述符设置为非阻塞,循环读取,如果没有数据了就放回错误,这样就不会让服务器阻塞

    可以添加下面这两行代码,将标准输入设置为非阻塞IO

    flag = fcntl(0, F_GETFL);
    fcntl(0, F_SETFL, flag | O_NONBLOCK);

    这就解释了为什么边沿触发必须使用非阻塞的问题。

     

    展开全文
  • 水平触发(level trigger,LT)与边沿触发(edge trigger,ET) 水平触发与边缘触发的区别: 水平触发:只要缓冲区有数据就会一直触发 边沿触发:只有在缓冲区增加数据的那一刻才会触发 下面举一个例子说明这...

    目录

     

    简答

    详细

    水平触发(level trigger,LT)与 边沿触发(edge trigger,ET)

    下面解释为什么使用边缘触发必须使用非阻塞


    简答

    ET 模式是一种边沿触发模型,在它检测到有 I/O 事件时,通过 epoll_wait 调用会得到有事件通知的文件描述符,对于每一个"有事”文件描述符,如可读,则必须将该文件描述符一直读到空(返回errno 或EAGAIN 为止),否则下次的 epoll_wait 不会返回余下的数据,会丢掉事件。

    而如果你的文件描述符如果不是非阻塞的,那这个一直读(或一直写)到最后读完了(或写完了)不会直接返回errno 或EAGAIN而是阻塞在那里等待新的数据到来。就会阻塞在那里,不会继续下一个while循环

    epoll ET 一般的调用如下:

    while (1)
    {
        int nFDs = epoll_wait(nEpollFD, events, 128, &timeout);
        for (int i = 0; i < nFDs; i ++)
        {
            if (events[i].events & EPOLLIN)
            {
                // 套接字有读事件,要读空,直到 recv 返回 -1 而且 errno == EAGAIN
                // 监听套接字可 accept 或套接字可读,都会得到可读通知
            }
             
            ...
        }
    }
    
    

    详细

    epoll有两种触发方式

    水平触发(level trigger,LT)与 边沿触发(edge trigger,ET)

    水平触发与边缘触发的区别:

    水平触发:只要缓冲区有数据就会一直触发

    边沿触发:只有在缓冲区增加数据的那一刻才会触发

    下面举一个例子说明这两者的区别

    /* 使用边沿触发 */
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <sys/epoll.h>
     
    int main(int argc, char *argv[])
    {
        int epfd, nfds;
        struct epoll_event event, events[10];
        int i;
    		
        epfd = epoll_create(10);
        event.data.fd = 0; /* 监听标准输入 */
        event.events = EPOLLIN | EPOLLET; /* 读监听、边缘触发 */
        //event.events = EPOLLIN; /* 读监听、边缘触发 */
        epoll_ctl(epfd, EPOLL_CTL_ADD, 0, &event);
    	
        while (1) 
        {
            
            nfds = epoll_wait(epfd, events, 10, -1); /* 放回就绪的描述符数量 */
    
            for (i = 0; i < nfds; i++) 
            {
                if (events[i].data.fd == 0) 
                {
                    printf("hello world\n");
                }
            }
        }
    	
    	return 0;
    }

    此程序的运行效果,只有当往缓冲区写入数据时才会打印。(注意:由于没有将数据从缓冲区读取,所以此时缓冲区一直有数据)

    如果将 event.events = EPOLLIN | EPOLLET(边沿触发) 改为 event.events = EPOLLIN(水平触发) ,则一旦输入数据,就会循环打印

    这是因为输入数据后,并没有将其从缓冲区读取出来,此时epoll是水平触发,一直检测到缓冲区有数据,所以就一直循环打印

    以上就是水平触发和边沿触发的区别

    下面解释为什么使用边缘触发必须使用非阻塞

    在设置边缘触发时,因为每次发消息只会触发一次(不管缓存区是否还留有数据),所以必须把数据一次性读取出来,否则会影响下一次消息

    下面的代码实现的是监听文件描述符,每次固定读取5个字节

    先看下面这段代码

    int main(int argc, char *argv[])
    {
        int epfd, nfds;
        int i;
        struct epoll_event event, events[10];
        char buf[5];
        int flag;
    	
        epfd = epoll_create(10);
        event.data.fd = 0; /* 监听标准输入 */
        event.events = EPOLLIN | EPOLLET; /* 读监听、边缘触发 */
        //event.events = EPOLLIN; /* 读监听、边缘触发 */
        epoll_ctl(epfd, EPOLL_CTL_ADD, 0, &event);
     
    #if 0
    	flag = fcntl(0, F_GETFL);
    	fcntl(0, F_SETFL, flag | O_NONBLOCK);
    #endif	
     
        while (1)
        {
            int i;
            int num = 0;
            char c;
    		
            nfds = epoll_wait(epfd, events, 5, -1); /* 返回就绪的文件描述符 */
    		
            for (i = 0; i < nfds; ++i) 
            {
                if (events[i].data.fd == STDIN_FILENO) 
                {
                    for(i = 0; i < 5; i++)
                    {
                        buf[i] = getc(stdin);
                        if(buf[i] == -1)
                            break;
                    }
     
                    printf("hello world\n");
                }
                
            }
        }
    	
        return 0;
    }

    这段代码的目的是,使用边沿触发,每次触发读取5个字节,此时getc函数是阻塞读取,这就会引起一个问题,当缓存中的数据小于5时,就会在这里阻塞等待,导致无法处理其他IO,这是非常错误的行为,在并发的服务器中,会导致服务器阻塞,无法处理其他客户端

    正确的处理方法是将读取的文件描述符设置为非阻塞,循环读取,如果没有数据了就放回错误,这样就不会让服务器阻塞

    可以添加下面这两行代码,将标准输入设置为非阻塞IO

    flag = fcntl(0, F_GETFL);
    fcntl(0, F_SETFL, flag | O_NONBLOCK);

    这就解释了为什么边沿触发必须使用非阻塞的问题。

     

    讨论:

    Q:

    你最后的结论“边缘触发必须使用非阻塞”,我的意思是“水平触发也需要使用非阻塞IO” 如果水平触发使用阻塞IO,当缓冲区数据不够read需要的字节数,同样会导致read阻塞,无法监听下一次就绪的读事件,进而形成死锁

    A:

    1、如果是水平触发非阻塞,然后一直调用读函数确实也会有这种问题,但如果是水平触发的话一般只会调用一次读函数,因为即使这个回合的数据没有读完,epoll依然会触发,从而再次读取,而不会响应下一个回合的数据,也保证这个回合数据的完整性。

    2、如果是边缘触发,一旦触发必须得把所有的数据读出来,否则将等到下一个回合的数据到来时epoll触发才能读取,如果没有一次读完,那么这一次的数据将不完整,并且会和下一回合的数据混合在一起。

    3、所以在边缘触发时一般都是while读取出所有的数据,直到read函数返回0,这就要求了边缘触发必须是非阻塞。 以上是个人观点~

     

    原文:https://blog.csdn.net/weixin_42462202/article/details/86821382

    展开全文
  • 本文详细介绍了52单片机中的6个中断源和单片机端口的关系以及中断请求源和中断优先级寄存器的讲解及边沿触发程序知识。
  • 资源是51单片机外部中断触发的例程,包括两个例程,一个是电平触发中断的例程,一个是边沿触发中断的例程。两个例程都是采用通道0实现。
  • 51单片机的外部中断有两种触发方式可选:电平触发和边沿触发。选择电平触发时,单片机在每个机器周期检查中断源口线,检测到低电平,即置位中断请求标志,向CPU请求中断。选择边沿触发方式时,单片机在上一个机器...
  • 边沿触发和电平触发的区别

    千次阅读 2019-06-18 19:55:41
    边沿触发和电平触发的区别 本文转自https://www.cnblogs.com/Blub-xinye1/p/5513549.html,如有侵权请联系作者删除。 电平触发:是在高或低电平保存的时间内触发。 电平触发:是由高到低或由低到高这一瞬间触发...

    边沿触发和电平触发的区别

    1. 追问: 我总觉得都是在电平为某一值是而触发的。那边沿触发到底解决了电平触发哪点没有解决的问题呢?
      • 追答:边沿触发一般时间短,边沿触发一般时间都是us级的,响应要快的,而电平触发只须是高和低就可以了,没时间要求,比如10s 时间内总是低电平,那么它也是触发的,比如中断计时或计数,最好用边沿触发,用电平触发误差会很大,电平触发一般用于简单报警,开关一类(时间要求不高的)

    分类

    • 电平触发,就是只有高电平的时候才做指定的事。
    • 边沿触发,就是有高电平向低电平转换,或者翻过来转换,这个转换过程触发一个动作。
      1. 上升沿:由低电平向高电平转换的瞬间
      2. 下降沿:由高电平向低电平转换的瞬间
        bydp_001.jpg
    1. 电平就是电压,高电平就是高电压,低电平就是低电压
    2. 高电平触发就是当电压为高就触发
    3. 边沿触发就是当电压由高变低或由低变高时触发
    4. 上升沿触发 就是当电压从低变高时触发
    5. 下降沿触发 就是当电压从高变低时触发
    • 边沿触发:上升沿和下降沿,这个在学数电时都学过的,简单说就是电平变化那一瞬间。
    • 电平触发:一般是指低电平,就是电平变为低了之后的全部时间里。
    • 如果是下降沿触发,当从高至低电平转变时,触发产生。低电平保持多久都只产生一次。
    • 如果是低电平触发,那么在低电平时间内中断一直有效。如果在电平没有恢复之前就退出中断程序,那么会在退出后又再次进入中断。只要不退出是不会重复触发的。我的做法是在退出前关闭中断,等后面有空时再打开。
    展开全文
  • 电平触发和边沿触发的区别

    万次阅读 多人点赞 2018-07-08 12:04:06
    电平触发是在高或低电平保持的时间内触发,而边沿触发是由高到低或由低到高这一瞬间触发 在数字电平变化的电压上升沿或下降沿到一定阀值时就产生触发,是谓边沿触发。当电压达到数字电平的高或低电压一段时间后...
  • 边沿触发与水平触发

    2021-07-17 08:54:41
    比如老师给你说你要完成作业,老师见你一次给你说一次,直到你把作业写完,这就是水平触发,老师如果只给你说一次,你爱写不写,这就是边沿触发。做不做是你自己的事情。 epoll select poll不仅适用于socket套接字,...
  • 单片机边沿触发中断响应时刻的测量.pdf
  • 电平触发、脉冲触发、边沿触发的区别

    万次阅读 多人点赞 2019-06-15 22:40:14
    电平触发、脉冲触发、边沿触发的区别电平触发脉冲触发边沿触发 电平触发 触发信号为有效电平(高或低)时,输入信号进入触发器电路,置触发器为相应状态。触发信号变为无效电平后,输入信号被封锁,触发器状态保持。...
  • 边沿触发与电平触发的区别

    千次阅读 2018-09-14 17:54:34
    1、边沿触发 边沿触发包括上升沿触发和下降沿触发,边沿触发检测的是电平变化,高电平转低电平或低电平转高电平时,触发一次中断。 边沿沿触发是锁存中断信号的,由D触发器记忆,即:若CPU来不及响应中断,外部...
  • 若监听的套接字描述符上有数据可读或可写,LT模式(水平触发)和ET模式(边沿触发)两种模式对应不同的通知模式。 LT模式会不断的通知监听的套接字有数据可读或可写(对应套接字的读缓冲区不为空或写缓冲区不为满); ET...
  • epoll模式下的水平触发、边沿触发 1,epoll默认是水平触发 2,水平触发通俗来讲:只要有数据,epoll_wait函数就一直返回;边沿触发通俗来讲:只有socket状态发生变化,epoll_wait函数才会返回。 3,水平触发优、...
  • 数字边沿启动触发,一通道有限采样,波形图显示
  • 2、边沿触发 只有缓冲区接收到新数据,才会触发事件。 如果触发了事件,但是没有读完缓冲区,也不会再次触发。 所以如果要使用边沿触发,就一定要保证一次触发事件,处理函数一定要读完接收缓冲区。否则下一次再触发...
  • FPGA中边沿触发和电平触发

    千次阅读 2018-07-17 19:49:00
    边沿触发和电平触发基本就是触发器和锁存器的区别: 触发器是边沿触发,只有当时钟上升(或下降)的一瞬间,触发器会读取并锁存输入信号。输出信号仅在时钟信号上升(或下降)的一瞬间会发生变化。 锁存器是电平...
  • 1、边沿触发 边沿触发包括上升沿触发和下降沿触发,边沿触发检测的是电平变化,高电平转低电平或低电平转高电平时,触发一次中断。 2、电平触发 电平触发分为高电平触发和低电平触发;电平触发需要手动清除中断信号...
  • epoll水平触发、边沿触发与非阻塞I/O模型epoll水平触发、边沿触发与非阻塞I/O模型水平触发与边沿触发非阻塞I/Oepoll水平触发导致效率低下的重要原因 epoll水平触发、边沿触发与非阻塞I/O模型 epoll作为多路I/O复用在...
  • MCS51单片机系列属于8位单片机,它是Intel公司继MCS48系列的成功设计之后,于1980年推出的产品。...若为1,则控制为边沿触发方式。这里是下降沿触发中断。  1 问题的引出  几乎国内所有的单片机资料对单片机边沿
  • } //边沿触发方式 #include #include #define uint unsigned int #define uchar unsigned char sbit D1=P2^0; uchar num; uchar wnum=0x00; uchar code dbit[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f...
  • MCS51单片机系列属于8位单片机,它是Intel公司继MCS48系列的成功设计之后,于1980年推出的产品。由于MCS51系列具有很强的片内功能和指令系统,因而使单片机的...若为1,则控制为边沿触发方式。这里是下降沿触发中断。
  • 边沿触发为什么要结合非阻塞IO,以及什么是非阻塞IO
  • 使用epoll多路复用编程时,会用epoll_wait阻塞等待事件的发生,对应有边沿触发和水平触发两种工作模式。 一、水平触发(EPOLLLT) 水平触发:只要缓冲区有数据,epoll_wait就会一直被触发,直到缓冲区为空; 水平...
  • 在 epoll 的 man 手册里其实并没有对边沿触发有一个特别清晰和明确的定义,作者也只是举了一个例子来阐述边沿触发的表现,在使用的时候还需要根据具体实现去测试它的行为。 在 man 手册里,作者列举了这样一个场景...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 11,313
精华内容 4,525
关键字:

边沿触发