这个程序是用开发板按键来仿真鼠标。
至于USB的全过程请看下参考资料。
USB HID 应用笔记 ,讲得十分简练。
Windows自动识别并自动安装驱动。这一点相当于免驱:
而这里用HID ASF库包括以下几个函数:
bool udi_hid_mouse_btnleft(bool b_state)
bool udi_hid_mouse_btnmiddle(bool b_state)
bool udi_hid_mouse_btnright(bool b_state)
bool udi_hid_mouse_moveScroll(int8_t pos)
bool udi_hid_mouse_moveX(int8_t pos_x)
bool udi_hid_mouse_moveY(int8_t pos_y)
这些都在ui.c中用上了:
#include <asf.h>
#include "ui.h"
#define MOUSE_MOVE_RANGE 3
/* Wakeup pin is push button 2 (BP3, fast wakeup 10) */
#define WAKEUP_PMC_FSTT (PUSHBUTTON_2_WKUP_FSTT)
#define WAKEUP_PIN (GPIO_PUSH_BUTTON_2)
#define WAKEUP_PIO (PIN_PUSHBUTTON_2_PIO)
#define WAKEUP_PIO_ID (PIN_PUSHBUTTON_2_ID)
#define WAKEUP_PIO_MASK (PIN_PUSHBUTTON_2_MASK)
#define WAKEUP_PIO_ATTR \
(PIO_INPUT | PIO_PULLUP | PIO_DEBOUNCE | PIO_IT_LOW_LEVEL)
/* Interrupt on "pin change" from push button to do wakeup on USB
* Note:
* This interrupt is enable when the USB host enable remotewakeup feature
* This interrupt wakeup the CPU if this one is in idle mode
*/
static void ui_wakeup_handler(uint32_t id, uint32_t mask)
{
if (WAKEUP_PIO_ID == id && WAKEUP_PIO_MASK == mask) {
/* It is a wakeup then send wakeup USB */
udc_remotewakeup();
LED_On(LED0);
}
}
void ui_init(void)
{
/* Set handler for push button */
pio_handler_set(WAKEUP_PIO, WAKEUP_PIO_ID, WAKEUP_PIO_MASK,
WAKEUP_PIO_ATTR, ui_wakeup_handler);
/* Enable IRQ for button (PIOA) */
NVIC_EnableIRQ((IRQn_Type) WAKEUP_PIO_ID);
/* Initialize LEDs */
LED_Off(LED0);
LED_Off(LED1);
}
void ui_powerdown(void)
{
LED_Off(LED0);
LED_Off(LED1);
}
void ui_wakeup_enable(void)
{
/* Configure BP3 as PIO input */
pio_configure_pin(WAKEUP_PIN, WAKEUP_PIO_ATTR);
/* Enable interrupt for BP3 */
pio_enable_pin_interrupt(WAKEUP_PIN);
/* Enable fast wakeup for button pin (WKUP10 for PA20) */
pmc_set_fast_startup_input(WAKEUP_PMC_FSTT);
}
void ui_wakeup_disable(void)
{
/* Disable interrupt for button pin */
pio_disable_pin_interrupt(WAKEUP_PIN);
/* Disable fast wakeup for button pin (WKUP10 for BP3) */
pmc_clr_fast_startup_input(WAKEUP_PMC_FSTT);
}
void ui_wakeup(void)
{
LED_On(LED0);
}
void ui_process(uint16_t framenumber)
{
static uint8_t cpt_sof = 0;
static bool btn_left = false, btn_right = false;
bool btn_pressed;
if ((framenumber % 1000) == 0) {
LED_On(LED1);
}
if ((framenumber % 1000) == 500) {
LED_Off(LED1);
}
/* Scan process running each 2ms */
cpt_sof++;
if (cpt_sof < 2) {
return;
}
cpt_sof = 0;
/* Uses buttons to move mouse */
if (!ioport_get_pin_level(GPIO_PUSH_BUTTON_3)) {
udi_hid_mouse_moveY(-MOUSE_MOVE_RANGE);
}
if (!ioport_get_pin_level(GPIO_PUSH_BUTTON_4)) {
udi_hid_mouse_moveY( MOUSE_MOVE_RANGE);
}
/* Check button click */
btn_pressed = !ioport_get_pin_level(GPIO_PUSH_BUTTON_2);
if (btn_pressed != btn_left) {
btn_left = btn_pressed;
udi_hid_mouse_btnleft(btn_left);
}
btn_pressed = !ioport_get_pin_level(GPIO_PUSH_BUTTON_1);
if (btn_pressed != btn_right) {
btn_right = btn_pressed;
udi_hid_mouse_btnright(btn_right);
}
}
/**
* \defgroup UI User Interface
*
* Human interface on SAM4E-EK:
* - Led 0 (D2) is on when USB is wakeup
* - Led 1 (D3) blinks when USB host has checked and enabled HID Mouse interface
* - Push button 2 (BP3) and push button 1 (BP2) are linked to mouse button
* left and right
* - Push button 3 (BP4) and push button 4 (BP5) are used to move mouse up
* and down
* - Only a low level on push button 2 (BP3) will generate a wakeup to USB Host
* in remote wakeup mode.
*
*/
运行结果是:我的板子就四个键,其中一个键管上,按住后光标上移,其中一下向下。一个是左键,一个是右键,都很好用。
|