边沿检测电路

边沿检测指的是检测一个信号的上升沿或者下降沿,如果发现上升沿或者下降沿,则给出一个信号指示出来。边沿检测电路 一般分为上升沿检测电路、下降沿检测电路和双沿检测电路。
复杂的逻辑设计里面,很多情况都需要检测信号的跳变,如果一个信号发生跳变,则给出一个指示,这个指示用来触发其他的动作,这里就需要有一个边沿检测电路 。

上升沿检测电路

信号检测由 0变 1的过程 ,就是上升沿检测电路( posedge edge 信号检测由1变0的过程 就是下降沿检测电路( negedge edge)。若上升沿和下降沿都检测,则这个电路就是双沿检测电路( double edge)。
在always块的敏感信号列表中可以直接用 posedge和 negedge来提取上升沿和下降沿,但是如果要在 always程序块的内部检测上升沿或者下降沿呢?还是用 poesedge和 negedge吗? 我们来实验下我们的推测,代码如下:

module edge_test 
( 
 input clk , // system clock 50Mhz on board 
 input rst_n, // system rst, low active 
 input a , 
 input b , 
 output reg y // output signal 
 ); 
 //============================================================== 
 // ------------------------- MAIN CODE ------------------------ 
 //============================================================== 
 always @ (posedge clk or negedge rst_n or posedge a) begin 
 if (rst_n == 1'b0) 
 y <= 1'b0 ; 
 else 
 y <= b ; 
 end 
 endmodule

always块的信号敏感变量有三个,一个是时钟clk,一个是复位rst_n,一个是a信号。y信号是在时钟clk或者a信号的上升沿进行跳变,在复位的rst_n下降沿进行复位。
通过Quartus或者 Vivado等工具进行全编译,在 Quartus里面发现是可以编译成功的, 编译后的Quartus RTL viewer显示的电路结构如下:

这个只是一个组合逻辑的选择电路,并没有寄存器,分析告警,

这个意思是说输出y和clk或者a都没有关系,也就是说这个边沿检测电路不可行。这个地方也间接说明always块的信号敏感变量只能有一个时钟和一个复位。带时钟的always块电路都是寄存器,而寄存器一般只有一个时钟信号,所以边沿检测不能直接利用always块的信号敏感变量作为边沿检测。

如上图所示,a信号是一个持续2个时钟周期的信号,如果想得到a信号的上升沿,这个上升沿就是a_posedge信号。a_posedge信号是一个持续1个时钟周期的脉冲信号,把a信号寄存一拍,得到a_dly1信号,再用a信号和a_dly1取反再相与,就可以得到一个持续1个时钟周期的脉冲信号,这个a_posedge信号就是a的上升沿指示信号。

下降沿检测电路。

如上图所示,a信号是一个持续2个时钟周期的信号,如果想得到a信号的下降沿,这个下降沿就是a_negedge信号。a_negedge信号是一个持续1个时钟周期的脉冲信号,把a信号寄存一拍,得到a_dly1信号,再把a信号取反,用a取反的信号和a_dly1相与,就可以得到一个持续1个时钟周期的脉冲信号,这个a_negedge信号就是a的下降沿指示信号。

下双沿检测电路

如上图所示,a信号是一个持续2个时钟周期的信号,如果想得到a信号的上升沿和下降沿,这个信号就是a_edge信号。a_edge信号刚好是a和a_dly1信号不同的地方为高电平,也就是a和a_dly1异或的结果就是a_edge信号,这个信号在a的上升沿持续一个时钟周期,然后在a的下降沿后又持续一个时钟周期。

程序设计

module edge_test 
 ( 
input clk , // system clock 50Mhz on board 
 input rst_n, // system rst, low active 
 input a ,  
output y1 , // output signal
output y2 , // output signal 
 output y3 // output signal 
 ); 
 reg a_dly1 ; 
 //================================================================ 
 // ------------------------- MAIN CODE -------------------------- 
 //================================================================ 
 always @ (posedge clk or negedge rst_n ) begin 
 if (rst_n == 1'b0) 
 a_dly1 <= 1'b0 ; 
 else 
 a_dly1 <= a ; 
 end 
 assign y1 = a & ( ~a_dly1 ) ; 
 assign y2 = ~a & a_dly1 ; 
 assign y3 = a ^ a_dly1 ; 
 endmodule

从上图可以看出,a_dly1是a寄存一拍的结果,y1是上升沿检测输出,y2是下降沿检测输出,y3是双沿检测输出(异或门)。

参考引用学习:

《正点原子逻辑设计指南 V1.9》

### PWM 边沿检测电路设计 PWM边沿检测电路用于识别PWM信号的上升沿或下降沿,这对于精确捕捉PWM周期和占空比至关重要。通过检测这些边沿事件,可以实现更精准的时间测量和其他控制功能。 #### 设计原理 在硬件层面,边沿检测通常依赖于专用逻辑门电路或微控制器内部资源来完成。对于基于微控制器的应用场景,输入捕获单元是一个常用的选择[^4]。该模块能够自动记录特定条件下的定时器状态,从而简化了软件编程复杂度并提高了响应速度。 具体来说,在STM32系列单片机中,TIMx->CCER寄存器中的`CC1P`位用来决定是监测上升沿还是下降沿。当配置为上升沿敏感时,只有遇到正跳变才会触发中断服务程序;反之亦然。此外,还可以启用双边沿触发模式以同时处理两种类型的转换。 #### 实现方法 为了提高抗干扰能力以及确保可靠的工作性能,实际应用时常采用施密特触发器作为前置缓冲级。这种器件具有迟滞特性,能够在噪声环境下稳定工作而不易误判边缘位置变化。 下面给出一段简单的C语言伪代码片段展示如何初始化一个典型的PWM输入捕获通道: ```c void Init_PWM_InputCapture(void){ // 配置GPIO引脚为复用推挽输出 GPIO_InitTypeDef GPIO_InitStruct; __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_0; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // 初始化定时器 TIM_HandleTypeDef htim1; htim1.Instance = TIM1; htim1.Init.Prescaler = 79; htim1.Init.CounterMode = TIM_COUNTERMODE_UP; htim1.Init.Period = 65535; htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; HAL_TIM_IC_ConfigChannel(&htim1, &sConfigIC, TIM_CHANNEL_1); } ``` 上述代码展示了针对STM32平台的一个基本框架,其中包含了必要的外设使能及时钟分频设定等内容。需要注意的是,具体的参数值应根据实际情况调整优化。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值