﻿<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="https://www.yfrobot.com.cn/wiki/skins/common/feed.css?303"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh">
		<id>https://www.yfrobot.com.cn/wiki/index.php?action=history&amp;feed=atom&amp;title=Cores%3AHID.cpp</id>
		<title>Cores:HID.cpp - 版本历史</title>
		<link rel="self" type="application/atom+xml" href="https://www.yfrobot.com.cn/wiki/index.php?action=history&amp;feed=atom&amp;title=Cores%3AHID.cpp"/>
		<link rel="alternate" type="text/html" href="https://www.yfrobot.com.cn/wiki/index.php?title=Cores:HID.cpp&amp;action=history"/>
		<updated>2026-04-04T16:34:47Z</updated>
		<subtitle>本wiki的该页面的版本历史</subtitle>
		<generator>MediaWiki 1.22.6</generator>

	<entry>
		<id>https://www.yfrobot.com.cn/wiki/index.php?title=Cores:HID.cpp&amp;diff=317&amp;oldid=prev</id>
		<title>Admin：以“&lt;font color=&quot;quartz&quot; size =&quot;+2&quot;&gt; '''HID.cpp ''' &lt;/font&gt;  &lt;pre style=&quot;color:royalblue&quot;&gt;   /* Copyright (c) 2011, Peter Barrett   **   ** Permission to use, copy, modi...”为内容创建页面</title>
		<link rel="alternate" type="text/html" href="https://www.yfrobot.com.cn/wiki/index.php?title=Cores:HID.cpp&amp;diff=317&amp;oldid=prev"/>
				<updated>2015-07-10T11:29:58Z</updated>
		
		<summary type="html">&lt;p&gt;以“&amp;lt;font color=&amp;quot;quartz&amp;quot; size =&amp;quot;+2&amp;quot;&amp;gt; &amp;#039;&amp;#039;&amp;#039;HID.cpp &amp;#039;&amp;#039;&amp;#039; &amp;lt;/font&amp;gt;  &amp;lt;pre style=&amp;quot;color:royalblue&amp;quot;&amp;gt;   /* Copyright (c) 2011, Peter Barrett   **   ** Permission to use, copy, modi...”为内容创建页面&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;font color=&amp;quot;quartz&amp;quot; size =&amp;quot;+2&amp;quot;&amp;gt; '''HID.cpp ''' &amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre style=&amp;quot;color:royalblue&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Copyright (c) 2011, Peter Barrett  &lt;br /&gt;
**  &lt;br /&gt;
** Permission to use, copy, modify, and/or distribute this software for  &lt;br /&gt;
** any purpose with or without fee is hereby granted, provided that the  &lt;br /&gt;
** above copyright notice and this permission notice appear in all copies.  &lt;br /&gt;
** &lt;br /&gt;
** THE SOFTWARE IS PROVIDED &amp;quot;AS IS&amp;quot; AND THE AUTHOR DISCLAIMS ALL  &lt;br /&gt;
** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED  &lt;br /&gt;
** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR  &lt;br /&gt;
** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES  &lt;br /&gt;
** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,  &lt;br /&gt;
** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,  &lt;br /&gt;
** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS  &lt;br /&gt;
** SOFTWARE.  &lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;USBAPI.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#if defined(USBCON)&lt;br /&gt;
#ifdef HID_ENABLED&lt;br /&gt;
&lt;br /&gt;
//#define RAWHID_ENABLED&lt;br /&gt;
&lt;br /&gt;
//	Singletons for mouse and keyboard&lt;br /&gt;
&lt;br /&gt;
Mouse_ Mouse;&lt;br /&gt;
Keyboard_ Keyboard;&lt;br /&gt;
&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
&lt;br /&gt;
//	HID report descriptor&lt;br /&gt;
&lt;br /&gt;
#define LSB(_x) ((_x) &amp;amp; 0xFF)&lt;br /&gt;
#define MSB(_x) ((_x) &amp;gt;&amp;gt; 8)&lt;br /&gt;
&lt;br /&gt;
#define RAWHID_USAGE_PAGE	0xFFC0&lt;br /&gt;
#define RAWHID_USAGE		0x0C00&lt;br /&gt;
#define RAWHID_TX_SIZE 64&lt;br /&gt;
#define RAWHID_RX_SIZE 64&lt;br /&gt;
&lt;br /&gt;
extern const u8 _hidReportDescriptor[] PROGMEM;&lt;br /&gt;
const u8 _hidReportDescriptor[] = {&lt;br /&gt;
	&lt;br /&gt;
	//	Mouse&lt;br /&gt;
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)	// 54&lt;br /&gt;
    0x09, 0x02,                    // USAGE (Mouse)&lt;br /&gt;
    0xa1, 0x01,                    // COLLECTION (Application)&lt;br /&gt;
    0x09, 0x01,                    //   USAGE (Pointer)&lt;br /&gt;
    0xa1, 0x00,                    //   COLLECTION (Physical)&lt;br /&gt;
    0x85, 0x01,                    //     REPORT_ID (1)&lt;br /&gt;
    0x05, 0x09,                    //     USAGE_PAGE (Button)&lt;br /&gt;
    0x19, 0x01,                    //     USAGE_MINIMUM (Button 1)&lt;br /&gt;
    0x29, 0x03,                    //     USAGE_MAXIMUM (Button 3)&lt;br /&gt;
    0x15, 0x00,                    //     LOGICAL_MINIMUM (0)&lt;br /&gt;
    0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)&lt;br /&gt;
    0x95, 0x03,                    //     REPORT_COUNT (3)&lt;br /&gt;
    0x75, 0x01,                    //     REPORT_SIZE (1)&lt;br /&gt;
    0x81, 0x02,                    //     INPUT (Data,Var,Abs)&lt;br /&gt;
    0x95, 0x01,                    //     REPORT_COUNT (1)&lt;br /&gt;
    0x75, 0x05,                    //     REPORT_SIZE (5)&lt;br /&gt;
    0x81, 0x03,                    //     INPUT (Cnst,Var,Abs)&lt;br /&gt;
    0x05, 0x01,                    //     USAGE_PAGE (Generic Desktop)&lt;br /&gt;
    0x09, 0x30,                    //     USAGE (X)&lt;br /&gt;
    0x09, 0x31,                    //     USAGE (Y)&lt;br /&gt;
    0x09, 0x38,                    //     USAGE (Wheel)&lt;br /&gt;
    0x15, 0x81,                    //     LOGICAL_MINIMUM (-127)&lt;br /&gt;
    0x25, 0x7f,                    //     LOGICAL_MAXIMUM (127)&lt;br /&gt;
    0x75, 0x08,                    //     REPORT_SIZE (8)&lt;br /&gt;
    0x95, 0x03,                    //     REPORT_COUNT (3)&lt;br /&gt;
    0x81, 0x06,                    //     INPUT (Data,Var,Rel)&lt;br /&gt;
    0xc0,                          //   END_COLLECTION&lt;br /&gt;
    0xc0,                          // END_COLLECTION&lt;br /&gt;
&lt;br /&gt;
	//	Keyboard&lt;br /&gt;
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)	// 47&lt;br /&gt;
    0x09, 0x06,                    // USAGE (Keyboard)&lt;br /&gt;
    0xa1, 0x01,                    // COLLECTION (Application)&lt;br /&gt;
    0x85, 0x02,                    //   REPORT_ID (2)&lt;br /&gt;
    0x05, 0x07,                    //   USAGE_PAGE (Keyboard)&lt;br /&gt;
   &lt;br /&gt;
	0x19, 0xe0,                    //   USAGE_MINIMUM (Keyboard LeftControl)&lt;br /&gt;
    0x29, 0xe7,                    //   USAGE_MAXIMUM (Keyboard Right GUI)&lt;br /&gt;
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)&lt;br /&gt;
    0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)&lt;br /&gt;
    0x75, 0x01,                    //   REPORT_SIZE (1)&lt;br /&gt;
    &lt;br /&gt;
	0x95, 0x08,                    //   REPORT_COUNT (8)&lt;br /&gt;
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)&lt;br /&gt;
    0x95, 0x01,                    //   REPORT_COUNT (1)&lt;br /&gt;
    0x75, 0x08,                    //   REPORT_SIZE (8)&lt;br /&gt;
    0x81, 0x03,                    //   INPUT (Cnst,Var,Abs)&lt;br /&gt;
    &lt;br /&gt;
	0x95, 0x06,                    //   REPORT_COUNT (6)&lt;br /&gt;
    0x75, 0x08,                    //   REPORT_SIZE (8)&lt;br /&gt;
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)&lt;br /&gt;
    0x25, 0x65,                    //   LOGICAL_MAXIMUM (101)&lt;br /&gt;
    0x05, 0x07,                    //   USAGE_PAGE (Keyboard)&lt;br /&gt;
    &lt;br /&gt;
	0x19, 0x00,                    //   USAGE_MINIMUM (Reserved (no event indicated))&lt;br /&gt;
    0x29, 0x65,                    //   USAGE_MAXIMUM (Keyboard Application)&lt;br /&gt;
    0x81, 0x00,                    //   INPUT (Data,Ary,Abs)&lt;br /&gt;
    0xc0,                          // END_COLLECTION&lt;br /&gt;
&lt;br /&gt;
#ifdef RAWHID_ENABLED&lt;br /&gt;
	//	RAW HID&lt;br /&gt;
	0x06, LSB(RAWHID_USAGE_PAGE), MSB(RAWHID_USAGE_PAGE),	// 30&lt;br /&gt;
	0x0A, LSB(RAWHID_USAGE), MSB(RAWHID_USAGE),&lt;br /&gt;
&lt;br /&gt;
	0xA1, 0x01,				// Collection 0x01&lt;br /&gt;
    0x85, 0x03,             // REPORT_ID (3)&lt;br /&gt;
	0x75, 0x08,				// report size = 8 bits&lt;br /&gt;
	0x15, 0x00,				// logical minimum = 0&lt;br /&gt;
	0x26, 0xFF, 0x00,		// logical maximum = 255&lt;br /&gt;
&lt;br /&gt;
	0x95, 64,				// report count TX&lt;br /&gt;
	0x09, 0x01,				// usage&lt;br /&gt;
	0x81, 0x02,				// Input (array)&lt;br /&gt;
&lt;br /&gt;
	0x95, 64,				// report count RX&lt;br /&gt;
	0x09, 0x02,				// usage&lt;br /&gt;
	0x91, 0x02,				// Output (array)&lt;br /&gt;
	0xC0					// end collection&lt;br /&gt;
#endif&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
extern const HIDDescriptor _hidInterface PROGMEM;&lt;br /&gt;
const HIDDescriptor _hidInterface =&lt;br /&gt;
{&lt;br /&gt;
	D_INTERFACE(HID_INTERFACE,1,3,0,0),&lt;br /&gt;
	D_HIDREPORT(sizeof(_hidReportDescriptor)),&lt;br /&gt;
	D_ENDPOINT(USB_ENDPOINT_IN (HID_ENDPOINT_INT),USB_ENDPOINT_TYPE_INTERRUPT,0x40,0x01)&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Driver&lt;br /&gt;
&lt;br /&gt;
u8 _hid_protocol = 1;&lt;br /&gt;
u8 _hid_idle = 1;&lt;br /&gt;
&lt;br /&gt;
#define WEAK __attribute__ ((weak))&lt;br /&gt;
&lt;br /&gt;
int WEAK HID_GetInterface(u8* interfaceNum)&lt;br /&gt;
{&lt;br /&gt;
	interfaceNum[0] += 1;	// uses 1&lt;br /&gt;
	return USB_SendControl(TRANSFER_PGM,&amp;amp;_hidInterface,sizeof(_hidInterface));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int WEAK HID_GetDescriptor(int /* i */)&lt;br /&gt;
{&lt;br /&gt;
	return USB_SendControl(TRANSFER_PGM,_hidReportDescriptor,sizeof(_hidReportDescriptor));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void WEAK HID_SendReport(u8 id, const void* data, int len)&lt;br /&gt;
{&lt;br /&gt;
	USB_Send(HID_TX, &amp;amp;id, 1);&lt;br /&gt;
	USB_Send(HID_TX | TRANSFER_RELEASE,data,len);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool WEAK HID_Setup(Setup&amp;amp; setup)&lt;br /&gt;
{&lt;br /&gt;
	u8 r = setup.bRequest;&lt;br /&gt;
	u8 requestType = setup.bmRequestType;&lt;br /&gt;
	if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType)&lt;br /&gt;
	{&lt;br /&gt;
		if (HID_GET_REPORT == r)&lt;br /&gt;
		{&lt;br /&gt;
			//HID_GetReport();&lt;br /&gt;
			return true;&lt;br /&gt;
		}&lt;br /&gt;
		if (HID_GET_PROTOCOL == r)&lt;br /&gt;
		{&lt;br /&gt;
			//Send8(_hid_protocol);	// TODO&lt;br /&gt;
			return true;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType)&lt;br /&gt;
	{&lt;br /&gt;
		if (HID_SET_PROTOCOL == r)&lt;br /&gt;
		{&lt;br /&gt;
			_hid_protocol = setup.wValueL;&lt;br /&gt;
			return true;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if (HID_SET_IDLE == r)&lt;br /&gt;
		{&lt;br /&gt;
			_hid_idle = setup.wValueL;&lt;br /&gt;
			return true;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	return false;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Mouse&lt;br /&gt;
&lt;br /&gt;
Mouse_::Mouse_(void) : _buttons(0)&lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Mouse_::begin(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Mouse_::end(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Mouse_::click(uint8_t b)&lt;br /&gt;
{&lt;br /&gt;
	_buttons = b;&lt;br /&gt;
	move(0,0,0);&lt;br /&gt;
	_buttons = 0;&lt;br /&gt;
	move(0,0,0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Mouse_::move(signed char x, signed char y, signed char wheel)&lt;br /&gt;
{&lt;br /&gt;
	u8 m[4];&lt;br /&gt;
	m[0] = _buttons;&lt;br /&gt;
	m[1] = x;&lt;br /&gt;
	m[2] = y;&lt;br /&gt;
	m[3] = wheel;&lt;br /&gt;
	HID_SendReport(1,m,4);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Mouse_::buttons(uint8_t b)&lt;br /&gt;
{&lt;br /&gt;
	if (b != _buttons)&lt;br /&gt;
	{&lt;br /&gt;
		_buttons = b;&lt;br /&gt;
		move(0,0,0);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Mouse_::press(uint8_t b) &lt;br /&gt;
{&lt;br /&gt;
	buttons(_buttons | b);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Mouse_::release(uint8_t b)&lt;br /&gt;
{&lt;br /&gt;
	buttons(_buttons &amp;amp; ~b);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
bool Mouse_::isPressed(uint8_t b)&lt;br /&gt;
{&lt;br /&gt;
	if ((b &amp;amp; _buttons) &amp;gt; 0) &lt;br /&gt;
		return true;&lt;br /&gt;
	return false;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//================================================================================&lt;br /&gt;
//================================================================================&lt;br /&gt;
//	Keyboard&lt;br /&gt;
&lt;br /&gt;
Keyboard_::Keyboard_(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Keyboard_::begin(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Keyboard_::end(void) &lt;br /&gt;
{&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Keyboard_::sendReport(KeyReport* keys)&lt;br /&gt;
{&lt;br /&gt;
	HID_SendReport(2,keys,sizeof(KeyReport));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
extern&lt;br /&gt;
const uint8_t _asciimap[128] PROGMEM;&lt;br /&gt;
&lt;br /&gt;
#define SHIFT 0x80&lt;br /&gt;
const uint8_t _asciimap[128] =&lt;br /&gt;
{&lt;br /&gt;
	0x00,             // NUL&lt;br /&gt;
	0x00,             // SOH&lt;br /&gt;
	0x00,             // STX&lt;br /&gt;
	0x00,             // ETX&lt;br /&gt;
	0x00,             // EOT&lt;br /&gt;
	0x00,             // ENQ&lt;br /&gt;
	0x00,             // ACK  &lt;br /&gt;
	0x00,             // BEL&lt;br /&gt;
	0x2a,			// BS	Backspace&lt;br /&gt;
	0x2b,			// TAB	Tab&lt;br /&gt;
	0x28,			// LF	Enter&lt;br /&gt;
	0x00,             // VT &lt;br /&gt;
	0x00,             // FF &lt;br /&gt;
	0x00,             // CR &lt;br /&gt;
	0x00,             // SO &lt;br /&gt;
	0x00,             // SI &lt;br /&gt;
	0x00,             // DEL&lt;br /&gt;
	0x00,             // DC1&lt;br /&gt;
	0x00,             // DC2&lt;br /&gt;
	0x00,             // DC3&lt;br /&gt;
	0x00,             // DC4&lt;br /&gt;
	0x00,             // NAK&lt;br /&gt;
	0x00,             // SYN&lt;br /&gt;
	0x00,             // ETB&lt;br /&gt;
	0x00,             // CAN&lt;br /&gt;
	0x00,             // EM &lt;br /&gt;
	0x00,             // SUB&lt;br /&gt;
	0x00,             // ESC&lt;br /&gt;
	0x00,             // FS &lt;br /&gt;
	0x00,             // GS &lt;br /&gt;
	0x00,             // RS &lt;br /&gt;
	0x00,             // US &lt;br /&gt;
&lt;br /&gt;
	0x2c,		   //  ' '&lt;br /&gt;
	0x1e|SHIFT,	   // !&lt;br /&gt;
	0x34|SHIFT,	   // &amp;quot;&lt;br /&gt;
	0x20|SHIFT,    // #&lt;br /&gt;
	0x21|SHIFT,    // $&lt;br /&gt;
	0x22|SHIFT,    // %&lt;br /&gt;
	0x24|SHIFT,    // &amp;amp;&lt;br /&gt;
	0x34,          // '&lt;br /&gt;
	0x26|SHIFT,    // (&lt;br /&gt;
	0x27|SHIFT,    // )&lt;br /&gt;
	0x25|SHIFT,    // *&lt;br /&gt;
	0x2e|SHIFT,    // +&lt;br /&gt;
	0x36,          // ,&lt;br /&gt;
	0x2d,          // -&lt;br /&gt;
	0x37,          // .&lt;br /&gt;
	0x38,          // /&lt;br /&gt;
	0x27,          // 0&lt;br /&gt;
	0x1e,          // 1&lt;br /&gt;
	0x1f,          // 2&lt;br /&gt;
	0x20,          // 3&lt;br /&gt;
	0x21,          // 4&lt;br /&gt;
	0x22,          // 5&lt;br /&gt;
	0x23,          // 6&lt;br /&gt;
	0x24,          // 7&lt;br /&gt;
	0x25,          // 8&lt;br /&gt;
	0x26,          // 9&lt;br /&gt;
	0x33|SHIFT,      // :&lt;br /&gt;
	0x33,          // ;&lt;br /&gt;
	0x36|SHIFT,      // &amp;lt;&lt;br /&gt;
	0x2e,          // =&lt;br /&gt;
	0x37|SHIFT,      // &amp;gt;&lt;br /&gt;
	0x38|SHIFT,      // ?&lt;br /&gt;
	0x1f|SHIFT,      // @&lt;br /&gt;
	0x04|SHIFT,      // A&lt;br /&gt;
	0x05|SHIFT,      // B&lt;br /&gt;
	0x06|SHIFT,      // C&lt;br /&gt;
	0x07|SHIFT,      // D&lt;br /&gt;
	0x08|SHIFT,      // E&lt;br /&gt;
	0x09|SHIFT,      // F&lt;br /&gt;
	0x0a|SHIFT,      // G&lt;br /&gt;
	0x0b|SHIFT,      // H&lt;br /&gt;
	0x0c|SHIFT,      // I&lt;br /&gt;
	0x0d|SHIFT,      // J&lt;br /&gt;
	0x0e|SHIFT,      // K&lt;br /&gt;
	0x0f|SHIFT,      // L&lt;br /&gt;
	0x10|SHIFT,      // M&lt;br /&gt;
	0x11|SHIFT,      // N&lt;br /&gt;
	0x12|SHIFT,      // O&lt;br /&gt;
	0x13|SHIFT,      // P&lt;br /&gt;
	0x14|SHIFT,      // Q&lt;br /&gt;
	0x15|SHIFT,      // R&lt;br /&gt;
	0x16|SHIFT,      // S&lt;br /&gt;
	0x17|SHIFT,      // T&lt;br /&gt;
	0x18|SHIFT,      // U&lt;br /&gt;
	0x19|SHIFT,      // V&lt;br /&gt;
	0x1a|SHIFT,      // W&lt;br /&gt;
	0x1b|SHIFT,      // X&lt;br /&gt;
	0x1c|SHIFT,      // Y&lt;br /&gt;
	0x1d|SHIFT,      // Z&lt;br /&gt;
	0x2f,          // [&lt;br /&gt;
	0x31,          // bslash&lt;br /&gt;
	0x30,          // ]&lt;br /&gt;
	0x23|SHIFT,    // ^&lt;br /&gt;
	0x2d|SHIFT,    // _&lt;br /&gt;
	0x35,          // `&lt;br /&gt;
	0x04,          // a&lt;br /&gt;
	0x05,          // b&lt;br /&gt;
	0x06,          // c&lt;br /&gt;
	0x07,          // d&lt;br /&gt;
	0x08,          // e&lt;br /&gt;
	0x09,          // f&lt;br /&gt;
	0x0a,          // g&lt;br /&gt;
	0x0b,          // h&lt;br /&gt;
	0x0c,          // i&lt;br /&gt;
	0x0d,          // j&lt;br /&gt;
	0x0e,          // k&lt;br /&gt;
	0x0f,          // l&lt;br /&gt;
	0x10,          // m&lt;br /&gt;
	0x11,          // n&lt;br /&gt;
	0x12,          // o&lt;br /&gt;
	0x13,          // p&lt;br /&gt;
	0x14,          // q&lt;br /&gt;
	0x15,          // r&lt;br /&gt;
	0x16,          // s&lt;br /&gt;
	0x17,          // t&lt;br /&gt;
	0x18,          // u&lt;br /&gt;
	0x19,          // v&lt;br /&gt;
	0x1a,          // w&lt;br /&gt;
	0x1b,          // x&lt;br /&gt;
	0x1c,          // y&lt;br /&gt;
	0x1d,          // z&lt;br /&gt;
	0x2f|SHIFT,    // &lt;br /&gt;
	0x31|SHIFT,    // |&lt;br /&gt;
	0x30|SHIFT,    // }&lt;br /&gt;
	0x35|SHIFT,    // ~&lt;br /&gt;
	0				// DEL&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
uint8_t USBPutChar(uint8_t c);&lt;br /&gt;
&lt;br /&gt;
// press() adds the specified key (printing, non-printing, or modifier)&lt;br /&gt;
// to the persistent key report and sends the report.  Because of the way &lt;br /&gt;
// USB HID works, the host acts like the key remains pressed until we &lt;br /&gt;
// call release(), releaseAll(), or otherwise clear the report and resend.&lt;br /&gt;
size_t Keyboard_::press(uint8_t k) &lt;br /&gt;
{&lt;br /&gt;
	uint8_t i;&lt;br /&gt;
	if (k &amp;gt;= 136) {			// it's a non-printing key (not a modifier)&lt;br /&gt;
		k = k - 136;&lt;br /&gt;
	} else if (k &amp;gt;= 128) {	// it's a modifier key&lt;br /&gt;
		_keyReport.modifiers |= (1&amp;lt;&amp;lt;(k-128));&lt;br /&gt;
		k = 0;&lt;br /&gt;
	} else {				// it's a printing key&lt;br /&gt;
		k = pgm_read_byte(_asciimap + k);&lt;br /&gt;
		if (!k) {&lt;br /&gt;
			setWriteError();&lt;br /&gt;
			return 0;&lt;br /&gt;
		}&lt;br /&gt;
		if (k &amp;amp; 0x80) {						// it's a capital letter or other character reached with shift&lt;br /&gt;
			_keyReport.modifiers |= 0x02;	// the left shift modifier&lt;br /&gt;
			k &amp;amp;= 0x7F;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// Add k to the key report only if it's not already present&lt;br /&gt;
	// and if there is an empty slot.&lt;br /&gt;
	if (_keyReport.keys[0] != k &amp;amp;&amp;amp; _keyReport.keys[1] != k &amp;amp;&amp;amp; &lt;br /&gt;
		_keyReport.keys[2] != k &amp;amp;&amp;amp; _keyReport.keys[3] != k &amp;amp;&amp;amp;&lt;br /&gt;
		_keyReport.keys[4] != k &amp;amp;&amp;amp; _keyReport.keys[5] != k) {&lt;br /&gt;
		&lt;br /&gt;
		for (i=0; i&amp;lt;6; i++) {&lt;br /&gt;
			if (_keyReport.keys[i] == 0x00) {&lt;br /&gt;
				_keyReport.keys[i] = k;&lt;br /&gt;
				break;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
		if (i == 6) {&lt;br /&gt;
			setWriteError();&lt;br /&gt;
			return 0;&lt;br /&gt;
		}	&lt;br /&gt;
	}&lt;br /&gt;
	sendReport(&amp;amp;_keyReport);&lt;br /&gt;
	return 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// release() takes the specified key out of the persistent key report and&lt;br /&gt;
// sends the report.  This tells the OS the key is no longer pressed and that&lt;br /&gt;
// it shouldn't be repeated any more.&lt;br /&gt;
size_t Keyboard_::release(uint8_t k) &lt;br /&gt;
{&lt;br /&gt;
	uint8_t i;&lt;br /&gt;
	if (k &amp;gt;= 136) {			// it's a non-printing key (not a modifier)&lt;br /&gt;
		k = k - 136;&lt;br /&gt;
	} else if (k &amp;gt;= 128) {	// it's a modifier key&lt;br /&gt;
		_keyReport.modifiers &amp;amp;= ~(1&amp;lt;&amp;lt;(k-128));&lt;br /&gt;
		k = 0;&lt;br /&gt;
	} else {				// it's a printing key&lt;br /&gt;
		k = pgm_read_byte(_asciimap + k);&lt;br /&gt;
		if (!k) {&lt;br /&gt;
			return 0;&lt;br /&gt;
		}&lt;br /&gt;
		if (k &amp;amp; 0x80) {							// it's a capital letter or other character reached with shift&lt;br /&gt;
			_keyReport.modifiers &amp;amp;= ~(0x02);	// the left shift modifier&lt;br /&gt;
			k &amp;amp;= 0x7F;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// Test the key report to see if k is present.  Clear it if it exists.&lt;br /&gt;
	// Check all positions in case the key is present more than once (which it shouldn't be)&lt;br /&gt;
	for (i=0; i&amp;lt;6; i++) {&lt;br /&gt;
		if (0 != k &amp;amp;&amp;amp; _keyReport.keys[i] == k) {&lt;br /&gt;
			_keyReport.keys[i] = 0x00;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	sendReport(&amp;amp;_keyReport);&lt;br /&gt;
	return 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Keyboard_::releaseAll(void)&lt;br /&gt;
{&lt;br /&gt;
	_keyReport.keys[0] = 0;&lt;br /&gt;
	_keyReport.keys[1] = 0;	&lt;br /&gt;
	_keyReport.keys[2] = 0;&lt;br /&gt;
	_keyReport.keys[3] = 0;	&lt;br /&gt;
	_keyReport.keys[4] = 0;&lt;br /&gt;
	_keyReport.keys[5] = 0;	&lt;br /&gt;
	_keyReport.modifiers = 0;&lt;br /&gt;
	sendReport(&amp;amp;_keyReport);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
size_t Keyboard_::write(uint8_t c)&lt;br /&gt;
{	&lt;br /&gt;
	uint8_t p = press(c);  // Keydown&lt;br /&gt;
	release(c);            // Keyup&lt;br /&gt;
	return p;              // just return the result of press() since release() almost always returns 1&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#endif /* if defined(USBCON) */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
------&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Arduino核心代码|返回核心代码首页]]&lt;br /&gt;
&lt;br /&gt;
更多建议和问题欢迎反馈至 [http://www.yfrobot.com YFRobot论坛]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	</feed>