久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4448|回復: 1
打印 上一主題 下一主題
收起左側

PDIUSBD12-USB鍵盤keyboard,51單片機程序源碼

[復制鏈接]
跳轉到指定樓層
樓主
PDIUSBD12芯片做的usb鍵盤的一個例子,51單片機主控.
EDN USB開發板上共有8個按鍵,功能分別為:
K1:左Ctrl鍵  K2:左Shift鍵  K3:左Alt鍵  K4:0鍵
K5:1鍵  K6:2鍵  K7:Caps Lock鍵 K8:Num Lock鍵

按鍵功能測試:

同時按下K1和K2可做輸入法切換,這跟鍵盤上的兩個鍵功能一樣的。
K7可打開大寫字母鎖定,同時LED2亮起。K8是小數字鍵盤鎖定鍵,
當數字鍵盤打開時,LED1亮起,這時可用K4,K5,K6輸入數字。
請留意EDN板上的LED會跟你自己的鍵盤上的LED燈同步。不管按哪塊
鍵盤切換都是如此。不過按住切換鍵不放,可能會導致兩塊鍵盤之間
的LED失步。


所有資料51hei提供下載:
PDIUSBD12-keyboard.rar (112.77 KB, 下載次數: 48)


PDIUSBD12芯片USB鍵盤的單片機源程序如下:
  1. /******************************************************************
  2.    本程序只供學習使用,未經作者許可,不得用于其它任何用途
  3. USBKeyBoard.C  file
  4. 作者:Computer-lov
  5. 版本:V1.1
  6. 版權所有,盜版必究。
  7. Copyright(C) Computer-lov 2007-2017
  8. All rights reserved            
  9. *******************************************************************/

  10. #include "AT89x52.H"
  11. #include "USB.H"
  12. #include "PDIUSBD12.H"
  13. #include "My_type.h"
  14. #include "UART.H"
  15. #include "key.h"
  16. #include "keyboard.h"
  17. #include "led.h"

  18. #define DispLineInf()      \
  19. {                          \
  20. Prints(" in file \"");    \
  21. Prints(__FILE__);         \
  22. Prints(", @ line ");      \
  23. PrintLongInt(__LINE__-1); \
  24. Prints("\r\n");           \
  25. }

  26. //#define debug

  27. #define USB_COMMAND_ADD           1
  28. #define USB_DATA_ADD              0

  29. //USB芯片連接引腳
  30. #define USB_DATA                  P0
  31. #define USB_A0                    P3_5
  32. #define USB_WR                    P3_6
  33. #define USB_RD                    P3_7
  34. #define USB_INT                   P3_2


  35. #define ENDPOINT_NUMBER           2
  36. #define MAX_CONTROL_DATA_SIZE     16


  37. //控制傳輸時保存數據
  38. CONTROL_DATA_BUFF Control_Data;

  39. //緩沖
  40. uint8 idata buffer[64];

  41. //交換數據時用的指針
  42. uint8 *pData;

  43. uint8 idle;     //空閑狀態
  44. uint8 protocol; //當前協議

  45. //高低字節交換

  46. #define SWAP16(x)  ((((uint16)(x))<<8)|(((uint16)(x))>>8))

  47. //取一個整數的低字節
  48. #define LSB(x) ((uint8)(x))

  49. //取一個整數的高字節
  50. #define MSB(x) ((uint8)(((uint16)(x))>>8))                              

  51. //字符串描述符所用的語言種類
  52. code uint8 LANGUAGE_ID[4]={0x04,0x03,0x09,0x04};                  

  53. //設備序列號                                                                                
  54. code uint8 device_serial_number[]=
  55. {22,STRING_DESCRIPTOR,'2',0,'0',0,'0',0,'7',0,'-',0,'1',0,'1',0,'-',0,'2',0,'9',0};

  56. //廠商字符串
  57. //漢字Unicode編碼
  58. code uint8 ManufacturerString[80]=
  59. {80,STRING_DESCRIPTOR,0x35,0x75,0x11,0x81,0x08,0x57,0x08,0x57,0x84,0x76,'U',0x00,
  60. 'S',0x00,'B',0x00,0x13,0x4E,0x3A,0x53,0x20,0x00,'H',0,'t',0,'t',0,
  61. 'p',0,':',0,'/',0,'/',0,'g',0,'r',0,'o',0,'u',0,'p',0,'.',0,'e',0,'d',0,'n',0,
  62. 'c',0,'h',0,'i',0,'n',0,'a',0,'.',0,'c',0,'o',0,'m',0,'/',0,'9',0,'3',0};

  63. //產品字符串 
  64. //漢字Unicode編碼
  65. code uint8 ProducterString[96]=
  66. {96,STRING_DESCRIPTOR,0x35,0x75,0x11,0x81,0x08,0x57,0x08,0x57,0x84,0x76,'U',0x00,
  67. 'S',0x00,'B',0x00,0x13,0x4E,0x3A,0x53,0x3B,0x6D,0xA8,0x52,0x4B,0x4E,'U',0x00,
  68. 'S',0x00,'B',0x00,0x2E,0x95,0xD8,0x76,0x20,0x00,'H',0,'t',0,'t',0,
  69. 'p',0,':',0,'/',0,'/',0,'g',0,'r',0,'o',0,'u',0,'p',0,'.',0,'e',0,'d',0,'n',0,
  70. 'c',0,'h',0,'i',0,'n',0,'a',0,'.',0,'c',0,'o',0,'m',0,'/',0,'9',0,'3',0};

  71. code DEVICE_DESCRIPTOR_STRUCT device_descriptor=     //設備描述符
  72. {
  73. sizeof(DEVICE_DESCRIPTOR_STRUCT),                   //設備描述符的字節數大小
  74. DEVICE_DESCRIPTOR,                                         //設備描述符類型編號
  75. SWAP16(0x0110),                                     //USB版本號,USB1.1
  76. 0x00,                                               //USB分配的設備類代碼
  77. 0x00,                                               //USB分配的子類代碼
  78. 0x00,                                               //USB分配的設備協議代碼
  79. 0x10,                                               //端點0的最大包大小
  80. SWAP16(0x8888),                                     //廠商編號VID,這里只是作為測試用,請使用自己的VID
  81. SWAP16(0x0001),                                     //產品編號PID,這里只是作為測試用,請使用自己的PID
  82. SWAP16(0x0001),                                     //設備出廠編號
  83. 0x01,                                               //設備廠商字符串的索引
  84. 0x02,                                               //描述產品字符串的索引
  85. 0x03,                                               //描述設備序列號字符串的索引
  86. 0x01                                                //可能的配置數量
  87. };

  88. //定義配置,接口,端點等描述符結構體,因為它們是隨配置描述符一起返回的
  89. typedef struct _CON_INT_ENDP_DESCRIPTOR_STRUCT
  90. {
  91. CONFIGURATION_DESCRIPTOR_STRUCT configuration_descriptor;
  92. INTERFACE_DESCRIPTOR_STRUCT  interface_descriptor;
  93. HID_DESCRIPTOR_STRUCT hid_descriptor;
  94. ENDPOINT_DESCRIPTOR_STRUCT  endpoint_descriptor[ENDPOINT_NUMBER];
  95. }CON_INT_ENDP_DESCRIPTOR_STRUCT;

  96. code CON_INT_ENDP_DESCRIPTOR_STRUCT con_int_endp_descriptor=
  97. {
  98. //configuration_descriptor                                          //配置描述符
  99. {
  100. sizeof(CONFIGURATION_DESCRIPTOR_STRUCT),                           //配置描述符的字節數大小
  101. CONFIGURATION_DESCRIPTOR,                                          //配置描述符類型編號
  102. SWAP16(sizeof(CON_INT_ENDP_DESCRIPTOR_STRUCT)),
  103. 0x01,                                                            //只包含一個接口
  104. 0x01,                                                            //該配置的編號
  105. 0x00,                                                            //iConfiguration字段
  106. 0xA0,                                                            //采用總線供電,支持遠程喚醒
  107. 0xC8                                                            //從總線獲取最大電流400mA
  108. },
  109. //interface_descritor                                             //接口描述符
  110. {
  111. sizeof(INTERFACE_DESCRIPTOR_STRUCT),                             //接口描述符的字節數大小
  112. INTERFACE_DESCRIPTOR,                                            //接口描述符類型編號
  113. 0x00,                                                            //接口編號為0
  114. 0x00,                                                            //該接口描述符的編號
  115. ENDPOINT_NUMBER,                                                 //非0端點數量為2,只使用端點主端點輸入和輸出
  116. 0x03,                                                            //人機接口設備(HID)類
  117. 0x01,                                                            //使用的子類:支持BIOS根啟動Boot的子類
  118. 0x01,                                                            //使用的協議:鍵盤
  119. 0x00                                                             //接口描述符字符串索引
  120. },
  121. //hid_descriptor
  122. {
  123. sizeof(HID_DESCRIPTOR_STRUCT),                                   //HID描述符的字節數大小
  124. HID_DESCRIPTOR,                                                  //HID描述符類型編號
  125. SWAP16(0x0110),                                                  //HID類協議版本號,為1.1
  126. 0x21,                                                            //固件的國家地區代號,0x21為美國
  127. NUM_SUB_DESCRIPTORS,                                             //下級描述符的數量
  128. {
  129.   {
  130.    REPORT_DESCRIPTOR,                                             //下級描述符為報告描述符
  131.    SWAP16(sizeof(KeyBoardReportDescriptor))                       //下級描述符的長度
  132.   }
  133. },
  134. },
  135. //endpoint_descriptor[]
  136. {
  137. {                                                                //主端點輸入描述
  138.   sizeof(ENDPOINT_DESCRIPTOR_STRUCT),                             //端點描述符的字節數大小
  139.   ENDPOINT_DESCRIPTOR,                                            //端點描述符類型編號
  140.   MAIN_POINT_IN,                                                  //端點號,主輸入端點
  141.   ENDPOINT_TYPE_INTERRUPT,                                        //使用的傳輸類型:中斷傳輸
  142.   SWAP16(0x0040),                                                 //該端點支持的最大包尺寸,64字節
  143.   0x0A                                                            //中斷掃描時間:設置為10ms
  144. },
  145.   
  146. {                                                                //主端點輸出描述
  147.   sizeof(ENDPOINT_DESCRIPTOR_STRUCT),                             //端點描述符的字節數大小
  148.   ENDPOINT_DESCRIPTOR,                                            //端點描述符類型編號
  149.   MAIN_POINT_OUT,                                                 //端點號,主輸出端點
  150.   ENDPOINT_TYPE_INTERRUPT,                                        //使用的傳輸類型:中斷傳輸
  151.   SWAP16(0x0040),                                                 //該端點支持的最大包尺寸,64字節
  152.   0x0A                                                            //中斷掃描時間:設置為10ms
  153. }
  154. }
  155. };

  156. union                                          //程序標志位
  157. {
  158. uint16 Register;
  159. struct
  160. {
  161. uint8 bus_reset        :1;
  162. uint8 suspend          :1;
  163. uint8 remote_wakeup    :1;
  164. uint8 int_isr          :1;
  165. uint8 not_end          :1;
  166. uint8 usb_idle         :1;
  167. uint8 usb_busy         :1;
  168. uint8 setup_packet_in  :1;
  169. uint8 setup_packet_out :1;
  170. uint8 set_addr         :1;
  171. uint8 usb_endp0_in     :1;
  172. uint8 usb_endp2_in     :1;
  173. uint8 usb_endp2_out    :1;
  174. }flags;
  175. }usb_flags;

  176. union                                         //中斷寄存器
  177. {
  178. uint8 Register[2];
  179. struct
  180.   {
  181.    uint8 control_out_port  :1;
  182.    uint8 control_in_port   :1;
  183.    uint8 port_out_1        :1;
  184.    uint8 port_in_1         :1;
  185.    uint8 main_out_port     :1;
  186.    uint8 main_in_port      :1;
  187.    uint8 bus_reset         :1;
  188.    uint8 suspend_change    :1;
  189.    uint8 DMA_EOT           :1;
  190.    uint8 not_use           :7;
  191.   }Interrupt;
  192. }Interrupt_Register;


  193. union                                    //端點最后處理狀態
  194. {
  195. uint8 Register;
  196. struct
  197. {
  198.   uint8 successful          :1;
  199.   uint8 error_code          :4;
  200.   uint8 setup_packet        :1;
  201.   uint8 data_1              :1;
  202.   uint8 prestatus_not_read  :1;
  203. }Status;
  204. }Last_Status;


  205. /*****************   延時x毫秒函數 ***********/
  206. void delay(uint16 x)               
  207. {
  208. uint16 i;
  209. uint16 j;
  210. for(i=0;i<x;i++)
  211. for(j=0;j<230;j++);
  212. }
  213. /********************************************/

  214. /*******************************寫USB命令******************************************/
  215. void write_usb_command(uint8 usb_command)
  216. {
  217. USB_A0=USB_COMMAND_ADD;
  218. USB_DATA=usb_command;
  219. USB_WR=0;
  220. USB_WR=1;
  221. USB_DATA=0xFF;
  222. }
  223. /******************************************************************************/

  224. /*********************寫一字節USB數據*******************************************/
  225. void write_a_usb_data(uint8 usb_data)      
  226. {
  227. USB_A0=USB_DATA_ADD;
  228. USB_DATA=usb_data;
  229. USB_WR=0;
  230. USB_WR=1;
  231. USB_DATA=0XFF;
  232. }
  233. /******************************************************************************/

  234. /****************************讀一字節USB數據************************************/
  235. uint8 read_a_usb_data(void)
  236. {
  237. uint8 temp;
  238. USB_A0=USB_DATA_ADD;
  239. USB_RD=0;
  240. temp=USB_DATA;
  241. USB_RD=1;
  242. return temp;
  243. }
  244. /******************************************************************************/

  245. /************************讀USB中斷寄存器**************************************/
  246. void read_interrupt_register(void)
  247. {
  248. write_usb_command(Read_Interrupt_Register);
  249. Interrupt_Register.Register[0]=read_a_usb_data();
  250. Interrupt_Register.Register[1]=read_a_usb_data();
  251. }
  252. /******************************************************************************/

  253. /************************設置USB地址*******************************************/
  254. void set_usb_addr(uint8 addr)
  255. {
  256. write_usb_command(Set_Address);
  257. write_a_usb_data(0x80|addr);
  258. Prints("   設置地址.\r\n");
  259. Prints("       地址為:  ");
  260. PrintLongInt(addr);
  261. Prints("\r\n");
  262. }
  263. /******************************************************************************/

  264. /*************************端點使能******************************************/
  265. void set_endpoint_enable(void)
  266. {
  267. write_usb_command(Set_Endpoint_Enable);
  268. write_a_usb_data(0x01);
  269. }
  270. /******************************************************************************/

  271. /****************************選擇終端點*************************************/
  272. uint8 select_endpoint(uint8 endp)
  273. {
  274. write_usb_command(Select_EndPoint+endp);
  275. return read_a_usb_data();
  276. }
  277. /******************************************************************************/

  278. /****************************讀端點最后狀態**********************************/
  279. uint8  read_last_status(uint8 endp)
  280. {
  281. write_usb_command(Read_Last_Status+endp);
  282. return read_a_usb_data();
  283. }
  284. /******************************************************************************/

  285. /****************************設置端點狀態**************************************/
  286. void set_endpoint_status(uint8 endp,uint8 status)  
  287. {
  288. write_usb_command(0x40+endp);
  289. write_a_usb_data(!status);
  290. }
  291. /******************************************************************************/

  292. /*****************************讀端點狀態**************************************/
  293. uint8 read_endpoint_status(uint8 endp)
  294. {
  295. write_usb_command(0x80+endp);
  296. return read_a_usb_data();
  297. }
  298. /******************************************************************************/

  299. /************************清緩沖,在讀取緩沖數據后調用**************************/
  300. void clear_buffer(void)
  301. {
  302. write_usb_command(Clear_Buffer);
  303. #ifdef debug
  304. Prints("Clear buffer.\r\n");
  305. #endif
  306. }
  307. /******************************************************************************/

  308. /***********************緩沖區數據有效,在寫緩沖后調用**************************/
  309. void validate_buffer(void)
  310. {
  311. write_usb_command(Validate_Buffer);
  312. #ifdef debug
  313. Prints("Validate buffer.\r\n");
  314. #endif
  315. }
  316. /******************************************************************************/

  317. /***************************應答建立包************************************/
  318. void ack_setup(uint8 endp)
  319. {
  320. select_endpoint(endp);
  321. write_usb_command(Ack_Setup);
  322. #ifdef debug
  323. Prints("Ack setup ");
  324. PrintLongInt(endp);
  325. Prints(".\r\n");
  326. #endif
  327. }
  328. /******************************************************************************/

  329. /***********************出錯處理******************************************/
  330. void error(uint8 number)
  331. {
  332. Prints("有錯誤發生。。r\n");
  333. number=0;
  334. }
  335. /******************************************************************************/

  336. /*************************讀終端點緩沖****************************************/
  337. uint8 read_endpoint_buff(uint8 endp,uint8 len,uint8 * buff)
  338. {
  339. uint8 i,j;
  340. read_last_status(endp);
  341. if(!(select_endpoint(endp)&0x01)){error(0); return 0;}
  342. if((read_endpoint_status(endp)&0x60)!=0x60)  //兩個緩沖沒有都滿,才能清中斷
  343. {
  344.   read_last_status(endp);  //清中斷
  345. }
  346. write_usb_command(Read_Buffer);
  347. read_a_usb_data();
  348. j=read_a_usb_data();
  349. if(j>len)
  350.   j=len;  
  351. #ifdef debug
  352. Prints("Read endpoint");
  353. PrintLongInt(endp);
  354. Prints("\'s buffer ");
  355. PrintLongInt(j);
  356. Prints(" bytes.\r\n");
  357. #endif  
  358. for(i=0;i<j;i++)
  359.   {
  360.    USB_RD=0;
  361.    *(buff+i)=USB_DATA;
  362.    USB_RD=1;
  363. #ifdef debug
  364.    PrintHex(*(buff+i));
  365. #endif
  366.   }
  367. #ifdef debug
  368. Prints("\r\n");
  369. #endif
  370. clear_buffer();
  371. return j;
  372. }
  373. /******************************************************************************/

  374. /*************************寫終端點緩沖*****************************************/
  375. uint8 write_endpoint_buff(uint8 endp,uint8 len,uint8 * buff)
  376. {
  377. uint8 i;
  378. read_last_status(endp);
  379. select_endpoint(endp);
  380. write_usb_command(Write_Buffer);
  381. write_a_usb_data(0);
  382. write_a_usb_data(len);
  383. #ifdef debug
  384. Prints("Write endpoint");
  385. PrintLongInt(endp);
  386. Prints("\'s buffer ");
  387. PrintLongInt(len);
  388. Prints(" bytes.\r\n");
  389. #endif
  390. for(i=0;i<len;i++)
  391.   {
  392.    USB_DATA=*(buff+i);
  393.    USB_WR=0;
  394.    USB_WR=1;
  395. #ifdef debug
  396.    PrintHex(*(buff+i));
  397. #endif
  398.   }
  399. #ifdef debug
  400. Prints("\r\n");
  401. #endif  
  402. USB_DATA=0xFF;
  403. validate_buffer();
  404. return len;
  405. }
  406. /******************************************************************************/

  407. /***************************斷開USB連接****************************************/
  408. void disconnect_usb(void)
  409. {
  410. Prints("斷開USB連接.\r\n");
  411. write_usb_command(0xf3);
  412. write_a_usb_data(0x0e);
  413. write_a_usb_data(0x47);
  414. delay(100);
  415. }
  416. /******************************************************************************/

  417. /*******************************連接USB**************************************/
  418. void connect_usb(void)
  419. {
  420. Prints("連接USB.\r\n");
  421. write_usb_command(0xf3);                         //初始化USBD12
  422. write_a_usb_data(0x1e);                          //連接USB
  423. write_a_usb_data(0x47);                          //設置頻率
  424. }
  425. /******************************************************************************/

  426. /***************************初始化USB***************************************************/
  427. void init_usb(void)               
  428. {
  429. Prints("USBD12芯片初始化\r\n");
  430. set_usb_addr(0);
  431. set_endpoint_enable();
  432. }
  433.                         
  434. ……………………

  435. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼



分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:142060 發表于 2019-12-23 14:19 | 只看該作者
謝謝樓主,厲害厲害
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 日韩乱码在线 | 欧美国产中文字幕 | 奇米四色在线观看 | 久久久久久久一区 | 欧美黄色网络 | 91视频久久| 一区中文字幕 | 国产精品一区二区三区在线 | 欧美视频二区 | 成人高清在线 | 美国一级毛片a | 视频一区二区三区中文字幕 | 99热首页| 91精品一区二区三区久久久久久 | 一级做a| 久久久www成人免费精品 | 成人午夜在线 | 午夜成人免费视频 | 涩涩视频网站在线观看 | 亚洲一区二区免费电影 | 一区精品在线观看 | 午夜专区| 亚洲a在线观看 | 一区二区三区在线免费观看 | 久久毛片网站 | 嫩草网 | 精品国产乱码一区二区三区a | 免费看的av | 久久久九九九九 | 免费观看羞羞视频网站 | 久久婷婷麻豆国产91天堂 | 欧美色偷拍 | 色婷婷九月 | 亚洲狠狠 | 毛片一级网站 | 91亚洲国产成人精品一区二三 | 久久精品影视 | www日日日 | 91久久看片 | 5060网一级毛片 | 久久精品亚洲 |