有時,基于微控制器的產品需要使用旋轉開關。由于很多微控制器都內置了ADC,在找不到旋轉開關或旋轉開關價格過高時,可以使用低成本電位計來替代旋轉開關(圖1)。 盡管僅需執行少量指令即可將電位計設定值數字化,使其表現得像開關一樣,但一個急需解決的問題是,在電氣噪聲或機械噪聲的影響下,在某一個值和下一個值之間的切換閾值處,數值會不穩定。該問題的解決方法是為每次轉換引入上、下兩個遲滯閾值,這樣一來,電位計就需要在另一個開關狀態有效前越過閾值。針對每次更新的開關狀態,都會有新的一對閾值替換之前的閾值。如此,遲滯效應可以實現各狀態間的完全切換。 圖1:替代多擲開關。 這一方法具有下述諸多優勢:單端口引腳對旋轉開關的多端口引腳、成本低、更易獲得且可實現去抖動切換。該方法的不足之處在于會失去制動感。設定點的另一特性是其可設置在任一位置,例如用以補償電位計在響應過程中出現的非線性變化。 遲滯通常稍高于會導致不期望切換的任何噪聲。建議在電位計觸點與地之間設置一個電容器,以濾除觸點噪聲(圖1)。 圖2列出了算法。一旦用ADC對電位計設定值進行了數字化操作,該數值就將與下閾值比較,若低于下閾值,開關狀態會逐漸降低并限制至零。若電位計設定值高于上閾值,開關狀態會逐漸增大并限制至最大值。若開關狀態發生變化,則上、下閾值會進行更新,并終止子程序。 圖2:流程圖。 為確保該遲滯算法起作用,必須定期讀取電位計設定值,并與上一次開關狀態進行比較。這樣做旨在將從不同狀態跨過閾值或處于相同值的電位計設定值與相同狀態區分開。 此處還需要計算出采樣率的最小值,可由電位計旋轉率最大值除以開關狀態數得到。例如,假設單匝電位計旋鈕在0.25s內完整旋轉一圈,同時假定有七種狀態,那么最低掃描率為28Hz。若電位計數值采樣周期低于最小值,即使切換方向正確,計算得出的開關狀態也可能不正確。倘若未以較快的速率持續改變電位計設定值,則隨后的采樣會對切換狀態進行校正。 以七種開關狀態為例創建一個閾值列表。假設有一個8位ADC。首先,ADC的256步范圍被分割為七種開關狀態。各開關狀態的寬度為ADC范圍除以狀態數,即:256/7=36.6。對其四舍五入,將各狀態的寬度定為36,但是兩個外端狀態需增加至38,以使總寬度為256。 下一步是確定各開關狀態的邊界。對于狀態0,邊界為0~37(包含兩端)。狀態1從38開始到73結束,其余開關狀態依此類推。根據增加或降低至邊界的遲滯數值確定閾值。此處使用“4”這一遲滯值。遲滯量既不得大于寬度,也不得低于預期的噪聲。因此,上邊界加4即可得出上閾值,下邊界減4即可得出下閾值,如表1所示。從該例可發現,從狀態2切換為狀態1需要使電位計數值下降至比切換點數值74小4,因此下閾值為70。相反,從狀態1切換為狀態2需要使電位計數值上升至比切換點數值73高4,因此上限閾值為77。用于程序代碼的表格僅需標明上、下閾值,在此例中僅需14個字節。 表1,閾值。 代碼示例(見下)支持Silicon Labs的C8051F310(8051架構),但也可以很容易地改編用于其他微控制器。 ![]() MOV UPRVAL, #00H ;set upper value to opposite end to force the code to run MOV LWRVAL, #0FFH ;set lower value to opposite end to force the code to run MOV SWPOS, #03H ;initialize switch position to middle MOV POSMAX, #06H ;set maximum switch position value ;SUBROUTINES POT2SW: ;CALCULATE SWITCH POSITION VALUE FROM POTENTIOMETER VALUE IN ACC ;check if pot setting is below lower threshold CLR C MOV B, A ;save pot setting to register B SUBB A, LWRVAL ;potval - lwrval JNC P2S1 ;no carry means potval >= lwrval DEC SWPOS ;carry means potval uprval, so increment switch position value ;check if switch position is > max MOV A, POSMAX ;load maximum xwitch position value CLR C SUBB A, SWPOS JNC P2S2 MOV SWPOS, POSMAX ;reset curve number to max curve value since overflow P2S2: ;read lower and upper thresholds using switch position value MOV A, SWPOS ;multiply switch position value by 2 MOV B, #02H MUL AB MOV B, A ;save multiplied value as table offset MOV DPTR, #HYSTBL ;load base address of table pointer MOVC A, @A+DPTR ;look up table value from base address + offset MOV LWRVAL, A ;read lower threshold value MOV A, B INC DPTR ;increment base address MOVC A, @A+DPTR MOV UPRVAL, A ;read upper threshold value RET HYSTBL: ;TABLE OF LOWER & UPPER THRESHOLDS FOR SEVEN POSITION SWITCH DB 00D, 41D ;Switch state 0 DB 34D, 77D ;Switch state 1 DB 70D, 113D ;Switch state 2 DB 106D, 149D ;Switch state 3 DB 142D, 185D ;Switch state 4 DB 178D, 221D ;Switch state 5 DB 214D, 255D ;Switch state 6 |