?? usb_kf.txt
字號:
一,概述
現在很多的主控上都帶有USB的功能,但是對于初學者來說,這方面應用還是比較棘手,因為usb的不但固件程序需要編寫,PC端的驅動也要編寫,而且驅動寫好了還要寫個上位機才能看出效果。這樣調試起來十分困難,建議從USB的鍵盤,鼠標開始做,了解清楚了,再做自己的協議就比較簡單了。
USB的概念歷史啥的這里就不說了。我們先不管具體的數據包格式,這一節先從整個包的層面上簡單的說,過程是這樣的,
---------------------------------------設備插入-------------------------------------------------------------
1) 主機會輪回查詢各個USB端口,主機檢測到D+與D-之間有電壓差,就認為有新的設置接入。主機等待100ms后發出復位請求。設備接到復位請求后將產生一個外部中斷信號。
---------------------------------------枚舉過程------------------------------------------------------------
2) 主機這時候只是知道有新的設備插入了,但是不知道插進來個什么東西,所以就開始詢問它是什么設備,怎么用,負荷能力怎么樣。這個時侯就進入了枚舉過程。因為剛剛插入的設備沒有分配地址,就用默認地址0,首先發送一個Get_descriptor(獲取設備描述符)指令包,設備接到包后就開始解析包(其實就是你在固件程序里判斷處理) ,然后按固定格式返回自己設備的設備描述符,這一步主要是主機知道你的USB設備的基礎屬性,比如支持的傳輸數據長度,電流負荷多少,支持那個USB版本,以及以后方便電腦找驅動的PID,VID。
3) 這時候主機知道你(你做的設備,簡稱你吧)的數據長度還有電流大小后,下一步就是給你分配一個屬于你的地址。
4) 給你一個地址后就開始詢問你的具體配置。首先發送一個試探性的設備配置請求Get_configuration(要求固定返回9個設備配置字),你接到后就開始發送9字節的設備配置字,其中包括你的配置字的總長度,這樣主機就知道你的配置到底有多長,然后再發一次設備配置請求,這時你就開始上傳所有的配置字。這個時侯主機就已經很明白你的工作方式就各種特性,然后就可以正常工作了
5) 如果你在前面的某些配置(以后章節詳細說明)要求要說明自己的名字什么的,這里還要上傳字符串描述符。
6) 如果是鼠標或者鍵盤還要上傳報告描述符
---------------------------------------正常數據階段------------------------------------------------------
7) 這個時侯你已經被主機正式接受并且注冊了,你可以通過自己寫測驅動或通用驅動與電腦進行通訊了。
以上是簡單的描述,詳細的后面章節再做介紹,學習一個東西關鍵是首先要知道這個東西是什么,簡單的工作原理。對于USB的工作我這里做個比方,
主機好比一個公司,你就是USB設備,要進入公司首先要面試(枚舉),你到了面試現場(第一次插入設備),面試官首先了解到你的外表,性別已經你要應聘的崗位(設備描述符),然后給你一個號,以后就開始按號叫人,當你被叫到就開始問你的專業知識,性格等(配置描述符),如果你比較合適(通過了枚舉)你就會錄取了,并且注冊一個你的信息到公司(驅動安裝,并且寫入注冊表)。等你下次來公司,只要把工號(PID,VID)報上,就知道是你來了。
二,實際數據過程測試
(圖片顏色顯示不出,可以到我博客http://blog.csdn.net/arthur05611/archive/2009/02/23/3929778.aspx)
這節主要是對固件里的USB請求處理有個概念,還有就是調試的方法。大篇幅的程序配合,如果不關心這一塊的話可以跳過,呵呵。
為了更好的說明整個USB啟動過程,我們可以用串口實時的跟蹤各個USB中斷。不過這里先不用串口進行測試,只是簡單的用一組變量記錄過程。測試程序如下(以下會有程序的說明):
uchar test[100];//100長度的變量,記錄過程
uchar conters=0;//記錄計數值,
/*------------------------------------------------------------
高校電子聯盟--肖繼達
QQ:258347765
-------------------------------------------------------------*/
void EXT_int(void)//USB中斷響應函數
{
/*------------------------------------------------------------
Check interrupt status register to know interrupt
source.
------------------------------------------------------------*/
if (USB_BUSRESET_ASS_INT())
{ /* USB bus reset */
/* for USB Rev.1.1
After USB bus reset released, 10msec recoverly time we have.
Follwing request must be processed normally.
*/
CLR_BUS_RESET_STATE(); /* USB bus reset status clear */
/*------------------------------------------------------------
Endpoint0 setting
------------------------------------------------------------*/
/* Tx/Rx payload size setting */
/* Rx payload is fixed as 8-byte or 32-byte, therefor the
setting has no meaninig */
SET_PAYLOAD_EPn(EP0RX, device_descriptor.bMaxPacketSize0);
SET_PAYLOAD_EPn(EP0TX, device_descriptor.bMaxPacketSize0);
/* Stall bit, the value undefined after reset, cleared */
CLR_STALL_EPn(EP0);
/*------------------------------------------------------------
Misceronous status variable initialization
------------------------------------------------------------*/
usb_status.configuration = NULL;
usb_status.remote_wakeup = 0;
usb_status.address = 0;
usb_status.dvcstate = DEFAULT_STATE; /* Device state :DEFAULT */
usb_status.stall_req = 0;
#ifdef Debug
test[conters]='!';
conters++;
#endif
/*------------------------------------------------------------
Callback to application layer
------------------------------------------------------------*/
(*usb_status.callback)();
}
else if (SUSPENDED_INT())
{ /* suspended state */
/* for USB Rev.1.1
Transit to suspended state after detect the USB line has kept idle over 3msec.
After resume detected, end suspend state in 3msec to be able to respond
the host request.
*/
CLR_SUSPENDED_STATE();
#ifdef Debug
test[conters]='@';
conters++;
#endif
}
else if (AWAKE_INT())
{ /* Deveice awake state */
/* AWAKE procedure */
CLR_AWAKE_STATE(); /* Request clear */
#ifdef Debug
test[conters]='#';
conters++;
#endif
}
else if (USB_BUSRESET_DES_INT())
{ /* USB bus reset deassert */
/* Procedure for USB bus reset de-assert */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -