FPGA驱动旋转编码器(Verilog)
简述
遇到问题:不知道怎么使用旋转编码器;不知道判断左旋右旋;编码器硬件消抖后还是抖动、乱跳,不符合编程预想结果。
编程思路:通过信号打拍进行信号跳变检测;当一个端口的跳变时,判断另一个端口的电平状态,来判断是左旋还是右旋;通过计数器计数来消除编码器的抖动。
正文
最近学习FPGA的时候有用到旋转编码器,学习过程也遇到许多的困难,也有看许多关于旋转编码器的文章,不过许多的文章都是关于C语言的,关于Verilog的非常少,因此准备写一篇FPGA驱动旋转编码器的文章。代码亲测可用。
遇到的问题
1、如何判断左旋右旋;
2、编码器加了硬件消抖后仍然有抖动、乱跳。
编码器介绍
目前我所遇到的编码器有两种,一种是拧动一下,端口电平跳变一次;另一种是拧动一下,端口产生一个高电平脉冲。不过两种编码器都有共同特点,左旋旋钮左端口电平先跳变,右旋旋钮右端口先跳变。(图片是自己画的有点简陋,凑合一下吧)
第一种编码器
第二种编码器
硬件电路
这里附上我的硬件电路图
代码编写
思路:
通过打拍,再进行逻辑判断,检测信号的上升沿和下降沿。
一个端口跳变的时候,判断另一个端口的电平。(如左端口出现上升沿时右端口是低电平代表左拧一次,以此类推。)
通过设置计数器计数1ms用于消除信号抖动。(计数时长根据自己需求修改)
代码:(亲测可用)
module rotary_encoder
(input wire sys_clk ,//时钟信号input wire sys_rst_n ,//复位信号input wire left_io ,//左/A端口input wire right_io ,//右/B端口
// input wire button_io ,output reg left_flag ,//左旋单脉冲信号output reg right_flag //右旋单脉冲信号
// output reg button_flag );parameter CNT_MAX = 16'd49_999;//计数1ms//用于打拍
reg left_io1 ;
reg right_io1;//计数延迟消抖
reg [15:0] cnt_left ;
reg [15:0] cnt_right;//稳定的电平信号
reg left_deb ;
reg right_deb;//用于打拍
reg left_deb1 ;
reg right_deb1;//各端口上升、下降沿信号
wire left_pose ;
wire right_pose;
wire left_nege ;
wire right_nege;//左端口计数消抖
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)cnt_left <= 16'd0;else if(left_io != left_io1)cnt_left <= 16'd0;else if(cnt_left == CNT_MAX)cnt_left <= CNT_MAX;elsecnt_left <= cnt_left + 16'd1;always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)left_deb <= 1'b0;else if(cnt_left == (CNT_MAX - 16'd1))left_deb <= left_io1;elseleft_deb <= left_deb;//右端口计数消抖
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)cnt_right <= 16'd0;else if(right_io != right_io1)cnt_right <= 16'd0;else if(cnt_right == CNT_MAX)cnt_right <= CNT_MAX;elsecnt_right <= cnt_right + 16'd1;always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)right_deb <= 1'b0;else if(cnt_right == (CNT_MAX - 16'd1))right_deb <= right_io1;elseright_deb <= right_deb;//打拍
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)beginleft_io1 <= 1'b0;right_io1 <= 1'b0;left_deb1 <= 1'b0;right_deb1 <= 1'b0;endelsebeginleft_io1 <= left_io ;right_io1 <= right_io ;left_deb1 <= left_deb ;right_deb1 <= right_deb;end//检测跳变
assign left_pose = left_deb & (!left_deb1);
assign right_pose = right_deb & (!right_deb1);
assign left_nege = left_deb1 & (!left_deb);
assign right_nege = right_deb1 & (!right_deb);// 左端口上升沿时,右端口低电平||左端口下降沿时,右端口高电平
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)left_flag <= 1'b0;else if((left_pose==1'b1) && (right_deb==1'b0))left_flag <= 1'b1;else if((left_nege==1'b1) && (right_deb==1'b1))left_flag <= 1'b1;elseleft_flag <= 1'b0;// 右端口上升沿时,左端口低电平||右端口下降沿时,左端口高电平
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)right_flag <= 1'b0;else if((right_pose==1'b1) && (left_deb==1'b0))right_flag <= 1'b1;else if((right_nege==1'b1) && (left_deb==1'b1))right_flag <= 1'b1;elseright_flag <= 1'b0;endmodule
我使用的是第一种旋转编码器,最后的判断能实现每拧一次,获得一个对应信号脉冲,当然也可以根据自己的需求拆解开。
注意!如果使用的是第二种旋转编码器,最后的判断会输出两个对应信号脉冲,需要自己拆开。
这段代码已实现左旋和右旋的判断,还缺少按下的判断,如有需求,可自行仿照左旋和右旋的代码逻辑编写。
希望这篇文章能够帮助到你,如有不足欢迎各位大佬指正。
FPGA驱动旋转编码器(Verilog)相关推荐
- STM32 编码器驱动/旋转编码器旋钮encoder
本文已比较纯粹的方式介绍编码器和驱动的编写 编码器最少有两个输出信号,一种典型的结构如上图所示.AB是编码器的输出引脚.当触点和黄色的金属片接触的时候信号发生跳变沿,可以上上升沿也可以是下降沿,具体根 ...
- 基于FPGA的分形编码器verilog设计
目录 一.理论基础 二.核心程序 三.仿真测试结果 一.理论基础 分形图像编码是目前较有发展前途的图像编码方法之一, 也是目前研究较为广泛的编码方法之一.对其研究已有近十年的历史,其间,人们发现了它所 ...
- 两相编码器的FPGA驱动
两相编码器的驱动原理 根据A,B相的相位差,即相位的领先或落后来判断编码器转轴旋转方向,根据编码器旋转产生的脉冲来计数. 二.输出信号 1.信号序列 一般编码器输出信号除A.B两相(A.B两通道的信号 ...
- 旋钮编码器c代码_旋转编码器EC11驱动
旋转编码器EC11驱动 /*-------->>>>>>>>--------注意事项:EC11旋转编码器的扫描时间间隔控制在1~4ms之间, 否则5ms ...
- linux4.6 EC11旋转编码器的驱动
最近项目使用了旋转编码器EC11,遍查内核,发现并没有它的驱动,查了查CSDN,终于找到一篇有用的.根据自己的需要和对最基础的gpio_key.c的理解,我改写出了一份EC11的专用驱动. 感谢下面博 ...
- 11旋转编码器原理_科普小知识:八分钟了解电机编码器!
获取更多学习资料知识可以扫码加微信进入非标设计学习交流微信群,也可直接加QQ群:834928686看免费非标设备设计直播公开课学习,领取课堂学习礼包! 编码器的工作原理及作用:它是一种将旋转位移转换成 ...
- 【swjtu】数字电路实验6_旋转编码器人机交互电路设计
一. 实验目的 1 . 学习旋转编码器的使用. 2 . 巩固 Verilog HDL 设计时序电路. 二. 实验内容 旋转编码器是一种输入器件,常用于示波器.信号源.汽车仪表盘等各种电子设备中,它可以 ...
- BH38旋转编码器初步测试
■ 实验背景 在 42HS48EIS步进闭环电机最大转速 对于42HS48EIS这款步进电机和驱动合在一起的电机进行了测试,准备将其应用到实验室机械臂关节驱动中.但这款电机体积略长,现在又购得同款小体 ...
- 11旋转编码器原理_旋转编码器的原理是什么?增量式编码器和绝对式编码器有什么区别?...
先给出结论,最重要的区别在于:增量式编码器没有记忆,断电重启必须回到参考零位,才能找到需要的位置,而绝对式编码器,有记忆,断电重启不用回到零位,即可知道目标所在的位置. 接下来细说一下,主要包含如下的 ...
最新文章
- 大神开车的标题-python中类方法、类实例方法、静态方法的使用与区别
- 分布式消息通信ActiveMQ原理-持久化策略-笔记
- MySQL · 特性分析 · 优化器 MRR BKA
- 关于通配泛型类型有几种_5.7 泛型通配符和类型参数的范围
- python国内谁的书最好看_强烈建议|转行Python最好看一下这篇文章
- c++ 打印条码_金蝶盘点机PDA仓库条码管理之——外购入库扫码开单操作
- 89c51,8255,6个led数码管显示时钟的汇编语言程序,汇编语言要求编写一个时钟程序 用八位数码管实现时分秒的计时功能...
- 2019年7月9日星期二(C语言)
- 【编辑器】Atom上手
- 基于fo-dicom 的 Worklist CStore 我的学习实现路线
- 2022-09-13 mysql列存储引擎-POC-查询数据错误追踪
- 推荐给中学生的数学课外书:《怎样解题——数学思维的新方法》
- 博弈论——取石子问题
- cpp调用c头文件引用方法
- 【Linux】yum install cmake 报错,出现错误ImportError: No module named urlgrabber.grabber
- 传统安防互联网化无插件直播分析及解决方案
- App Store上推广App的实战经验
- 【云服务器 ECS 实战】一文掌握弹性伸缩服务原理及配置方法
- oracle 的dual是什么东西
- XigmaNAS(原 NAS4Free) 发布 11.2.0.4.6625 版本