一、前言
在利用處理編碼信號(hào)時(shí),一般在較為理想的環(huán)境下可以很方便進(jìn)行計(jì)算,判斷等。但是由于有時(shí)候受到電磁干擾等環(huán)境因素,會(huì)導(dǎo)致編碼信號(hào)產(chǎn)生毛刺等,這時(shí)候如果不對(duì)編碼信號(hào)進(jìn)行預(yù)處理而是直接進(jìn)行邊緣判斷等操作則極容易導(dǎo)致錯(cuò)誤,所以需要提前對(duì)編碼信號(hào)進(jìn)行濾波。
二、濾波算法
其算法思想也容易理解:如果有電平跳變,則立即進(jìn)行計(jì)數(shù),如果計(jì)數(shù)值超過(guò)設(shè)定閾值,則電平跳轉(zhuǎn)有效,否則依然保持原電平不變。另外如果在計(jì)數(shù)時(shí)又發(fā)生電平跳轉(zhuǎn),則重新進(jìn)行計(jì)數(shù)。濾波算法跳轉(zhuǎn)圖如下:
三、代碼設(shè)計(jì)
首先我們需要確定編碼信號(hào)的毛刺信號(hào)大概時(shí)間寬度為多少,這樣我們才能設(shè)置閾值進(jìn)行濾波。以Altera芯片設(shè)計(jì)為例,可以利用SigalTapII嵌入式邏輯觀測(cè)毛刺的時(shí)間寬度。
這樣設(shè)計(jì)代碼如下即可實(shí)現(xiàn)濾波效果:
module encoder_filter (
input clk,
input A, //原始編碼信號(hào)A
output reg A_f, //濾波后的編碼信號(hào)A_f
output led, //觀測(cè)程序是否燒錄成功
output samp_clk_20us //SigalTapII中采樣時(shí)鐘
);
pll_ippll_ip_inst ( //調(diào)用PLL_IP
.inclk0 ( clk ),
.c0 ( samp_clk_20us )
);
parameter [11:0] Cnt_20us=12'd1000; //20us/20ns=1000; //毛刺的脈寬不會(huì)大于20us
parameter [1:0] S0 = 2'b00, S1 = 2'b01, S2 = 2'b10, S3 = 2'b11;
reg [1:0] state; //當(dāng)前狀態(tài)
reg [2:0] A_delay; //延遲打拍
reg [11:0] count; //電平跳轉(zhuǎn)計(jì)數(shù)
reg last_level; //A的上一個(gè)電平狀態(tài)
reg A_sig_pos;
reg A_sig_neg;
reg [7:0] reset_counter=8'd0;
always@(posedge clk) //軟件不發(fā)復(fù)位信號(hào),FPGA自己產(chǎn)生,邏輯加載起來(lái)后馬上自己復(fù)位一次。
begin
if (reset_counter != 8'h59 )
reset_counter <= reset_counter + 8'h1;??
end
reg n_rst;
always@(posedge clk) //軟件不發(fā)復(fù)位信號(hào),F(xiàn)PGA自己產(chǎn)生,邏輯加載起來(lái)后馬上自己復(fù)位一次。
begin
if((reset_counter > 8'd1)&&(reset_counter < 8'd6))
n_rst <= 1'b0;? ? ?
else
n_rst <= 1'b1;
end
assign led=1'b0;
always @(posedge clk or negedge n_rst ) //將外部a信號(hào)進(jìn)行時(shí)鐘同步
begin
if(n_rst==1'b0)
A_delay <=2'b00;
else
A_delay <={A_delay[1:0],A};
end
wire A_risingedge=(A_delay[2:1]==2'b01);
wire A_fallingedge=(A_delay[2:1]==2'b10);
always @(posedge clk or negedge n_rst )
begin
if(n_rst==1'b0)
begin
state<= S0;
count<=12'b0;
last_level<=1'b0;
A_sig_neg<=1'b0;
A_sig_pos<=1'b0;
end
else
case(state)
S0://空閑狀態(tài),判斷電平是否變化
begin
if(A_risingedge||A_fallingedge)
begin
state<= S1;
count<=12'b0;
last_level<=A_delay[2];
end
end
S1://計(jì)數(shù)狀態(tài)
begin
if(A_delay[2]==A_delay[1])
if(count==Cnt_20us)//判斷計(jì)數(shù)是否達(dá)到20us
begin
count<=12'b0;
state<= S2;
end
else
count<=count+1'b1;
else
count<=12'b0;
end
S2://判決狀態(tài)
begin
state<= S3;
if(!last_level&&A_delay[1])//確定是由低電平---->高電平
begin
A_sig_pos<=1'b1;
A_sig_neg<=1'b0;
end
else if(last_level&&!A_delay[1])//確定是由高電平---->低電平
begin
A_sig_neg<=1'b1;
A_sig_pos<=1'b0;
end
else
begin
A_sig_neg<=1'b0;
A_sig_pos<=1'b0;
end
end
S3:
begin
state<= S0;
count<=12'b0;
end
default:
begin
state<= S0;
count<=12'b0;
end
endcase
end
always @(posedge clk or negedge n_rst )
begin
if(n_rst==1'b0)
A_f<=1'b0;
else if(A_sig_pos==1'b1)
A_f<=1'b1;
else if(A_sig_neg==1'b1)
A_f<=1'b0;
else
A_f<=A_f;
end
endmodule
值得注意的是:
1、需要根據(jù)實(shí)際毛刺Cnt_20us的時(shí)間寬度改變閾值
2、在程序使用了軟復(fù)位,由于未設(shè)置按鍵這種異步復(fù)位,就實(shí)際程序隨板子上電后在主時(shí)鐘下進(jìn)行軟件同步復(fù)位。
審核編輯:劉清
-
FPGA
+關(guān)注
關(guān)注
1626文章
21667瀏覽量
601838 -
嵌入式
+關(guān)注
關(guān)注
5068文章
19018瀏覽量
303265 -
電磁干擾
+關(guān)注
關(guān)注
36文章
2287瀏覽量
105312 -
異步復(fù)位
+關(guān)注
關(guān)注
0文章
47瀏覽量
13300
原文標(biāo)題:FPGA處理編碼信號(hào)進(jìn)行毛刺濾波
文章出處:【微信號(hào):gh_9d70b445f494,微信公眾號(hào):FPGA設(shè)計(jì)論壇】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論