原创 STM32 USB 上位机驱动和应用简单图例

2010-10-13 20:00 11603 13 14 分类: MCU/ 嵌入式

STM32 USB 上位机驱动和应用简单图例


新近项目需要,简单研究下STM32 USB的应用,power avr的开发板,CPU是stm32103rbt6。


Firmware我就不说了,stm的usb开发包有例子,直接在框架的基础上修改。这里以图片的形式讨论上位机的驱动和应用程序的简单过程。


1.开发环境的配置可以搜索下先辈的经验,我用的是winddk2600+driverstudio3.2+vc6。


2.打开driverstudio的开始菜单ddk build setting然后launch program启动开发环境。


19b2f61f-3ecd-4443-bd9a-f43265710ea4.jpg


3.开始driverwizard。


d8d6eb6d-6104-45c4-9662-40c9d1bb75f4.jpg


4.然后顺序完成以下12项设置。


08309769-c28b-4099-9065-75b67df5ede3.jpg


3d4e8086-499c-4d81-81c6-75af1c591b16.jpg


be5cba28-64b9-4504-8a91-5921e406f380.jpg


dde2ea5b-8f00-4a07-acf6-546d8d8a86b5.jpg


4fbfcb92-b7d9-4ac2-808a-42cccc65aa9e.jpg


d5725eab-b115-43b7-9493-2cb6a42e9284.jpg


5c040dc1-336c-433e-b5b5-71cf98471793.jpg


235eee07-a7d1-4c21-b011-ede175e701b1.jpg


1872bc50-a0fb-4033-8c06-23725343806b.jpg


5.然后会在vc插入ds自动生成的框架。包括驱动和app。


f9a16a3e-266f-48bd-9897-54ba90bf4073.jpg


6.驱动需要修改的有两个地方:


1)是bug,10进制改成16进制;


7695ba86-d54b-404a-84f6-9106f74bb692.jpg


2)是读写read,write或者iocontrol函数。根据需要,注意读写的方式,有的是直接IO,有的是


buffer IO,还有其他的类型,这些的区别建议阅读有关windows驱动的书籍。另外这里的读写函数


是同步的,用linux的话是阻塞类型,所以没有用到完成例程或者异步的机制,需要的话也请参考有关


书籍。


///////////////////////////////////////////////////////////////////////////////////////////////////
//  USB_DemoDevice::Read
//  Dispatch routine for IRP_MJ_READ requests. 
//
// Arguments:
//  IN I
//   the read IRP
//
// Return Value:
//  NTSTATUS
//
NTSTATUS USB_DemoDevice::Read(KIrp I)
{
 T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);


 NTSTATUS status = STATUS_SUCCESS;


 // TODO: Validate the parameters of the IRP.  Replace "FALSE"
 //   in the following line with error checking code that
 //   evaulates to TRUE if the request is not valid.
 if (FALSE)
 {
  status = STATUS_INVALID_PARAMETER;
  I.Information() = 0;
  I.PnpComplete(status);


  T.Trace(TraceWarning, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);


  return status;
 }


 // Always ok to read 0 elements
 if (I.ReadSize() == 0)
 {
  I.Information() = 0;
  I.PnpComplete(this, status);


  T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);


  return status;
 }


 KMemory Mem(I.Mdl()); // Declare a memory object


 // Get a pointer to the caller's buffer.  Note that this
 // routine is safe on all platforms.
 PUCHAR pBuffer = (PUCHAR) Mem.MapToSystemSpace();
 ULONG readSize = I.ReadSize();
 ULONG bytesRead = 0;


 // TODO: At this point, perform any processing for IRP_MJ_READ
 //   To satisfy the read now, transfer data from the driver
 //   to the caller's buffer at "pBuffer".  Then, indicate
 //   how much data was transferred:
 PURB pUrb = EP2_IN.BuildInterruptTransfer(
             pBuffer,
             readSize,
             TRUE,
             NULL,
             NULL,
             TRUE);
 if (pUrb == NULL)
 {
  status = STATUS_INSUFFICIENT_RESOURCES;
 }
 else
 {
  status = EP2_IN.SubmitUrb(pUrb,NULL,NULL,0);//100MS
  bytesRead = pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;//pUrb->UrbInterruptTransfer.TransferBufferLength;
  delete pUrb;
 }


 I.Information() = bytesRead;



 I.PnpComplete(this, status);


 T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);


 return status;
}


