14. rotary-encoder - GPIO 連線裝置的通用驅動程式¶
- 作者:
Daniel Mack <daniel@caiaq.de>, 2009 年 2 月
14.1. 功能¶
旋轉編碼器是使用兩根線連線到 CPU 或其他外圍裝置的裝置。 輸出相移 90 度,透過觸發下降沿和上升沿,可以確定旋轉方向。
一些編碼器在穩定狀態下兩個輸出都為低電平,另一些編碼器也具有兩個輸出都為高電平的穩定狀態(半週期模式),而另一些編碼器在所有步進中都具有穩定狀態(四分之一週期模式)。
這兩個輸出的相點陣圖如下所示
_____ _____ _____
| | | | | |
Channel A ____| |_____| |_____| |____
: : : : : : : : : : : :
__ _____ _____ _____
| | | | | | |
Channel B |_____| |_____| |_____| |__
: : : : : : : : : : : :
Event a b c d a b c d a b c d
|<-------->|
one step
|<-->|
one step (half-period mode)
|<>|
one step (quarter-period mode)
14.2. 事件/狀態機¶
在半週期模式下,使用上述狀態 a) 和 c) 根據最後一個穩定狀態確定旋轉方向。 如果新的穩定狀態與上一個狀態不同(即旋轉沒有中途反轉),則在狀態 b) 和 d) 中報告事件。
否則,以下適用
- 通道 A 上的上升沿,通道 B 處於低電平狀態
此狀態用於識別順時針旋轉
- 通道 B 上的上升沿,通道 A 處於高電平狀態
當進入此狀態時,編碼器進入“準備就緒”狀態,這意味著它已經看到了一步過渡的一半。
- 通道 A 上的下降沿,通道 B 處於高電平狀態
此狀態用於識別逆時針旋轉
- 通道 B 上的下降沿,通道 A 處於低電平狀態
停車位置。 如果編碼器進入此狀態,則應該發生完全過渡,除非它在中途翻轉回來。“準備就緒”狀態告訴我們這一點。
14.3. 平臺要求¶
由於此驅動程式中沒有硬體相關的呼叫,因此與其一起使用的平臺必須支援 gpiolib。 另一個要求是 IRQ 必須能夠在兩個邊沿上觸發。
14.4. 板級整合¶
要在您的系統中使用此驅動程式,請註冊一個名稱為“rotary-encoder”的 platform_device,並將 IRQ 和一些特定的平臺數據與其關聯。 由於驅動程式使用通用裝置屬性,因此可以透過裝置樹、ACPI 或使用靜態板檔案來完成,如下例所示
/* board support file example */
#include <linux/input.h>
#include <linux/gpio/machine.h>
#include <linux/property.h>
#define GPIO_ROTARY_A 1
#define GPIO_ROTARY_B 2
static struct gpiod_lookup_table rotary_encoder_gpios = {
.dev_id = "rotary-encoder.0",
.table = {
GPIO_LOOKUP_IDX("gpio-0",
GPIO_ROTARY_A, NULL, 0, GPIO_ACTIVE_LOW),
GPIO_LOOKUP_IDX("gpio-0",
GPIO_ROTARY_B, NULL, 1, GPIO_ACTIVE_HIGH),
{ },
},
};
static const struct property_entry rotary_encoder_properties[] = {
PROPERTY_ENTRY_U32("rotary-encoder,steps-per-period", 24),
PROPERTY_ENTRY_U32("linux,axis", ABS_X),
PROPERTY_ENTRY_U32("rotary-encoder,relative_axis", 0),
{ },
};
static const struct software_node rotary_encoder_node = {
.properties = rotary_encoder_properties,
};
static struct platform_device rotary_encoder_device = {
.name = "rotary-encoder",
.id = 0,
};
...
gpiod_add_lookup_table(&rotary_encoder_gpios);
device_add_software_node(&rotary_encoder_device.dev, &rotary_encoder_node);
platform_device_register(&rotary_encoder_device);
...
請查閱裝置樹繫結文件以檢視驅動程式支援的所有屬性。