打印
[MM32软件]

【灵动微电子MM32F5330测评】7.基于tinyusb的USBHID键盘测试

[复制链接]
176|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
从官网下载的LibSamples_MM32F5330中没有USB的驱动代码,MM32官方在论坛里发过MM32F5270的USB驱动视频教程,看视频才知道还有MindSDK。
先介绍一下MindSDK,MindSDK(mm32-mcu-sdk)是由灵动官方的软件团队开发和维护的基于灵动微控制器的软件开发平台。MindSDK包含灵动微控制器所必须的芯片头文件、启动程序、连接命令脚本等源码,以及灵动微控制器外设模块的驱动程序源码,以及大量便于用户使用的软件组件源码和开发工具。
地址https://mindsdk.mindmotion.com.cn/
第一次使用需要注册个账号,选择你使用的操作系统、IDE和开发板,然后点击BUILD PROJECT

生成成功后在Build Dashboard中就可以看到生成的工程了,点击打开

点击Download Board Package下载

下载下来的文件中包含了USB例程,打开tud_hid_keyboard这个例程

编译并烧录,用数据线连接开发板,这个程序会一直输出a

接下来改造一下这个程序,用开发板上的按键控制输出,按键1按下输出Hello World!,按键2按下输出MM32F5330,按键3按下复制,按键4按下粘贴,修改的过程中发现MindSDK生成的工程中的库和官网上下的还不一样,文件名一样里面的类型定义却不完全一样,希望官方后面能统一一下

原来的按键处理方法要改成这样

enum
{
    LED_NO_1 = 0,
    LED_NO_2,
    LED_NO_3,
    LED_NO_4,
    LED_NUM,
};

enum
{
    KEY_NO_1 = 0,
    KEY_NO_2,
    KEY_NO_3,
    KEY_NO_4,
    KEY_NUM,
};

GPIO_Type *led_ports[] = {GPIOB,GPIOB,GPIOC,GPIOC};
uint16_t led_pins[] = {GPIO_PIN_11,GPIO_PIN_10,GPIO_PIN_7,GPIO_PIN_6};

GPIO_Type *key_ports[] = {GPIOC,GPIOC,GPIOB,GPIOB};
uint16_t key_pins[] = {GPIO_PIN_4,GPIO_PIN_5,GPIO_PIN_1,GPIO_PIN_2};
const uint8_t key_press_states[] = {1,0,0,0};
uint8_t key_press_counts[KEY_NUM];
uint8_t key_pressed = 0xFF;
char *key_msg1 = "Hello World!\n";
char *key_msg2 = "MM32F5330\n";
uint8_t key_send_index = 0;
const uint8_t conv_table[128][2] =  { HID_ASCII_TO_KEYCODE };

void APP_LedInit(void)
{
    uint8_t i = 0;
    GPIO_Init_Type cfg;
    RCC_EnableAHB1Periphs(RCC_AHB1_PERIPH_GPIOB, true);
    RCC_EnableAHB1Periphs(RCC_AHB1_PERIPH_GPIOC, true);
    cfg.PinMode = GPIO_PinMode_Out_PushPull;
    cfg.Speed = GPIO_Speed_50MHz;
    while(i < LED_NUM)
    {
        cfg.Pins = led_pins[i];
        GPIO_Init(led_ports[i],&cfg);
        GPIO_SetBits(led_ports[i],led_pins[i]);
        i += 1;
    }
}

void APP_LedOnOff(uint8_t led,uint8_t on)
{
    if(on)
        GPIO_ClearBits(led_ports[led], led_pins[led]);
    else
        GPIO_SetBits(led_ports[led], led_pins[led]);
}

