基于旋轉(zhuǎn)編碼器的調(diào)節(jié)系統(tǒng)設(shè)計(jì)
實(shí)驗(yàn)任務(wù)
實(shí)驗(yàn)?zāi)康?/h4>在基礎(chǔ)數(shù)字電路實(shí)驗(yàn)部分我們已經(jīng)掌握了FPGA驅(qū)動(dòng)獨(dú)立顯示數(shù)碼管的原理及方法,本實(shí)驗(yàn)主要學(xué)習(xí)旋轉(zhuǎn)編碼器的驅(qū)動(dòng)原理,最后完成旋轉(zhuǎn)調(diào)節(jié)系統(tǒng)總體設(shè)計(jì)。
本文引用地址:http://2s4d.com/article/202312/453766.htm設(shè)計(jì)框圖
根據(jù)前面的實(shí)驗(yàn)解析我們可以得知,該設(shè)計(jì)可以拆分成三個(gè)功能模塊實(shí)現(xiàn),
頂層模塊Amp_Adjust通過(guò)實(shí)例化三個(gè)子模塊并將對(duì)應(yīng)的信號(hào)連接,最終實(shí)現(xiàn)旋轉(zhuǎn)調(diào)節(jié)系統(tǒng)的總體設(shè)計(jì)。
實(shí)驗(yàn)原理
旋轉(zhuǎn)編碼器介紹
旋轉(zhuǎn)編碼器(rotary encoder)也稱為軸編碼器,是將旋轉(zhuǎn)位置或旋轉(zhuǎn)量轉(zhuǎn)換成模擬或數(shù)字信號(hào)的機(jī)電設(shè)備。旋轉(zhuǎn)編碼器用在許多需要精確旋轉(zhuǎn)位置及速度的場(chǎng)合,如工業(yè)控制、機(jī)器人技術(shù)、專用鏡頭、電腦輸入設(shè)備(如鼠標(biāo)及軌跡球)等。 旋轉(zhuǎn)編碼器以碼盤刻孔方式不同分為:絕對(duì)式和增量式兩類。
STEP BaseBoard V3.0底板上集成的旋轉(zhuǎn)編碼器就是機(jī)械增量式的。
旋轉(zhuǎn)編碼器連接
STEP BaseBoard V3.0底板上旋轉(zhuǎn)編碼器的電路圖如下:
我們使用的旋轉(zhuǎn)編碼器為EC11系列的,支持按動(dòng)開關(guān),共有5個(gè)管腳,
旋轉(zhuǎn)編碼器驅(qū)動(dòng)設(shè)計(jì)
上圖是機(jī)械增量式旋轉(zhuǎn)編碼器的原理示意圖,中間圓形齒輪連接到旋轉(zhuǎn)編碼器的公共端4管腳,STEP BaseBoard V3.0底板上我們將之接地處理,A、B兩個(gè)觸點(diǎn)連接到旋轉(zhuǎn)編碼器的A、B相輸出端3、5管腳,當(dāng)進(jìn)行旋轉(zhuǎn)操作時(shí),A、B觸點(diǎn)會(huì)先后接觸和錯(cuò)開圓形齒輪,從而導(dǎo)致A、B相輸出信號(hào)產(chǎn)生相位不同的脈沖信號(hào):
根據(jù)時(shí)序圖可以看出旋轉(zhuǎn)編碼器順時(shí)針或逆時(shí)針旋轉(zhuǎn)時(shí),A相信號(hào)超前或滯后B相信號(hào),FPGA接收到旋轉(zhuǎn)編碼器的A、B信號(hào)時(shí),可以根據(jù)A、B的狀態(tài)組合判定編碼器的旋轉(zhuǎn)方向。 程序設(shè)計(jì)中我們可以對(duì)A、B信號(hào)檢測(cè),檢測(cè)A信號(hào)的邊沿及B信號(hào)的狀態(tài),
以上就是我們旋轉(zhuǎn)編碼器驅(qū)動(dòng)設(shè)計(jì)的總體思路,下面我們就通過(guò)編程來(lái)實(shí)現(xiàn)它。
前面電路連接部分我們使用了兩個(gè)電容對(duì)A、B信號(hào)作去抖處理,可以起到一定的效果,為了驅(qū)動(dòng)更加穩(wěn)定,我們?cè)诔绦蛑性俸?jiǎn)單處理一下,先對(duì)系統(tǒng)時(shí)鐘分頻得到2KHz的時(shí)鐘,然后在2KHz時(shí)鐘的節(jié)拍下對(duì)A、B信號(hào)采樣,三級(jí)鎖存消除亞穩(wěn)態(tài)
對(duì)A信號(hào)采樣程序?qū)崿F(xiàn)如下(對(duì)B信號(hào)一樣):
reg key_a_r,key_a_r1,key_a_r2;//消除亞穩(wěn)態(tài)always@(posedge clk_500us) begin
key_a_r <= key_a;
key_a_r1 <= key_a_r;
key_a_r2 <= key_a_r1;end
然后簡(jiǎn)單去抖處理程序?qū)崿F(xiàn)如下(對(duì)B信號(hào)一樣):
reg A_state;//簡(jiǎn)單去抖動(dòng)處理
always@(key_a_r1 or key_a_r2) begin
case({key_a_r1,key_a_r2})
2'b11: A_state <= 1'b1;
2'b00: A_state <= 1'b0;
default: A_state <= A_state;
endcaseend
檢測(cè)A信號(hào)的邊沿程序?qū)崿F(xiàn)如下:
reg A_state_r,A_state_r1;//對(duì)A_state信號(hào)進(jìn)行邊沿檢測(cè)
always@(posedge clk) begin
A_state_r <= A_state;
A_state_r1 <= A_state_r;
end
wire A_pos = (!A_state_r1) && A_state_r;
wire A_neg = A_state_r1 && (!A_state_r);
最后根據(jù)A信號(hào)邊沿與B信號(hào)的狀態(tài)組合判定旋轉(zhuǎn)的信息,
逆時(shí)針旋轉(zhuǎn)脈沖輸出程序?qū)崿F(xiàn)如下:
//當(dāng)A的上升沿伴隨B的高電平或當(dāng)A的下降沿伴隨B的低電平 為向左旋轉(zhuǎn)
always@(posedge clk or negedge rst_n) begin
if(!rst_n) L_pulse <= 1'b0;
else if((A_pos&&B_state)||(A_neg&&(!B_state))) L_pulse <= 1'b1;
else L_pulse <= 1'b0;
end //當(dāng)A的上升沿伴隨B的低電平或當(dāng)A的下降沿伴隨B的高電平 為向右旋轉(zhuǎn)
always@(posedge clk or negedge rst_n) begin
if(!rst_n) R_pulse <= 1'b0;
else if((A_pos&&(!B_state))||(A_neg&&B_state)) R_pulse <= 1'b1;
else R_pulse <= 1'b0;
end
所以通過(guò)上面程序最終實(shí)現(xiàn)了左旋右旋的脈沖輸出,脈沖的脈寬等于系統(tǒng)時(shí)鐘的周期。
系統(tǒng)總體實(shí)現(xiàn)
回顧旋轉(zhuǎn)調(diào)節(jié)系統(tǒng)設(shè)計(jì)框架,剛剛我們已經(jīng)學(xué)習(xí)完成了旋轉(zhuǎn)編碼器的驅(qū)動(dòng)設(shè)計(jì),在基礎(chǔ)數(shù)字電路實(shí)驗(yàn)部分我們已經(jīng)掌握了FPGA驅(qū)動(dòng)獨(dú)立顯示數(shù)碼管的原理及方法, 模塊通過(guò)一個(gè)4位的輸入傳遞要顯示的數(shù)值,通過(guò)9位的輸出控制數(shù)碼管顯示該數(shù)值,這里我們不再重復(fù),還需要設(shè)計(jì)一個(gè)模塊,通過(guò)旋轉(zhuǎn)編碼器模塊脈沖輸出控制變量在0~99范圍內(nèi)加減變化。
關(guān)于BCD碼在基礎(chǔ)數(shù)字電路實(shí)驗(yàn)部分已經(jīng)接觸過(guò),BCD碼(Binarycoded Decimal),是用4位二進(jìn)制碼的組合代表十進(jìn)制數(shù)的碼制方法,這樣顯示更符合人的閱讀習(xí)慣,所以BCD數(shù)值變化要求滿9進(jìn)1。
脈沖控制變量在0~99范圍變化,左旋減,右旋加,程序?qū)崿F(xiàn)如下
//key_pulse transfer to seg_dataalways@(posedge clk or negedge rst_n) begin
if(!rst_n) begin
seg_data <= 8'h50;
end else begin
if(L_pulse) begin
if(seg_data[3:0]==4'd0) begin
seg_data[3:0] <= 4'd9;
if(seg_data[7:4]==4'd0) seg_data[7:4] <= 4'd9;
else seg_data[7:4] <= seg_data[7:4] - 1'b1;
end else seg_data[3:0] <= seg_data[3:0] - 1'b1;
end else if(R_pulse) begin
if(seg_data[3:0]==4'd9) begin
seg_data[3:0] <= 4'd0;
if(seg_data[7:4]==4'd9) seg_data[7:4] <= 4'd0;
else seg_data[7:4] <= seg_data[7:4] + 1'b1;
end else seg_data[3:0] <= seg_data[3:0] + 1'b1;
end else begin
seg_data <= seg_data;
end
end
end
綜合后的設(shè)計(jì)框圖如下:
實(shí)驗(yàn)步驟
實(shí)驗(yàn)現(xiàn)象
將程序下載到實(shí)驗(yàn)平臺(tái),核心板數(shù)碼管顯示50,旋轉(zhuǎn)編碼器左旋(逆時(shí)針)數(shù)值減小,旋轉(zhuǎn)編碼器右旋(順時(shí)針)數(shù)值增加,旋轉(zhuǎn)編碼器旋轉(zhuǎn)時(shí)有頓挫感,每次頓挫數(shù)值變化1。
在基礎(chǔ)數(shù)字電路實(shí)驗(yàn)部分我們已經(jīng)掌握了FPGA驅(qū)動(dòng)獨(dú)立顯示數(shù)碼管的原理及方法,本實(shí)驗(yàn)主要學(xué)習(xí)旋轉(zhuǎn)編碼器的驅(qū)動(dòng)原理,最后完成旋轉(zhuǎn)調(diào)節(jié)系統(tǒng)總體設(shè)計(jì)。
本文引用地址:http://2s4d.com/article/202312/453766.htm根據(jù)前面的實(shí)驗(yàn)解析我們可以得知,該設(shè)計(jì)可以拆分成三個(gè)功能模塊實(shí)現(xiàn),
頂層模塊Amp_Adjust通過(guò)實(shí)例化三個(gè)子模塊并將對(duì)應(yīng)的信號(hào)連接,最終實(shí)現(xiàn)旋轉(zhuǎn)調(diào)節(jié)系統(tǒng)的總體設(shè)計(jì)。
旋轉(zhuǎn)編碼器(rotary encoder)也稱為軸編碼器,是將旋轉(zhuǎn)位置或旋轉(zhuǎn)量轉(zhuǎn)換成模擬或數(shù)字信號(hào)的機(jī)電設(shè)備。旋轉(zhuǎn)編碼器用在許多需要精確旋轉(zhuǎn)位置及速度的場(chǎng)合,如工業(yè)控制、機(jī)器人技術(shù)、專用鏡頭、電腦輸入設(shè)備(如鼠標(biāo)及軌跡球)等。 旋轉(zhuǎn)編碼器以碼盤刻孔方式不同分為:絕對(duì)式和增量式兩類。
STEP BaseBoard V3.0底板上集成的旋轉(zhuǎn)編碼器就是機(jī)械增量式的。
STEP BaseBoard V3.0底板上旋轉(zhuǎn)編碼器的電路圖如下:
我們使用的旋轉(zhuǎn)編碼器為EC11系列的,支持按動(dòng)開關(guān),共有5個(gè)管腳,
上圖是機(jī)械增量式旋轉(zhuǎn)編碼器的原理示意圖,中間圓形齒輪連接到旋轉(zhuǎn)編碼器的公共端4管腳,STEP BaseBoard V3.0底板上我們將之接地處理,A、B兩個(gè)觸點(diǎn)連接到旋轉(zhuǎn)編碼器的A、B相輸出端3、5管腳,當(dāng)進(jìn)行旋轉(zhuǎn)操作時(shí),A、B觸點(diǎn)會(huì)先后接觸和錯(cuò)開圓形齒輪,從而導(dǎo)致A、B相輸出信號(hào)產(chǎn)生相位不同的脈沖信號(hào):
根據(jù)時(shí)序圖可以看出旋轉(zhuǎn)編碼器順時(shí)針或逆時(shí)針旋轉(zhuǎn)時(shí),A相信號(hào)超前或滯后B相信號(hào),FPGA接收到旋轉(zhuǎn)編碼器的A、B信號(hào)時(shí),可以根據(jù)A、B的狀態(tài)組合判定編碼器的旋轉(zhuǎn)方向。 程序設(shè)計(jì)中我們可以對(duì)A、B信號(hào)檢測(cè),檢測(cè)A信號(hào)的邊沿及B信號(hào)的狀態(tài),
以上就是我們旋轉(zhuǎn)編碼器驅(qū)動(dòng)設(shè)計(jì)的總體思路,下面我們就通過(guò)編程來(lái)實(shí)現(xiàn)它。
前面電路連接部分我們使用了兩個(gè)電容對(duì)A、B信號(hào)作去抖處理,可以起到一定的效果,為了驅(qū)動(dòng)更加穩(wěn)定,我們?cè)诔绦蛑性俸?jiǎn)單處理一下,先對(duì)系統(tǒng)時(shí)鐘分頻得到2KHz的時(shí)鐘,然后在2KHz時(shí)鐘的節(jié)拍下對(duì)A、B信號(hào)采樣,三級(jí)鎖存消除亞穩(wěn)態(tài)
對(duì)A信號(hào)采樣程序?qū)崿F(xiàn)如下(對(duì)B信號(hào)一樣):
reg key_a_r,key_a_r1,key_a_r2;//消除亞穩(wěn)態(tài)always@(posedge clk_500us) begin key_a_r <= key_a; key_a_r1 <= key_a_r; key_a_r2 <= key_a_r1;end
然后簡(jiǎn)單去抖處理程序?qū)崿F(xiàn)如下(對(duì)B信號(hào)一樣):
reg A_state;//簡(jiǎn)單去抖動(dòng)處理 always@(key_a_r1 or key_a_r2) begin case({key_a_r1,key_a_r2}) 2'b11: A_state <= 1'b1; 2'b00: A_state <= 1'b0; default: A_state <= A_state; endcaseend
檢測(cè)A信號(hào)的邊沿程序?qū)崿F(xiàn)如下:
reg A_state_r,A_state_r1;//對(duì)A_state信號(hào)進(jìn)行邊沿檢測(cè) always@(posedge clk) begin A_state_r <= A_state; A_state_r1 <= A_state_r; end wire A_pos = (!A_state_r1) && A_state_r; wire A_neg = A_state_r1 && (!A_state_r);
最后根據(jù)A信號(hào)邊沿與B信號(hào)的狀態(tài)組合判定旋轉(zhuǎn)的信息,
逆時(shí)針旋轉(zhuǎn)脈沖輸出程序?qū)崿F(xiàn)如下:
//當(dāng)A的上升沿伴隨B的高電平或當(dāng)A的下降沿伴隨B的低電平 為向左旋轉(zhuǎn) always@(posedge clk or negedge rst_n) begin if(!rst_n) L_pulse <= 1'b0; else if((A_pos&&B_state)||(A_neg&&(!B_state))) L_pulse <= 1'b1; else L_pulse <= 1'b0; end //當(dāng)A的上升沿伴隨B的低電平或當(dāng)A的下降沿伴隨B的高電平 為向右旋轉(zhuǎn) always@(posedge clk or negedge rst_n) begin if(!rst_n) R_pulse <= 1'b0; else if((A_pos&&(!B_state))||(A_neg&&B_state)) R_pulse <= 1'b1; else R_pulse <= 1'b0; end
所以通過(guò)上面程序最終實(shí)現(xiàn)了左旋右旋的脈沖輸出,脈沖的脈寬等于系統(tǒng)時(shí)鐘的周期。
回顧旋轉(zhuǎn)調(diào)節(jié)系統(tǒng)設(shè)計(jì)框架,剛剛我們已經(jīng)學(xué)習(xí)完成了旋轉(zhuǎn)編碼器的驅(qū)動(dòng)設(shè)計(jì),在基礎(chǔ)數(shù)字電路實(shí)驗(yàn)部分我們已經(jīng)掌握了FPGA驅(qū)動(dòng)獨(dú)立顯示數(shù)碼管的原理及方法, 模塊通過(guò)一個(gè)4位的輸入傳遞要顯示的數(shù)值,通過(guò)9位的輸出控制數(shù)碼管顯示該數(shù)值,這里我們不再重復(fù),還需要設(shè)計(jì)一個(gè)模塊,通過(guò)旋轉(zhuǎn)編碼器模塊脈沖輸出控制變量在0~99范圍內(nèi)加減變化。
關(guān)于BCD碼在基礎(chǔ)數(shù)字電路實(shí)驗(yàn)部分已經(jīng)接觸過(guò),BCD碼(Binarycoded Decimal),是用4位二進(jìn)制碼的組合代表十進(jìn)制數(shù)的碼制方法,這樣顯示更符合人的閱讀習(xí)慣,所以BCD數(shù)值變化要求滿9進(jìn)1。
脈沖控制變量在0~99范圍變化,左旋減,右旋加,程序?qū)崿F(xiàn)如下
//key_pulse transfer to seg_dataalways@(posedge clk or negedge rst_n) begin if(!rst_n) begin seg_data <= 8'h50; end else begin if(L_pulse) begin if(seg_data[3:0]==4'd0) begin seg_data[3:0] <= 4'd9; if(seg_data[7:4]==4'd0) seg_data[7:4] <= 4'd9; else seg_data[7:4] <= seg_data[7:4] - 1'b1; end else seg_data[3:0] <= seg_data[3:0] - 1'b1; end else if(R_pulse) begin if(seg_data[3:0]==4'd9) begin seg_data[3:0] <= 4'd0; if(seg_data[7:4]==4'd9) seg_data[7:4] <= 4'd0; else seg_data[7:4] <= seg_data[7:4] + 1'b1; end else seg_data[3:0] <= seg_data[3:0] + 1'b1; end else begin seg_data <= seg_data; end end end
綜合后的設(shè)計(jì)框圖如下:
將程序下載到實(shí)驗(yàn)平臺(tái),核心板數(shù)碼管顯示50,旋轉(zhuǎn)編碼器左旋(逆時(shí)針)數(shù)值減小,旋轉(zhuǎn)編碼器右旋(順時(shí)針)數(shù)值增加,旋轉(zhuǎn)編碼器旋轉(zhuǎn)時(shí)有頓挫感,每次頓挫數(shù)值變化1。
評(píng)論