单片机-基于stm32usb程序开发笔记_第1页
单片机-基于stm32usb程序开发笔记_第2页
单片机-基于stm32usb程序开发笔记_第3页
单片机-基于stm32usb程序开发笔记_第4页
单片机-基于stm32usb程序开发笔记_第5页
免费预览已结束,剩余61页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

去去基于STM32USB程序开发笔以前一直就有打玩USB的想法,最近时间充足于是决心打玩STM32的USB, 月,在固件、上位机驱动以及应用程序的 面终于有所突破,这期间通过网络上授寻了许多相关资料,主要来自ST提供的说确实存在许多的知识壁垒,本着开源精神,在此对STM32的USB固件程序的编写、DriverStudio+WindowsXPDDK+VC6驱动开发第一篇:需要准备的一1:STM32的参考手册,这对于设备底层USB的硬件配置以及事件驱 操作,比如CNTR、ISTR、EPnR、DADDR等等,如果你想学习USB,这个手册是必须的。的所谓的中文版的USB2.0协议不是 英文版的USB2.0协议, STM32 去去 去去去去去去 USB设备(DEVICE)从来只 触发,USB主机(HOST)掌握主动权,发送什么数据,什么时候发送,是给设备数据还是从设备Function

::ThisfunctionhandlesUSBHighPriorityorCANTX:::void{}去Function去

::ThisfunctionhandlesUSBLowPriorityorCANRX0:: :voidUSB_LP_CAN_RX0_IRQHandler(void){}相关处理。中断传输(interrupt)、控制传输(control)、大流量传输(bulk)USB_LPI()响应,大流量传输(bulk)同样可能响应USB_HPI(),同步传输(isochronous)只响应USB_HPI()。USB_HPI()函数未做任何处理,在此开源希望大家能完善与纠正错误并能共享喜悦。以下是USB_LPI()函数:////Function////////

::LowPriorityInterrupt'sservice:::去//去void{unsignedshortwValISTR=#if(CNTR_MASK&ISTR_RESET) //Resetif(wValISTR&ISTR_RESET&vwInterruptMask)去去{}#if(CNTR_MASK&ISTR_DOVR) //DMAOver/Underrunif(wValISTR&ISTR_DOVR&vwInterruptMask){}#if(CNTR_MASK&ISTR_ERR) //Errorif(wValISTR&ISTR_ERR&vwInterruptMask){}#if(CNTR_MASK&ISTR_WKUP) //Wakeupif(wValISTR&ISTR_WKUP&vwInterruptMask){去去}#if(CNTR_MASK&ISTR_SUSP) //Suspendif(wValISTR&ISTR_SUSP&vwInterruptMask){ //mustbedoneaftersettingof}#if(CNTR_MASK&ISTR_SOF) //StartOfFrameif(wValISTR&ISTR_SOF&vwInterruptMask){}#if(CNTR_MASK&ISTR_ESOF) //ExpectedStartOfFrameif(wValISTR&ISTR_ESOF&vwInterruptMask){}#if(CNTR_MASK&ISTR_CTR) //CorrectTransferif(wValISTR&ISTR_CTR&vwInterruptMask){}}////Function////////

::HighPriorityInterrupt'sservice:::去//去void{}INT_ISTR_CTR()响应一次正确的数据传输中断,故名思意,在完成一次正确的数据传输操作后,就会响应此函数。voidISTR_CTR(void);voidISTR_SOF(void);voidISTR_ESOF(void);voidISTR_DOVR(void);voidISTR_ERROR(void);voidISTR_RESET(void);voidISTR_WAKEUP(void);//CNTRmask#defineCNTR_MASK CNTR_CTRM|CNTR_WKUPM|CNTR_SUSPM|CNTR_ERRM| CNTR_SOFM|CNTR_ESOFM|CNTR_RESETM| //去//Function去////////

::ISTRResetInterruptservice:::去去//void{//Setthebuffertable//Set pointtype:ENDP0SetEPR_Type(ENDP0,//Set pointdatabufferaddress:ENDP0RXSetBuffDescTable_RXAddr(ENDP0,ENDP0_RXADDR);//Set pointdatabufferaddress:ENDP0TXSetBuffDescTable_TXCount(ENDP0,0);SetBuffDescTable_TXAddr(ENDP0,ENDP0_TXADDR);//InitializetheRX/TXstatus:ENDP0SetEPR_RXStatus(ENDP0,EP_RX_VALID);SetEPR_TXStatus(ENDP0,//Set pointaddress:ENDP0SetEPR_Address(ENDP0,ENDP0);去去//TODO:Addyoucode// pointtype:SetEPR_Type(ENDP1,//Set pointdatabufferaddress:ENDP1RXSetBuffDescTable_RXAddr(ENDP1,ENDP1_RXADDR);//Set pointdatabufferaddress:ENDP1TXSetBuffDescTable_TXCount(ENDP1,0);SetBuffDescTable_TXAddr(ENDP1,ENDP1_TXADDR);//InitializetheRX/TXstatus:ENDP1SetEPR_RXStatus(ENDP1,EP_RX_VALID);SetEPR_TXStatus(ENDP1,//Set pointaddress:ENDP1SetEPR_Address(ENDP1,ENDP1);SetEPR_Type(ENDP2,去去//Set pointdatabufferaddress:ENDP2RXSetBuffDescTable_RXAddr(ENDP2,ENDP2_RXADDR);//Set pointdatabufferaddress:ENDP2TXSetBuffDescTable_TXCount(ENDP2,0);SetBuffDescTable_TXAddr(ENDP2,ENDP2_TXADDR);//InitializetheRX/TXstatus:ENDP2SetEPR_RXStatus(ENDP2,EP_RX_DIS);SetEPR_TXStatus(ENDP2,EP_TX_VALID);//Set pointaddress:ENDP2SetEPR_Address(ENDP2,ENDP2);//EndofyouvsDeviceInfo.eDeviceState=DS_DEFAULT;vsDeviceInfo.bCurrentFeature=0x00;vsDeviceInfo.bCurrentConfiguration=0x00;vsDeviceInfo.bCurrentInterface=0x00;去去vsDeviceInfo.bCurrentAlternateSetting=vsDeviceInfo.uStatusInfo.w=}RX/TX缓冲描述表说明是数据 //USB_IPPacketMemoryAreabaseaddress#definePMAAddr(0x40006000L)//BufferTableaddress#defineBTABLE((volatileunsigned*)(RegBase+////Packetmemoryarea:Total//#define ////PMAAddr+BASEADDR_BTABLE+0x00000000://PMAAddr+BASEADDR_BTABLE+0x00000002://PMAAddr+BASEADDR_BTABLE+0x00000004://PMAAddr+BASEADDR_BTABLE+0x00000006://PMAAddr+BASEADDR_BTABLE+0x00000008://PMAAddr+BASEADDR_BTABLE+0x0000000A:去去//PMAAddr+BASEADDR_BTABLE+0x0000000C://PMAAddr+BASEADDR_BTABLE+0x0000000E://PMAAddr+BASEADDR_BTABLE+0x00000010://PMAAddr+BASEADDR_BTABLE+0x00000012://PMAAddr+BASEADDR_BTABLE+0x00000014://PMAAddr+BASEADDR_BTABLE+0x00000016://PMAAddr+BASEADDR_BTABLE+0x00000018://PMAAddr+BASEADDR_BTABLE+0x0000001A://PMAAddr+BASEADDR_BTABLE+0x0000001C://PMAAddr+BASEADDR_BTABLE+0x0000001E://PMAAddr+BASEADDR_BTABLE+0x00000020://PMAAddr+BASEADDR_BTABLE+0x00000022://PMAAddr+BASEADDR_BTABLE+0x00000024://PMAAddr+BASEADDR_BTABLE+0x00000026://PMAAddr+BASEADDR_BTABLE+0x00000028://PMAAddr+BASEADDR_BTABLE+0x0000002A://PMAAddr+BASEADDR_BTABLE+0x0000002C://PMAAddr+BASEADDR_BTABLE+0x0000002E://PMAAddr+BASEADDR_BTABLE+0x00000030://PMAAddr+BASEADDR_BTABLE+0x00000032://PMAAddr+BASEADDR_BTABLE+0x00000034://PMAAddr+BASEADDR_BTABLE+0x00000036://PMAAddr+BASEADDR_BTABLE+0x00000038://PMAAddr+BASEADDR_BTABLE+0x0000003A://PMAAddr+BASEADDR_BTABLE+0x0000003C://PMAAddr+BASEADDR_BTABLE+0x0000003E:////PMAAddr+BASEADDR_BTABLE+(0x00000040-0x000001FF):assignedtodata//#define (BASEADDR_BTABLE+//ENP0