///////////////////////////////////////////////////////////////////////////////////////////////////
//  USB_DemoDevice::Write
//  Dispatch routine for IRP_MJ_WRITE requests. 
//
// Arguments:
//  IN I
//   the write IRP
//
// Return Value:
//  NTSTATUS
//
NTSTATUS USB_DemoDevice::Write(KIrp I)
{
 T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);


 NTSTATUS status = STATUS_SUCCESS;


 // TODO: Validate the parameters of the IRP.  Replace "FALSE"
 //   in the following line with error checking code that
 //   evaulates to TRUE if the request is not valid.
 if (FALSE)
 {
  status = STATUS_INVALID_PARAMETER;
  I.Information() = 0;
  I.PnpComplete(status);


  T.Trace(TraceWarning, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);


  return status;
 }


 // Always ok to write 0 elements
 if (I.WriteSize() == 0)
 {
  I.Information() = 0;
  I.PnpComplete(this, status);


  T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);


  return status;
 }


 KMemory Mem(I.Mdl()); // Declare a memory object


 // Get a pointer to the caller's buffer.  Note that this
 // routine is safe on all platforms.
 PUCHAR pBuffer = (PUCHAR) Mem.MapToSystemSpace();
 ULONG writeSize = I.WriteSize();
 ULONG bytesSent = 0;
 // TODO: At this point, perform any processing for IRP_MJ_WRITE
 //   To satisfy the write now, transfer data to the driver
 //   from the caller's buffer at "pBuffer".  Then, indicate
 //   how much data was transferred:
 PURB pUrb = EP1_OUT.BuildInterruptTransfer(
             pBuffer,
             writeSize,
             TRUE,
             NULL,
             NULL,
             FALSE);
 if (pUrb == NULL)
 {
  status = STATUS_INSUFFICIENT_RESOURCES;
 }
 else
 {
  status = EP1_OUT_Out.SubmitUrb(pUrb,NULL,NULL,0);
  bytesSent = pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;//pUrb->UrbInterruptTransfer.TransferBufferLength;
  delete pUrb;
 }


 I.Information() = bytesSent;


 I.PnpComplete(this, status);


 T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);


 return status;
}


7.然后build with build exe,生成驱动的sys和inf,以及app的exe测试程序。


29bbc643-0d8c-4a54-8854-df47ad134a1f.jpg


8.插入硬件,stm32的开发板,系统提示安装驱动。


3ee0dcb2-b8c4-4021-950a-09b46943a0e7.jpg


9.选择手动安装,指定路径。


5907cfcb-47f3-4005-aca1-f5dbdf9202ed.jpg


10.安装成功


aa72ba6d-0f25-491f-9d18-54762ce33e9a.jpg


11.打开bus hound测试下。


1c28be5f-afac-46e0-9a6c-7335453c0b2b.jpg


12.选择端点1写入GOOG,bus hound会捕捉到写入的请求和数据。


b97f4d9f-6b21-40d1-8eda-5861c778e623.jpg


13.选择端点2读入4字节数据。


5a3c29b5-0ff5-44f3-b644-cc7a8aac35a4.jpg


14.好,现在打开driverstudio生成的测试应用程序,写入4字节数据。


f96b2786-de03-4a25-bd57-f81b1b909fe8.jpg


 


15.


下面是简单的应用,开发板上的两个按键和两个LED,读取按键的状态,控制LED的亮灭。


621efaf5-6214-4f1c-8cef-e07030e07a5d.jpg


8df12498-8cbb-4f8b-95d2-6b7a59ecafdb.JPG


 


很简单吧?!

文章评论1条评论)

登录后参与讨论

用户958884 2012-8-25 13:56

图片怎么下载不了啊,关于STM32 USB的问题困扰着很多人啊!如何与上位机VB通信和HMI通信
相关推荐阅读
用户1620250 2013-06-14 21:21
CIMCOEdit5自动生成轮廓的G代码
做了台全自动的NC数控玻璃切割机,感觉就是一台CNC的雏形了。     不管是哪一类的机床,只要是 NC 加工,零件的加工步骤如下: 1. 分析研究零件图; 2. 选择最合适...
用户1620250 2012-12-30 22:38
STM32 FSMC与FPGA 存储器接口 读写
  STM32 FSMC与FPGA 存储器接口 读写  panasonic.lin@163.com FPG...
用户1620250 2012-01-12 21:33
DSP/BIOS:Cannot create/delete a Clock from Hwi or Swi thread
DSP/BIOS:Cannot create/delete a Clock from Hwi or Swi thread 上篇文章提到Task_sleep睡死的问题解决后,添加了系统心跳cloc...
用户1620250 2012-01-12 21:28
DSP/BIOS:Task_sleep睡死的问题
程序其中的一个任务调用了Task_sleep(100),结果睡死在里面,用ROV查看任务的状态,Blocked阻塞,但是阻塞点是Unknown. 这是因为没有添加clock模块到系统...
用户1620250 2011-12-23 00:55
TI DSP 28335 CCSV4 外置SRAM调试(二)
11.为再次确保万无一失,往外置SRAM读写校验一下   12由于板子设置了从FLASH boot,FLASH内还有程序,debug 在LOAD了程序后自动复位然后运行了flash的...
用户1620250 2011-12-23 00:38
TI DSP 28335 CCSV4 外置SRAM调试(一)
DSP28335有内置256K X 16的FLASH,34K X 16的RAM,但是如果运行一个大一点的系统,如SYS/BIOS,这么小的RAM很难容纳的下,如果在FLASH中调试的话,每次都烧写...
我要评论
1
13
关闭 站长推荐上一条 /2 下一条