【GD32F470紫藤派开发板使用手册】第十三讲 USB_虚拟键盘实验

发布者:theta18最新更新时间:2024-11-19 来源: elecfans关键字:USB  虚拟键盘 手机看文章 扫描二维码
随时随地手机看文章


/* configure USB capabilities */

(void)usb_basic_init (&udev->bp, &udev->regs, core);


usb_globalint_disable(&udev->regs);


/* initializes the USB core*/

(void)usb_core_init (udev->bp, &udev->regs);


/* set device disconnect */

usbd_disconnect (udev);


#ifndef USE_OTG_MODE

usb_curmode_set(&udev->regs, DEVICE_MODE);

#endif /* USE_OTG_MODE */


/* initializes device mode */

(void)usb_devcore_init (udev);


usb_globalint_enable(&udev->regs);


/* set device connect */

usbd_connect (udev);


udev->dev.cur_status = (uint8_t)USBD_DEFAULT;

}

配置USB中断函数如下。


C

void usb_intr_config(void)

{

nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);


#ifdef USE_USB_FS

nvic_irq_enable((uint8_t)USBFS_IRQn, 3U, 0U);


#if USBFS_LOW_POWER

/* enable the power module clock */

rcu_periph_clock_enable(RCU_PMU);


/* USB wakeup EXTI line configuration */

exti_interrupt_flag_clear(EXTI_18);

exti_init(EXTI_18, EXTI_INTERRUPT, EXTI_TRIG_RISING);

exti_interrupt_enable(EXTI_18);


nvic_irq_enable((uint8_t)USBFS_WKUP_IRQn, 0U, 0U);

#endif /* USBFS_LOW_POWER */

#elif defined(USE_USB_HS)

nvic_irq_enable((uint8_t)USBHS_IRQn, 3U, 0U);


#if USBHS_LOW_POWER

/* enable the power module clock */

rcu_periph_clock_enable(RCU_PMU);


/* USB wakeup EXTI line configuration */

exti_interrupt_flag_clear(EXTI_20);

exti_init(EXTI_20, EXTI_INTERRUPT, EXTI_TRIG_RISING);

exti_interrupt_enable(EXTI_20);


nvic_irq_enable((uint8_t)USBHS_WKUP_IRQn, 0U, 0U);

#endif /* USBHS_LOW_POWER */

#endif /* USE_USB_FS */


#ifdef USB_HS_DEDICATED_EP1_ENABLED

nvic_irq_enable(USBHS_EP1_Out_IRQn, 1, 0);

nvic_irq_enable(USBHS_EP1_In_IRQn, 1, 0);

#endif /* USB_HS_DEDICATED_EP1_ENABLED */

}

内部上拉电阻被上拉后,主机将会对设备进行枚举,设备端采用while (USBD_CONFIGURED != hid_keyboard.dev.cur_status) 语句进行等待。当USB设备状态变为USBD_CONFIGURED状态时,表明设备枚举完成。


枚举完成之后,程序将进入主循环中,在主循环中,循环调用HID USB模拟键盘数据处理函数,在该函数中,首先判断上次传输是否完成,完成之后通过扫描按键的方式查看按键是否被按下,若按键被按下,则通过hid_report_send()函数发送键盘报告数据。


C

static void hid_key_data_send(usb_dev *udev)

{

standard_hid_handler *hid = (standard_hid_handler *)udev->dev.class_data[USBD_HID_INTERFACE];


if (hid->prev_transfer_complete) {

switch (key_state()) {

case CHAR_A:

hid->data[2] = 0x04U;

break;

case CHAR_B:

hid->data[2] = 0x05U;

break;

default:

break;

}


if (0U != hid->data[2]) {

hid_report_send(udev, hid->data, HID_IN_PACKET);

}

}

}

报文发送函数定义如下,该函数包含三个参数,udev为初始化后的设备操作结构体;report为发送报告缓冲区地址;len为发送报告的长度。在该函数中,如果设备已经被枚举成功,则首先将prev_transfer_complete标志位设置为0,表明接下来将进行发送数据,数据并未发送完成,之后,调用usbd_ep_send()将需要发送的报告拷贝到USB外设缓冲区中并设置端点为有效状态,等待主机发送IN令牌包,USB设备将外设缓冲区中的数据发送给主机。


C

uint8_t hid_report_send (usb_dev *udev, uint8_t *report, uint32_t len)

{

standard_hid_handler *hid = (standard_hid_handler *)udev->dev.class_data[USBD_HID_INTERFACE];


hid->prev_transfer_complete = 0U;


usbd_ep_send(udev, HID_IN_EP, report, len);


return USBD_OK;

}

当数据发送完成,USB设备将调用hid_data_in()函数进行数据处理。该函数程序如下所示。在该函数中,首先判断hid->data[2]的数据是否为0x00,如果不为0x00表明上次发送的为按键按下的键值,还需发送按键松开的键值,如果为0x00表明上次按键按下和松开的键值均已发送完成,之后将prev_transfer_complete设置为1,表明上一次的按键数据传输完成,可进行下次按键数据传输。


C

static uint8_t hid_data_in (usb_dev *udev, uint8_t ep_num)

{

standard_hid_handler *hid = (standard_hid_handler *)udev->dev.class_data[USBD_HID_INTERFACE];


if (0U != hid->data[2]) {

hid->data[2] = 0x00U;


usbd_ep_send(udev, HID_IN_EP, hid->data, HID_IN_PACKET);

} else {

hid->prev_transfer_complete = 1U;

}


return USBD_OK;

}

在该例程中通过hid->prev_transfer_complete数据流程标志位进行数据发送控制,读者可使用该标志位用于对数据发送的控制,当该标志位为0的时候,表明数据已被填送到USB缓冲区,但还没有发送给主机,此时MCU不能继续调用发送函数向缓冲区中填数据,否则可能导致数据覆盖丢失,正确做法是等待该标志位置位,表明上一包数据已被主机读取,然后再继续发送后续数据。


13.5实验结果


将本例程烧录到紫藤派开发板中,通过Type C数据线连接开发板和PC,之后分别按下WKUP和USER按键,将会向PC发送A、B键值。

[1] [2]
关键字:USB  虚拟键盘 引用地址:【GD32F470紫藤派开发板使用手册】第十三讲 USB_虚拟键盘实验

上一篇:GD32F303固件库开发(8)----USART收发配置
下一篇:最后一页

小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved