内容介绍
内容介绍
一、项目描述
1.项目介绍
基于nRF7002DK的蓝牙鼠标键盘复合设备
- 功能一:Button 1模拟鼠标点击
- 功能二:Button 2模拟键盘按键,按下时输入“eetree”字符
- 功能三:电脑开启大写锁定时,板卡的LED亮起
2.设计思路
本项目是基于nRF7002DK的蓝牙鼠标键盘复合设备,可以分别实现蓝牙鼠标和蓝牙键盘的对应功能,再将两种功能合在一起。
功能一是模拟鼠标,功能二和功能三是模拟键盘。进一步分析功能二是模拟的键盘向电脑发送信息,而功能三是电脑向模拟的键盘发送信息。由于单独的蓝牙鼠标和单独的蓝牙键盘在nordic官方demo中都有比较好的实现,可以进行借鉴学习;难点是如何将两种功能合在一起,也就是编写一个复合HID设备描述。所以这个复合HID设备描述中,要包含项目所需功能必要的通信信息。
3.简单的硬件介绍
本项目使用的是nRF7002DK板卡。这个板卡可以分为两个部分:一部分是板载jlink区,用于程序下载调试;另一部分是nordic芯片功能评估区,由nRF5340和nRF7002组成。本项目主要使用的nRF5340这款芯片。
二、软件流程图及主要代码片段
1.软件流程图
软件主要分两部分:
- 开发板硬件初始化
- 配置按键、LED
- 设置蓝牙回调函数
- 设置蓝牙混合设备信息
- 蓝牙初始化
- 进行蓝牙配对
- 蓝牙鼠标键盘混合设备功能实现
- 模拟鼠标
- 鼠标左键模拟
- 模拟键盘
- 键盘按键模拟
- CapsLock按键模拟
- 模拟鼠标
2.主要代码片段
- 设置按键和LED
#define CON_STATUS_LED DK_LED1 /*蓝牙混合设备连接状态灯*/
#define LED_CAPS_LOCK DK_LED2 /*CapsLock按键灯*/
#define KEY_SHIFT_MASK DK_BTN1_MSK /*按键1*/
#define KEY_TEXT_MASK DK_BTN2_MSK /*按键2*/
当个蓝牙设备连接成功时LED1亮起;LED1实现按键输入功能;当按下按键2时,实现CapsLock功能并亮起LED2
- 蓝牙配对按键设置
#define KEY_PAIRING_ACCEPT DK_BTN1_MSK /*确认蓝牙连接*/
#define KEY_PAIRING_REJECT DK_BTN2_MSK /*取消蓝牙连接*/
- Zephyr HID设备生成宏
BT_HIDS_DEF(hids_obj,
OUTPUT_REPORT_MAX_LEN,
INPUT_REPORT_KEYS_MAX_LEN,
INPUT_REP_BUTTONS_LEN);
Zephyr OS的生成宏,在编译前生成蓝牙HIDS设备的信息
- HID设备描述
static const uint8_t report_map[] = {
0x05, 0x01, /* Usage Page (Generic Desktop) */
0x09, 0x06, /* Usage (Keyboard) */
0xA1, 0x01, /* Collection (Application) */
/* Keys */
#if INPUT_REP_KEYS_REF_ID
0x85, INPUT_REP_KEYS_REF_ID,
#endif
0x05, 0x07, /* Usage Page (Key Codes) */
0x19, 0xe0, /* Usage Minimum (224) */
0x29, 0xe7, /* Usage Maximum (231) */
0x15, 0x00, /* Logical Minimum (0) */
0x25, 0x01, /* Logical Maximum (1) */
0x75, 0x01, /* Report Size (1) */
0x95, 0x08, /* Report Count (8) */
0x81, 0x02, /* Input (Data, Variable, Absolute) */
0x95, 0x01, /* Report Count (1) */
0x75, 0x08, /* Report Size (8) */
0x81, 0x01, /* Input (Constant) reserved byte(1) */
0x95, 0x06, /* Report Count (6) */
0x75, 0x08, /* Report Size (8) */
0x15, 0x00, /* Logical Minimum (0) */
0x25, 0x65, /* Logical Maximum (101) */
0x05, 0x07, /* Usage Page (Key codes) */
0x19, 0x00, /* Usage Minimum (0) */
0x29, 0x65, /* Usage Maximum (101) */
0x81, 0x00, /* Input (Data, Array) Key array(6 bytes) */
/* LED */
#if OUTPUT_REP_KEYS_REF_ID
0x85, OUTPUT_REP_KEYS_REF_ID,
#endif
0x95, 0x05, /* Report Count (5) */
0x75, 0x01, /* Report Size (1) */
0x05, 0x08, /* Usage Page (Page# for LEDs) */
0x19, 0x01, /* Usage Minimum (1) */
0x29, 0x05, /* Usage Maximum (5) */
0x91, 0x02, /* Output (Data, Variable, Absolute), */
/* Led report */
0x95, 0x01, /* Report Count (1) */
0x75, 0x03, /* Report Size (3) */
0x91, 0x01, /* Output (Data, Variable, Absolute), */
/* Led report padding */
0xC0, /* End Collection (Application) */
//mouse
0x05, 0x01, /* Usage Page (Generic Desktop) */
0x09, 0x02, /* Usage (Mouse) */
0xA1, 0x01, /* Collection (Application) */
/* Report ID 2: Mouse buttons + scroll/pan */
#if INPUT_REP_REF_BUTTONS_ID
0x85, INPUT_REP_REF_BUTTONS_ID, /* Report Id 2 */
#endif
0x09, 0x01, // USAGE (Pointer)
0xa1, 0x00, // COLLECTION (Physical)
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x01, // USAGE_MINIMUM (Button 1)
0x29, 0x03, // USAGE_MAXIMUM (Button 3)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x95, 0x03, // REPORT_COUNT (3)
0x75, 0x01, // REPORT_SIZE (1)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x05, // REPORT_SIZE (5)
0x81, 0x03, // INPUT (Cnst,Var,Abs)
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x30, // USAGE (X)
0x09, 0x31, // USAGE (Y)
0x15, 0x81, // LOGICAL_MINIMUM (-127)
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x02, // REPORT_COUNT (2)
0x81, 0x06, // INPUT (Data,Var,Rel)
0xc0, // END_COLLECTION
0xc0 // END_COLLECTION
};
蓝牙混合HID的设置信息,通过hid_init生成hids_obj结构体,以给Zephyr的BT_HITS_DEF必要的初始化信息
- 按键输入字符
static const uint8_t hello_world_str[] = {
0x08, /* Key e */
0x08, /* Key e */
0x17, /* Key t */
0x15, /* Key r */
0x08, /* Key e */
0x08, /* Key e */
0x28, /* Key Return */
};
当按下按键1时依次输入eetree
- 模拟鼠标左键功能
static int mouse_click_send(uint8_t click)
{
int err;
for (size_t i = 0; i < CONFIG_BT_HIDS_MAX_CLIENT_COUNT; i++) {
if (conn_mode[i].conn) {
int err;
err = mouse_report_con_send(click,
conn_mode[i].in_boot_mode,
conn_mode[i].conn);
if (err) {
printk("Key report send error: %d\n", err);
return err;
}
}
}
return 0;
}
当按下按键1时,模拟鼠标左键功能
- 键盘功能模拟
static void button_text_changed(bool down)
{
static const uint8_t *chr = hello_world_str;
if (down) {
hid_buttons_press(chr, 1);
} else {
hid_buttons_release(chr, 1);
if (++chr == (hello_world_str + sizeof(hello_world_str))) {
chr = hello_world_str;
}
}
}
当按下按键2时,依次输入eetree
- main函数主要功能
int main(void)
{
int err;
int blink_status = 0;
printk("Starting Bluetooth Peripheral MIX HIDS example\n");
configure_gpio();
err = bt_conn_auth_cb_register(&conn_auth_callbacks);
if (err) {
printk("Failed to register authorization callbacks.\n");
return 0;
}
err = bt_conn_auth_info_cb_register(&conn_auth_info_callbacks);
if (err) {
printk("Failed to register authorization info callbacks.\n");
return 0;
}
hid_init();
err = bt_enable(NULL);
if (err) {
printk("Bluetooth init failed (err %d)\n", err);
return 0;
}
printk("Bluetooth initialized\n");
if (IS_ENABLED(CONFIG_SETTINGS)) {
settings_load();
}
#if CONFIG_NFC_OOB_PAIRING
k_work_init(&adv_work, delayed_advertising_start);
app_nfc_init();
#else
advertising_start();
#endif
k_work_init(&pairing_work, pairing_process);
for (;;) {
if (is_adv) {
dk_set_led(ADV_STATUS_LED, (++blink_status) % 2);
} else {
dk_set_led_off(ADV_STATUS_LED);
}
k_sleep(K_MSEC(ADV_LED_BLINK_INTERVAL));
}
}
- configure_gpio函数配置按键和LED
- bt_conn_auth_cb_register函数和bt_conn_auth_info_cb_register函数设置蓝牙回调函数,即蓝牙键盘鼠标对应功能
- hid_init蓝牙设备初始化
-
k_work_init(&pairing_work, pairing_process),开始蓝牙配对
三、功能展示及说明
- 打开nRF7002DK板卡开关
- 电脑端开启蓝牙连接板卡,如板卡连接成功则LED 1亮起
- Button 1模拟鼠标左键
- Button 2模拟键盘按键,连续按键输入“eetree”字符
- 在电脑端按下CapsLock按键,板卡上LED 2亮起;再按CapsLock,LED 2灭。LED 2与CapsLock保持相同状态
四、对本活动的心得体会
- 本次活动使用了nordic的nRF5340蓝牙芯片,让我体会的这款蓝牙芯片的强大的功能。双核M33的配置可以在蓝牙应用中提供性能和安全的双重保障。当然双核开发也比之前的单核开发要复杂一些
- 学习了VSCode上ncs的开发也与之前使用KEIL进行开发有很大的不同
- 学习了Zephyr RTOS相关知识,利用Zephyr更好地实现实现nRF5340上的功能。由于时间有限,以后可以更加深入地学习这个非常强大的RTOS
- 项目最难的地方,我认为是设置环境,很多人卡在这里,如果能提供方便的开发环境,把更多的精力放在项目功能实现上就更好了
附件下载
peripheral_hids_mix.rar
团队介绍
个人
评论
0 / 100
查看更多