void APP_KeysInit(void)
{
    GPIO_Init_Type cfg;
    RCC_EnableAHB1Periphs(RCC_AHB1_PERIPH_GPIOB, true);
    RCC_EnableAHB1Periphs(RCC_AHB1_PERIPH_GPIOC, true);

    cfg.PinMode = GPIO_PinMode_In_PullUp;
    cfg.Pins = GPIO_PIN_5;
    GPIO_Init(GPIOC,&cfg);
    cfg.Pins = GPIO_PIN_1|GPIO_PIN_2;
    GPIO_Init(GPIOB,&cfg);
   
    cfg.PinMode = GPIO_PinMode_In_Floating;
    cfg.Pins = GPIO_PIN_4;
    GPIO_Init(GPIOC,&cfg);
    memset(key_press_counts,0,KEY_NUM);
}

void APP_KeyStateCheck(void)
{
    uint8_t i = 0;
    while(i < KEY_NUM)
    {
        if(GPIO_ReadInDataBit(key_ports[i], key_pins[i]) == key_press_states[i])
        {
            if(key_press_counts[i] < 0xFF)
                key_press_counts[i] += 1;
        }
        else
            key_press_counts[i] = 0;
        if(key_press_counts[i] == 20)
        {
            APP_LedOnOff(i,1);
            key_send_index = 0;
            key_pressed = i;
        }
        i += 1;
    }
}

来了解一下键盘HID消息格式


实现发送方法
void APP_SendKeyMsg(void)
{
    uint8_t keycode[6] = { 0 };
    if ( !tud_hid_ready() )
        return;
    if(tud_suspended())
        tud_remote_wakeup();
    switch(key_pressed)
    {
        case KEY_NO_1:
            if(key_send_index/2 < strlen(key_msg1))
            {
                if(key_send_index%2 == 0)
                {
                    keycode[0] = conv_table[key_msg1[key_send_index/2]][1];
                    tud_hid_keyboard_report(REPORT_ID_KEYBOARD, conv_table[key_msg1[key_send_index/2]][0]?KEYBOARD_MODIFIER_LEFTSHIFT:0, keycode);
                }
                else
                    tud_hid_keyboard_report(REPORT_ID_KEYBOARD, 0, NULL);
                key_send_index += 1;
            }
            else
                key_pressed = 0xFF;
            break;
        case KEY_NO_2:
            if(key_send_index/2 < strlen(key_msg2))
            {
                if(key_send_index%2 == 0)
                {
                    keycode[0] = conv_table[key_msg2[key_send_index/2]][1];
                    tud_hid_keyboard_report(REPORT_ID_KEYBOARD, conv_table[key_msg2[key_send_index/2]][0]?KEYBOARD_MODIFIER_LEFTSHIFT:0, keycode);
                }
                else
                    tud_hid_keyboard_report(REPORT_ID_KEYBOARD, 0, NULL);
                key_send_index += 1;
            }
            else
                key_pressed = 0xFF;
            break;
        case KEY_NO_3:
            keycode[0] = HID_KEY_C;
            tud_hid_keyboard_report(REPORT_ID_KEYBOARD, KEYBOARD_MODIFIER_LEFTCTRL, keycode);
            key_pressed = 0xFF;
            break;
        case KEY_NO_4:
            keycode[0] = HID_KEY_V;
            tud_hid_keyboard_report(REPORT_ID_KEYBOARD, KEYBOARD_MODIFIER_LEFTCTRL, keycode);
            key_pressed = 0xFF;
            break;
        default:
            tud_hid_keyboard_report(REPORT_ID_KEYBOARD, 0, NULL);
            APP_LedOnOff(LED_NO_1,0);
            APP_LedOnOff(LED_NO_2,0);
            APP_LedOnOff(LED_NO_3,0);
            APP_LedOnOff(LED_NO_4,0);
            break;
    }
}

void APP_MyTask(void)
{
    APP_KeyStateCheck();
    APP_SendKeyMsg();
}

运行效果


使用特权

评论回复
沙发
elephant00| | 2024-7-4 14:42 | 只看该作者
感谢大神的分享

使用特权

评论回复
板凳
chenjun89| | 2024-7-4 19:24 | 只看该作者
可以做个小键盘,实现组合按键的功能。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

127

主题

622

帖子

5

粉丝