其實再次之前我們已經體驗過基于STM32H533和手勢傳感器實現的特殊功能小鍵盤了,在綜合比較按鍵和手勢發現各有利弊,手勢的新奇操作方式讓我們擺脫枯燥的按鍵模式,有利于手的保護,不過按鍵的可靠性確實比手勢的識別準確率更高,避免一些誤操作,所以我們本次通過這次活動,選用大家都比較滿意的按鍵——機械按鍵實現本次的小鍵盤。
本次活動是2024得捷活動系列之一,感謝電源網組織的本次活動以及得捷的贊助,我們通過得捷快捷的購物渠道,快速活動我們感興趣的開發板,體驗前言技術。
回歸到本次的DIY,我們已經確定了使用NUCLEO-H533RB作為本次的主控,而機械按鍵另外采購,我們通過不斷的對比選擇了一款凱華的機械按鍵作為這次DIY的輸入:
接下來就要考慮怎么安裝和固定了,由于我們使用的是開發板,好處就是大多數的引腳都是引出來的,我們只要做一個按鍵模塊就可以,看一下接口分布:
注意要避開一些關鍵引腳,比如板載的LED和按鍵(PA5與PC13),這里我們選取了一些集中的引腳,供電部分有CN6提供,引腳主要集中在CN10,通過分配繪制,我們制作了以下的4按鍵模塊:
接下來就是軟件功能的實現,按鍵功能的實現主要依托于USB功能,我們在H5的固件庫中發現有關USB的例程只有一個Ux_Device_CDC_ACM的例程,這是一個虛擬串口的例子,當然我們用的不是虛擬串口,我們將依托這個例程進行修改,我們先以這個例子為基礎修改例程初始化代碼,打開MX工程,修改USB基本配置:
修改具體參數:
到這里USB的內容就改完了,由于本次使用的是USBx協議棧,對應需要Threadx的配置,其實已經開啟了。
接下來就是按鍵和狀態燈代碼初始化,這一部分比較簡單,都是簡單的引腳配置,LED是輸出控制,按鍵是外部中斷模式如下:
實時操作系統中循環,我們通過初始化階段如下模式添加任務分支:
if (tx_byte_allocate(byte_pool, (VOID**) &pointer,
TX_APP_STACK_SIZE, TX_NO_WAIT) != TX_SUCCESS)
{
return TX_POOL_ERROR;
}
/* Create tx app thread. */
if (tx_thread_create(&tx_app_thread, "tx app thread", tx_app_thread_entry, 0, pointer,
TX_APP_STACK_SIZE, TX_APP_THREAD_PRIO, TX_APP_THREAD_PREEMPTION_THRESHOLD,
TX_APP_THREAD_TIME_SLICE, TX_APP_THREAD_AUTO_START) != TX_SUCCESS)
{
return TX_THREAD_ERROR;
}
接下我們看一下代碼發送的的程序,鍵盤碼值實際上是一個8個字節的數據:
uint8_t keyboard[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
void GetKeyboardData(UX_SLAVE_CLASS_HID_EVENT *hid_event,uint8_t key)
{
uint32_t i;
keyboard[2] = key;
hid_event->ux_device_class_hid_event_length = 8;
for(i=0;i<8;i++)
{
hid_event->ux_device_class_hid_event_buffer[i] = keyboard[i];
}
}
void GetKeyByte1Data(UX_SLAVE_CLASS_HID_EVENT *hid_event,uint8_t Byte1)
{
uint32_t i;
keyboard[0] = Byte1;
hid_event->ux_device_class_hid_event_length = 8;
for(i=0;i<8;i++)
{
hid_event->ux_device_class_hid_event_buffer[i] = keyboard[i];
}
}
void ClearKeyboardData(UX_SLAVE_CLASS_HID_EVENT *hid_event)
{
uint32_t i;
hid_event->ux_device_class_hid_event_length = 8;
for(i=0;i<8;i++)
{
keyboard[i] = 0;
hid_event->ux_device_class_hid_event_buffer[i] = 0;
}
}
接下來就是USB發送進程的處理了:
VOID usbx_hid_thread_entry(ULONG thread_input)
{
UX_SLAVE_DEVICE *device;
UX_SLAVE_CLASS_HID_EVENT hid_event;
TX_PARAMETER_NOT_USED(thread_input);
device = &_ux_system_slave->ux_system_slave_device;
while(1)
{
if(device->ux_slave_device_state == UX_DEVICE_CONFIGURED && hid_keyboard != UX_NULL)
{
tx_thread_sleep(MS_TO_TICK(10));
if(SW3_Flag == 1)
{
SW3_Flag = 0;
if(Key_Mode == 0)
{
GetKeyboardData(&hid_event,0x4B);
ux_device_class_hid_event_set(hid_keyboard, &hid_event);
HAL_Delay(20);
ClearKeyboardData(&hid_event);
ux_device_class_hid_event_set(hid_keyboard, &hid_event);
LED3_Off;
}
else
{
GetKeyByte1Data(&hid_event,Byte1_Left_Ctrl);
ux_device_class_hid_event_set(hid_keyboard, &hid_event);
HAL_Delay(20);
GetKeyboardData(&hid_event,0x06);
ux_device_class_hid_event_set(hid_keyboard, &hid_event);
HAL_Delay(20);
ClearKeyboardData(&hid_event);
ux_device_class_hid_event_set(hid_keyboard, &hid_event);
LED3_Off;
}
}
if(SW4_Flag == 1)
{
SW4_Flag = 0;
if(Key_Mode == 0)
{
GetKeyboardData(&hid_event,0x4E);
ux_device_class_hid_event_set(hid_keyboard, &hid_event);
HAL_Delay(20);
ClearKeyboardData(&hid_event);
ux_device_class_hid_event_set(hid_keyboard, &hid_event);
LED3_Off;
}
else
{
GetKeyByte1Data(&hid_event,Byte1_Left_Ctrl);
ux_device_class_hid_event_set(hid_keyboard, &hid_event);
HAL_Delay(20);
GetKeyboardData(&hid_event,0x19);
ux_device_class_hid_event_set(hid_keyboard, &hid_event);
ClearKeyboardData(&hid_event);
ux_device_class_hid_event_set(hid_keyboard, &hid_event);
LED3_Off;
}
}
if(SW2_Flag == 1)
{
SW2_Flag = 0;
if(Key_Mode == 0)
{
GetKeyboardData(&hid_event,0x28);
ux_device_class_hid_event_set(hid_keyboard, &hid_event);
HAL_Delay(20);
ClearKeyboardData(&hid_event);
ux_device_class_hid_event_set(hid_keyboard, &hid_event);
LED3_Off;
}
else
{
if(enter_state == 0)
{
enter_state = 1;
GetKeyboardData(&hid_event,0x28);
ux_device_class_hid_event_set(hid_keyboard, &hid_event);
HAL_Delay(20);
LED3_On;
}
else
{
enter_state = 0;
ClearKeyboardData(&hid_event);
ux_device_class_hid_event_set(hid_keyboard, &hid_event);
LED3_Off;
}
}
}
}
}
}
咱們看一下效果模式一下的K2-K4的按鍵模擬狀態:
模式二下的K2-K4的按鍵模擬狀態:
組合成的實物如下: