【正文】
部結(jié)構(gòu)在書上有一個(gè)很好的USB內(nèi)部接口模塊內(nèi)部結(jié)構(gòu)圖,比較好的解釋了各個(gè)模塊之間的關(guān)系,我這里試著用我自己的理解闡述一下吧。 ISTR_CTR amp。}處理端點(diǎn)傳輸完成的代碼,這段是最重要的,()文件中的CTR_LP()函數(shù)來處理端點(diǎn)數(shù)據(jù)傳輸完成中斷。}else{/* if not possible then resume after xx ms */Resume(RESUME_LATER)。 ISTR_SUSP amp。Resume(RESUME_EXTERNAL)。 ISTR_WKUP amp。 //清復(fù)位中斷()。 ISTR_RESET amp。wIstr = _GetISTR()。SetEPTxValid(ENDP1)。主要代碼如下:UserToPMABufferCopy(Mouse_Buffer, GetEPTxAddr(ENDP1), 4)。當(dāng)然這里真正的發(fā)送工作并不是由該代碼完成的。JoyState()用來獲取按鍵的狀態(tài)。這個(gè)函數(shù)調(diào)用主要是為程序中用到的精確延時(shí)作配置。但我還是先把main()函數(shù)的代碼看完吧。 /* set interrupts mask */bDeviceState = UNCONNECTED。/* clear pending interrupts */wInterrupt_Mask = IMR_MSK。//連接USB設(shè)備,實(shí)質(zhì)是能讓主機(jī)檢測(cè)到了。//獲取設(shè)備序列號(hào),轉(zhuǎn)變?yōu)閡nicode字符串pInformationCurrent_Configuration = 0。這是指針的高級(jí)應(yīng)用。Windows中處理消息,好像也用到了這種模式。而下層函數(shù)(usb_init相對(duì)于usb_prop是輸入底層操作文件)調(diào)用上層文件函數(shù)我們稱之為回調(diào)。Usb_init()函數(shù)調(diào)用pPropertyInit()(實(shí)質(zhì)上就是Joystick_init)完成設(shè)備的初始化。DEVICE_PROP Device_Property ={Joystick_init,Joystick_Reset,Joystick_Status_In,Joystick_Status_Out,Joystick_Data_Setup,Joystick_NoData_Setup,Joystick_Get_Interface_Setting,Joystick_GetDeviceDescriptor,Joystick_GetConfigDescriptor,Joystick_GetStringDescriptor,0,0x40 /*MAX PACKET SIZE*/}。/* Initialize devices one by one */pPropertyInit()。pUser_Standard_Requests = amp。pProperty = amp。Device_Info。后面兩個(gè)是函數(shù)指針結(jié)構(gòu)體,里面都是USB請(qǐng)求實(shí)現(xiàn)、功能實(shí)現(xiàn)的函數(shù)指針。(4)USB_Init(void)這個(gè)是main函數(shù)中調(diào)用的第四個(gè)函數(shù)。(3)Set_USBClock()這個(gè)是main函數(shù)中調(diào)用的第三個(gè)函數(shù)。主要功能是配置USB所用到的中斷。(2)USB_Interrupts_Config()。它的主要功能是初始化時(shí)鐘系統(tǒng)、使能相關(guān)的外圍設(shè)備電源。而是先利用MDK的軟件模擬器仿真執(zhí)行,先了解一下設(shè)備初始化的流程。(2)上層結(jié)構(gòu)上層結(jié)構(gòu)總共5個(gè)文件:(用于USB硬件配置)、(用于USB連接、斷開操作)、(直接處理USB中斷)、(用于上層協(xié)議處理,比如HID協(xié)議,大容量存儲(chǔ)設(shè)備協(xié)議)、(具體設(shè)備的相關(guān)描述符定義和處理)。在這個(gè)頭文件中,又有以下定義:include include include include include include include 。. . . .一、USB的“JoyStickMouse”例程結(jié)構(gòu)分析例程的結(jié)構(gòu)(1)底層結(jié)構(gòu)包括5個(gè)文件:(USB總線數(shù)據(jù)處理的核心文件),(用于端點(diǎn)數(shù)據(jù)輸入輸入中斷處理),(用于緩沖區(qū)操作),(用于寄存器操作)。它們都包含了頭文件“”??梢姡琒T的USB操作庫結(jié)構(gòu)十分清晰明了,我先不準(zhǔn)備直接閱讀源代碼。設(shè)備初始化所做的工作(1)Set_System(void)這個(gè)是main函數(shù)中首先調(diào)用的函數(shù)。配置了JoyStickMouse所用到的5個(gè)按鍵,并且配置了兩個(gè)EXTI中斷,一個(gè)是用于把USB從掛起模式喚醒,還有一個(gè)用途未知。這個(gè)是main函數(shù)中調(diào)用的第二個(gè)函數(shù)。跟蹤到代碼中,主要設(shè)配置了USB低優(yōu)先級(jí)中斷和喚醒中斷,又有一個(gè)EXTI中斷功能未知。它的功能是配置和使能USB時(shí)鐘。它初始化了三個(gè)全局指針,指向DEVICE_INFO、USER_STANDARD_REQUESTS和DEVICE_PROP結(jié)構(gòu)體。void USB_Init(void){pInformation = amp。pInformationControlState = 2。Device_Property。User_Standard_Requests。}這三個(gè)結(jié)構(gòu)體都是與具體設(shè)備枚舉和功能實(shí)現(xiàn)相關(guān)的。USER_STANDARD_REQUESTS User_Standard_Requests ={Joystick_GetConfiguration,Joystick_SetConfiguration,Joystick_GetInterface,Joystick_SetInterface,Joystick_GetStatus,Joystick_ClearFeature,Joystick_SetEndPointFeature,Joystick_SetDeviceFeature,Joystick_SetDeviceAddress}。上層程序調(diào)用下次函數(shù)是常規(guī)性的操作?;卣{(diào)函數(shù)的意義在于同一種操作模式、提供不同的回調(diào)函數(shù)則可以實(shí)現(xiàn)不同的功能?;卣{(diào)函數(shù)的實(shí)現(xiàn)方法是函數(shù)指針數(shù)組。這是函數(shù)的代碼:void Joystick_init(void){/* Update the serial number string descriptor with the data from the uniqueID*/Get_SerialNum()。/* Connect the device */PowerOn()。/* USB interrupts initialization */_SetISTR(0)。_SetCNTR(wInterrupt_Mask)。}實(shí)質(zhì)上,代碼執(zhí)行到這里,開發(fā)板已經(jīng)可以響應(yīng)主機(jī)發(fā)來的數(shù)據(jù)了。(5)SysTick_Config()。進(jìn)入主循環(huán)進(jìn)入主循環(huán)的工作就兩個(gè):Joystick_Send(JoyState())。Joystick_Send(JoyState())用來把按鍵狀態(tài)發(fā)到主機(jī)。它的工作只是將數(shù)據(jù)寫入IN端點(diǎn)緩沖區(qū),主機(jī)的IN令牌包來的時(shí)候,SIE負(fù)責(zé)把它返回給主機(jī)。//從用戶復(fù)制四個(gè)字節(jié)到端點(diǎn)1緩沖區(qū),控制端點(diǎn)的輸入緩沖區(qū)。 /* enable endpoint for transmission */中斷處理過程大致理解(1)usb_istr()函數(shù)中的中斷處理簡(jiǎn)單分析有用的代碼大概以下幾段,首先是處理復(fù)位的代碼,調(diào)用設(shè)備結(jié)構(gòu)中的復(fù)位處理函數(shù)。if (wIstr amp。 wInterrupt_Mask){_SetISTR((u16)CLR_RESET)。}處理喚醒的代碼:if (wIstr amp。 wInterrupt_Mask){_SetISTR((u16)CLR_WKUP)。}處理總線掛起的代碼:if (wIstr amp。 wInterrupt_Mask){if (fSuspendEnabled) /* check if SUSPEND is possible */{Suspend()。}/* clear of the ISTR bit must be done after setting of CNTR_FSUSP */_SetISTR((u16)CLR_SUSP)。if (wIstr amp。 wInterrupt_Mask){CTR_LP()。首先在總線端(與D+、D相連的那一端),通過模擬收發(fā)器與SIE連接。與SIE相關(guān)的的有三大塊:CPU內(nèi)部控制、中斷和端點(diǎn)控制寄存器,掛起定時(shí)器(這個(gè)好像是USB協(xié)議的要求,總線在一定時(shí)間內(nèi)沒有活動(dòng),SIE模塊能夠進(jìn)入SUSPEND狀態(tài)以節(jié)約電能),還有包緩沖區(qū)接口模塊。這塊緩沖區(qū)同時(shí)受到SIE和CPU核心的控制,用于CPU與SIE共享達(dá)到數(shù)據(jù)傳輸?shù)哪康?。?dāng)然我們關(guān)注的中心點(diǎn)是控制、中斷和端點(diǎn)控制寄存器。CPU可以通過APB1總線接口來訪問這些寄存器。USB模塊的寄存器認(rèn)識(shí)(1)控制寄存器CNTR傳輸完成中斷允許位。第15位包緩沖區(qū)溢出中斷允許位錯(cuò)誤中斷允許位喚醒中斷允許位。1有效