(ENDP0_RXADDR+去去//#define #defineENDP1_RXADDR (ENDP0_TXADDR+ENDP0_PACKETSIZE)#define (ENDP1_RXADDR+//#define #define (ENDP1_TXADDR+去去+//++//++//++//++//++////Function////////

::ISTRCorrectTransferInterruptservice:::去//去void{unsigned unsignedshortwValISTR;unsignedshortwhile(((wValISTR=GetISTR())&ISTR_CTR)!=0{//Gettheindexnumber Index=wValISTR& Index=={//Setendpoint0RX/TXstatus:NAK(Negative-SetEPR_TXStatus(ENDP0,去去//Transferif((wValISTR&ISTR_DIR)=={//DIR=0://DIR=0impliesthatEP_CTR_TXalways}{//DIR=1:SETUPor//DIR=1impliesthatCTR_TXorCTR_RXalwayswValENDP=GetEPR(ENDP0);if((wValENDP&EP_CTR_TX)!=0){}elseif((wValENDP&EP_SETUP)!={去去}elseif((wValENDP&EP_CTR_RX)!={}}}//Other{wValENDP= Index,if((wValENDP&EP_CTR_TX)!={ClrEPR_CTR_TX( {caseENDP1:CTR_IN1();caseENDP2:CTR_IN2();break;caseENDP3:CTR_IN3();break;caseENDP4:CTR_IN4();break;去去caseENDP5:CTR_IN5();break;caseENDP6:CTR_IN6();break;caseENDP7:CTR_IN7();break;default:break;}}if((wValENDP&EP_CTR_RX)!={ClrEPR_CTR_RX( {caseENDP1:CTR_OUT1();caseENDP2:CTR_OUT2();break;caseENDP3:CTR_OUT3();break;caseENDP4:CTR_OUT4();break;caseENDP5:CTR_OUT5();break;caseENDP6:CTR_OUT6();break;caseENDP7:CTR_OUT7();break;default:break;}}}}}去去去去去去去去去去去去去去去去volatileDEVICE_INFO////typedefstruct_DEVICE_INFO{unsignedcharunsignedcharbCurrentFeature;unsignedcharbCurrentConfiguration;unsignedcharbCurrentInterface;

去CONTROL_STATE去 TRANSFER_INFO}typedefstruct{unsignedcharunsignedchar

//request// 去去WORD_2BYTEwValue;WORD_2BYTEwIndex;WORD_2BYTE}typedefunion{unsignedshort{unsignedcharunsignedchar}去去CTR_SETUP0()函数将SETUP数据提取出来,SETUP数据结构有0长度和非0长度的数据结构,详细参阅USB2.0 这将两种区别开来分别执行SETUP0_NoData()和SETUP0_Data()函数,并返回结果,根据返回结果再响应USB主机////FunctionName:// // // // //void{RESULTBufferCopy_PMAToUser((unsignedcharif(vsDeviceInfo.SetupData.wLength.w=={eResult=}去去{eResult=}{casecasecasecaseSetEPR_TXStatus(ENDP0,}}done"的部分表明此部分功能已完成。对于未完成部////RoutineGroups:RESULTSETUP0_Data(void){//SetupData.bRequest: {casecaseSR_GET_DESCRIPTOR:caseSR_SET_DESCRIPTOR:caseSR_GET_INTERFACE:case

returnreturnSR_GetDescriptor();returnSR_SetDescriptor();returnSR_GetInterface();returnSR_SynchFrame();

////////////去去default:return}}////RoutineGroups://RESULT{//SetupData.bRequest: {casecasecaseSR_SET_INTERFACE:

returnSR_ClearFeature();returnSR_SetFeature();returnSR_SetAddress();returnSR_SetInterface();

//////////default:return}}SetEPR_RXStatus(ENDP0,SetEPR_TXStatus(ENDP0,//去//Function去//////

::::// RESULTSETUP0_Trans0Data(void){//Send0-lengthdataframeasACKtoSetBuffDescTable_TXCount(ENDP0,0);SetEPR_RXStatus(ENDP0,EP_RX_NAK);return}////Function////////

:::::去//去RESULT{unsignedshortwLength=unsignedshortwOffset=vsDeviceInfo.TransInfo.wOffset;unsignedshortwMaxSize=vsDeviceInfo.TransInfo. {if(wLength>{wLength=}//Copythetransferbufferto point0'sbuffer

//transfer//endpoint0TX去去SetBuffDescTable_TXCount(ENDP0,wLength);SetEPR_RXStatus(ENDP0,EP_RX_NAK);SetEPR_TXStatus(ENDP0,EP_TX_VALID);//UpdatethedatalengthsvsDeviceInfo.TransInfo.wLength-=wLength;vsDeviceInfo.TransInfo.wOffset+=return}return}//////typedefstruct{unsignedshortunsignedshortwOffset;unsignedshort unsignedchar*pBuffer;}

//totallengthsdatawillbe//numberofdatabe//endpointspacketmax//addressofdata去去机将无条件退出请求;TXVALID,USBUSB设备数据。CTR_SETUP0()->SETUP0_Data()->SR_GetDescriptor()-RESULT{//RequestType:device->host,standardrequestanddeviceif(vsDeviceInfo.SetupData.bmRequestType=={//SetupData.wValue.b.MSB:descriptor//SetupData.wValue.b.LSB:descriptorindex{casecaseDESCRIPTOR_CONFIG:caseDESCRIPTOR_STRING:

returnreturnSR_GetDescriptor_Config();returnSR_GetDescriptor_String();去去default:return}}return}RESULT{//AssignedthedevicedescriptortothevsDeviceInfo.TransInfo.wOffset=0; cketSize=ENDP0_PACKETSIZE;vsDeviceInfo.TransInfo.wLength=DescBuffer_Device.wLen;vsDeviceInfo.eControlState=CS_GET_DESCRIPTOR;if(vsDeviceInfo.TransInfo.wLength>去去{vsDeviceInfo.TransInfo.wLength=}return} ////FunctionName:// // // // //void{{caseif(SETUP0_TransData()=={SetEPR_TXStatus(ENDP0,SetEPR_RXStatus(ENDP0,}去去caseCS_SET_ADDRESS:SetEPR_TXStatus(ENDP0,EP_TX_NAK);vsDeviceInfo.eDeviceState=DS_ADDRESSED;caseSetEPR_TXStatus(ENDP0,SetEPR_RXStatus(ENDP0,vsDeviceInfo.eDeviceState=DS_CONFIGURED;}}构等等,条件是你必须了解这些标准设备的一些信息,好处是省去一些麻烦的驱动编写。constunsignedcharcbDescriptor_Device[DESC_SIZE_DEVICE]{

//bLength://descriptor

//bcdUSBLSB:USBreleasenumber->//bcdUSBMSB:USBreleasenumber->

// Classinformationintheinterface//////bMaxPacketSize0:LowS(8),FullS(8,16,32,64),去去idVendorLSB:idVendoridProductidProductbcdDevicebcdDevice

//iManufacturer:Indexofstringdescriptordescribing//iProduct:Indexofstringdescriptordescribing//iSerialNumber:Indexofstringdescriptordescribingthedeviceserial

//bNumConfigurations:numberofconstunsignedcharcbDescriptor_Config[DESC_SIZE_CONFIG]{//Descriptorof

////descriptor

//Totalconfigurationdescriptorlengths//Totalconfigurationdescriptorlengths

//bNumInterfaces:Totalnumberof//bConfigurationValue:Configuration//iConfiguration:Indexofstringdescriptordescribingthe去去 //bmAttributes:bus//bit4...0 ,setto//bit//bit//bit

:Remotewakeup:Selfpower ,setto //bMaxPower:thiscurrentisusedfordetectingVbus=//Descriptorofinterface

//bInterfaceNumber:Numberof//bAlternateSetting:Alternate

//bNumEndpoints:Numberofendpointsexcept//////去去 //iInterface:Indexofstringdescriptordescribingthe//Descriptorofendpoint1OUT ////bit3...0 point//bit6...4//bit :0(OUT),

////bit1...0:Transfer 00(CONTROL),01(ISOCHRONOUS),10(BULK),//bit3...2:Synchronization 00(NoSynch),01(Asynchronous),10(Adaptive),//bit5...4:EndpointUsage 00(data),01(Feedback),10(Implicitfeedbackdataendpoint), //bit7...6 ,mustbe//packetsize//packetsize去去 //pollingintervaltime://Descriptorofendpoint2IN ////bit3...0 point//bit6...4//bit :0(OUT),

bit1...0:Transfer00(CONTROL),01(ISOCHRONOUS),10(BULK),//bit3...2//bit5...4//bit7...6

Synchronization00(NoSynch),01(Asynchronous),10(Adaptive),EndpointUsage00(data),01(Feedback),10(Implicitfeedbackdataendpoint), ,mustbe //packetsize //packetsize

//pollingintervaltime:constunsignedcharcbDescriptor_StringLangID[DESC_SIZE_STRING_LANGID]{

////bDescriptorType=String去去

//LangID//LangIDMSB:0x0409(U.S.去去constunsignedcharcbDescriptor_StringVendor[DESC_SIZE_STRING_VENDOR]{DESC_SIZE_STRING_VENDOR,// //bDescriptorType=String//String:'L',0,'a',0,'B',0,'i',0,'X',0,'i',0,'a',0,'X',0,'i',0,'a',0,'o',0,'X',0,'i',0,constunsignedcharcbDescriptor_StringProduct[DESC_SIZE_STRING_PRODUCT]{DESC_SIZE_STRING_PRODUCT,// //bDescriptorType=String//String:"STM32ezUSB-CORE'S',0,'T',0,'M',0,'3',0,'2',0,'',0,'e',0,'z',0,'U',0,'S',0,'-',0,'C',0,'O',0,'R',0,'E',0,'',0,'V',0,'1',0,'.',0,'0',0,constunsignedcharcbDescriptor_StringSerial[DESC_SIZE_STRING_SERIAL]{DESC_SIZE_STRING_SERIAL,// //bDescriptorType=String去去//String:"ezUSB-COREDemo'e',0,'z',0,'U',0,'S',0,'B',0,'-',0,'C',0,'O',0,'R',0,'E',0,''D',0,'e',0,'m',0,'o',0,'',0,'2',0,'0',0,'0',0,'8',0,'/',0,'1',0,'1',0,'/',0,'1',0, 必须的先决条件1:XPDDK(DriverDevelopmentKits),可从MS 处理稍微不当,就容易让你系统直接挂了(WINDOWS著名的蓝屏)。DDK提供了一些驱动代码,有 去去WindowsXP去去去去 去去ReadFile()/WriteFile()IRP_MJ_READ/IRP_MJ_WRITEReadFrom_EP2和WriteTo_EP1NTSTATUSezUSBDevice::ReadFrom_EP2_Handler(KIrpI);NTSTATUSezUSBDevice::WriteTo_EP1_Handler(KIrpI);去去去去 去去去去 去去VC6USBCUSBAPIUSBAPI.h#defineFILE_DEVICE_EZUSB#defineEZUSB_IOCTL(index)CTL_CODE(FILE_DEVICE_EZUSB,index,METHOD_BUFFERED,#defineReadFrom_EP2CTL_CODE(FILE_DEVICE_EZUSB,0x800,METHOD_IN_DIRECT,#defineWriteTo_EP1CTL_CODE(FILE_DEVICE_EZUSB,0x801,METHOD_OUT_DIRECT, typedefstruct{ //Indexforthisstruct_NODE_ENUDEVICEINTERFACE}去去 0xE075C5B2,0xE7FB,0x4186,0xA1,0x39,0x0B,0x3F,0xD2,0x05,0xE7, typedefstruct{HWNDh HANDLEhDevice;DWORDDWORDdwInSize;DWORDdwOutSize;LPDWORD} #define#defineCORESTATUS_READWRITE_EVENT_ERROR#defineCORESTATUS_IOCONTROL_EVENT_ERROR

#defineERROR_HANDLE_WINDOW#defineERROR_HANDLE_DEVICE#defineERROR_BUFFER_LENGTH#defineERROR_BUFFER_ISNULL#define

去去 PLETION和 PLETION通知应用程序。详细代码请参考源程序。////ClassmembersclassCUSBAPI{DWORDEnumDeviceInter

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论