这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » 国产MCU » 学习AI8051开发板例程:26AI8051的HID实现键盘

共3条 1/1 1 跳转至

学习AI8051开发板例程:26AI8051的HID实现键盘

高工
2026-02-06 16:30:01   被打赏 50 分(兑奖)     打赏

一:HID协议

    USB HID设备主要基于两种协议:报告协议(report protocol)和引导协议(boot protocol)。报告是从设备发送到主机的数据结构,也可以从主机发送到设备。当设备向主机发送报告时,通常包含状态变化信息,例如按键,鼠标移动等。当主机向设备发送报告时,通常包含用于配置设备的命令(set_report请求),例如在键盘上设置LED。这个协议依赖于标准的USB框架。USBHID设备使用中断传输进行通信,因为设备并不是一直在传输数据,但当设备传输数据时,主机需要软件有快速的响应。中断传输时传输的数据量通常很小。报告通常有两种类型,具体取决于协议类型。

    HID报告协议基于“项目(item)”的概念,其数据结构在报告描述符中定义。引导协议要简单得多,并且遵循鼠标和键盘的标准结构。依据本次实验内容,此处将仅讨论引导协议。

二:USB键盘

USB 键盘使用报告与软件通信,就像其他 HID设备一样。通过接口描述符中的类字段(bInterfaceClass)3和协议字段(bInterfaceProtocol)来检测 USB键盘。

(1)报告格式

该报告必须由软件每隔固定时间使用一次中断传输请求,并且此间隔应在USB键盘的端点IN触发的中断中定义。USB键盘报告的大小可能高达8个字节,但这些字节不一定都被使用,如果只使用前三个或四个字节来实现正确的键码传输是可行的。此处描述键盘的完整报告机制。表15.75定义的报告数据结构仅适用于引导协议。

(2)按键机制

USB键盘在按下或释放键时发送中断。当用户按下一个键时,中断会在其中一个按键字段中带有一个扫描码值。当一个键被释放时,对应的按键字段在下一个数据包中返回零。为了更清楚地说明这一点并说明为什么有多个普通按键扫描码字段,让我们看以下示例。假设用户按下“A”键,即扫描码Ox04。返回的中断数据包为:

00 00 04 00 00 00 00 00 00

三:软件代码如下所示:

3.1 USB代码如下所示:

void usb_class_in()
{
    BYTE key[8];
    BYTE i;
    
    if (DeviceState != DEVSTATE_CONFIGURED)
        return;

    if (!UsbInBusy && fKeyOK)
    {
        fKeyOK = 0;

        key[0] = 0;
        key[1] = 0;
        key[2] = 0;
        key[3] = 0;
        key[4] = 0;
        key[5] = 0;
        key[6] = 0;
        key[7] = 0;

        switch (bKeyCode)
        {
        case 0xfe:  key[2] = 0x1e; break;
        case 0xfd:  key[2] = 0x1f; break;
        case 0xfb:  key[2] = 0x20; break;
        case 0xf7:  key[2] = 0x21; break;
        case 0xef:  key[2] = 0x22; break;
        case 0xdf:  key[2] = 0x23; break;
        case 0xbf:  key[2] = 0x24; break;
        case 0x7f:  key[2] = 0x25; break;
        }
        
        EUSB = 0;
        UsbInBusy = 1;
        usb_write_reg(INDEX, 1);
        for (i=0; i<8; i++)
        {
            usb_write_reg(FIFO1, key[i]);
        }
        usb_write_reg(INCSR1, INIPRDY);
        EUSB = 1;
    }
}

3.2 按键扫描函数

void scan_key()
{
    BYTE key;    
    P0M0 = 0x00;
    P0M1 = 0x00;   
    key = 0;
    P0 = 0xff;
    P06 = 0;
    _nop_();
    _nop_();
    key |= P0 & 0x0f;
    P06 = 1;
    P07 = 0;
    _nop_();
    _nop_();
    key |= (P0 & 0x0f) << 4;
    P07 = 1;   
    if (key != bKeyCode)
    {
        bKeyCode = key;
        bKeyDebounce = 20;
    }
    else
    {
        if (bKeyDebounce)
        {
            bKeyDebounce--;
            if (bKeyDebounce == 0)
            {
                fKeyOK = 1;
            }
        }
    }   
}

3.3 在主程序中进行扫描即可

    while (1)
    {
        usb_class_in();
        
        if (f1ms)
        {
            f1ms = 0;
            scan_key();
        }
    }

四:实验验证如下:

ai26-1.png

ai26-2.png





关键词: AI8051     键盘    

院士
2026-02-07 00:11:50     打赏
2楼

这个好厉害啊!

楼主能力真棒!继续,继续


院士
2026-02-11 15:22:10     打赏
3楼

谢谢分享,学习了。


共3条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]