集成电路技术分享

 找回密码
 我要注册

QQ登录

只需一步,快速开始

搜索
查看: 2644|回复: 0

仿制HCTL-2016的旋转增量(正交)编码器计数器

[复制链接]
老怪甲 该用户已被删除
老怪甲 发表于 2010-5-8 09:49:51 | 显示全部楼层 |阅读模式
仿制HCTL-2016的旋转增量(正交)编码器计数器

最近要用到旋转增量(正交)编码器,想买HCTL-2016,找不到货源,干脆自己现学VerilogHDL,做了一个解码器,呵呵
望大家批评指正,开发环境Quartus II 7.2

//给懒人们贴上来,干脆
// ***************************************************************
//
// AB_DECODER.v Decoder for phase A and B encoder
//
// V1.00 2009-6-04
//
// Design by cqfeiyu in chongqing, all right reserved
//
// ***************************************************************

module AB_DECODER
(
DI_SYSCLK,
DI_PHASE_A,
DI_PHASE_B,
DI_PHASE_Z,
DI_ADDER,
DI_RD,
DI_OE,
DO_PULSE,
DO_DIRECT,
DO_COUNT
);

// input
//
input DI_SYSCLK;
input DI_PHASE_A;
input DI_PHASE_B;
input DI_PHASE_Z;
input DI_RD;
input DI_OE;
input [1:0] DI_ADDER;
// output
//
output DO_PULSE;
output DO_DIRECT;
output [7:0] DO_COUNT;

// register
//
reg [23:0] ENCODER_COUNT;
reg [7:0] DO_COUNT;
reg [3:0] COUNT_PHASE_A;
reg [3:0] COUNT_PHASE_B;
reg [3:0] COUNT_PHASE_Z;

reg PULSE;
reg PULSE_LAST;
reg DO_DIRECT;

reg PHASE_A;
reg PHASE_B;
reg PHASE_Z;

reg PULSE_DOUBLE;
reg PULSE_DOUBLE_LAST;

reg PHASE_A_LAST;
reg PHASE_B_LAST;
reg PHASE_Z_LAST;

reg DI_RD_LAST;

reg DO_PULSE1;
reg DO_PULSE2;
reg DO_PULSE3;
reg DO_PULSE4;

assign DO_PULSE=PULSE_LAST;

always @(posedge DI_SYSCLK) begin
COUNT_PHASE_A <= COUNT_PHASE_A << 1;
COUNT_PHASE_A[0] <= DI_PHASE_A;
COUNT_PHASE_B <= COUNT_PHASE_B << 1;
COUNT_PHASE_B[0] <= DI_PHASE_B;
COUNT_PHASE_Z <= COUNT_PHASE_Z << 1;
COUNT_PHASE_Z[0] <= DI_PHASE_Z;
end

always @(posedge DI_SYSCLK) begin
if(COUNT_PHASE_A == 4'b1111)
PHASE_A = 1'B1;
else PHASE_A = 1'B0;
PHASE_A_LAST <= PHASE_A;
DO_PULSE1 <= (!PHASE_A_LAST)& PHASE_A;
DO_PULSE2 <= PHASE_A_LAST & (!PHASE_A);
end

always @(posedge DI_SYSCLK) begin
if(COUNT_PHASE_B == 4'b1111)
PHASE_B = 1'B1;
else PHASE_B = 1'B0;
PHASE_B_LAST <= PHASE_B;
DO_PULSE3 <= (!PHASE_B_LAST)& PHASE_B;
DO_PULSE4 <= PHASE_B_LAST & (!PHASE_B);
end

always @(posedge DI_SYSCLK) begin
if(COUNT_PHASE_Z == 4'b1111)
PHASE_Z = 1'B1;
else PHASE_Z = 1'B0;
PHASE_Z_LAST <= PHASE_Z;
end

always PULSE = DO_PULSE1 | DO_PULSE2 | DO_PULSE3 | DO_PULSE4;

always @(posedge DI_SYSCLK) begin
if((DO_PULSE1 & PHASE_B) | (DO_PULSE2 & !PHASE_B) | (DO_PULSE3 & !PHASE_A) | (DO_PULSE4 & PHASE_A))DO_DIRECT<=1;
else if((DO_PULSE1 & !PHASE_B) | (DO_PULSE2 & PHASE_B) | (DO_PULSE3 & PHASE_A) | (DO_PULSE4 & !PHASE_A))DO_DIRECT<=0;
end

always @(posedge DI_SYSCLK) begin
PULSE_LAST<=PULSE;
if((PHASE_Z_LAST==1)&&(PHASE_Z==0))ENCODER_COUNT = 24'd0;
else if(PULSE_LAST)begin
if(DO_DIRECT)ENCODER_COUNT<=ENCODER_COUNT + 1'b1;
else ENCODER_COUNT<=ENCODER_COUNT- 1'b1;
end
end

always @(posedge DI_SYSCLK) begin
DI_RD_LAST<=DI_RD;
if(DI_OE==1)DO_COUNT<=8'bZ;
else if((DI_RD_LAST==0)&&(DI_RD==1))begin
case(DI_ADDER)
0: DO_COUNT<=8'd0;
1: DO_COUNT<=ENCODER_COUNT[7:0];
2: DO_COUNT<=ENCODER_COUNT[15:8];
3: DO_COUNT<=ENCODER_COUNT[23:16];
//default: DO_COUNT<=8'bZ;
endcase
end
end

endmodule
您需要登录后才可以回帖 登录 | 我要注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

QQ|小黑屋|手机版|Archiver|fpga论坛|fpga设计论坛 ( 京ICP备20003123号-1 )

GMT+8, 2024-12-23 23:42 , Processed in 0.056467 second(s), 20 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表