
首先在ST官网上下载了STM32的USB开发套件 地址:http://www.st.com/stonline/products/support/micro/files/um0424.zip 由于此开发套件基于ST的官方开发板,与EK-STM32F的电路有所不同。 比较了一下,不同之处在于 1, 官方的开发套件使用PD.09作为USB识别使能线,而EK-STM32F使用PD.08。 2, 官方的开发套件通过PB.09来判断是否进入DFU模式, 而EK-STM32F的按键使用了PD.03和PD.04。 3, EK-STM32F没有接外部SPI Flash, 所以只能更新内部flash。 因此修改代码如下: void DFU_Button_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; /* Enable GPIOD clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE); /* Configure PD.04 as input floating (Key push-button on EK-STM32F) */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOD, &GPIO_InitStructure); } u8 DFU_Button_Read (void) { /* Return the value of PD.04 */ return GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_4); } void Set_System(void) { GPIO_InitTypeDef GPIO_InitStructure; FLASH_Unlock(); /* RCC system reset(for debug purpose) */ RCC_DeInit(); /* Enable HSE */ RCC_HSEConfig(RCC_HSE_ON); /* Wait till HSE is ready */ HSEStartUpStatus = RCC_WaitForHSEStartUp(); if(HSEStartUpStatus == SUCCESS) { /* Enable Prefetch Buffer */ FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); /* Flash 2 wait state */ FLASH_SetLatency(FLASH_Latency_2); /* HCLK = SYSCLK */ RCC_HCLKConfig(RCC_SYSCLK_Div1); /* PCLK2 = HCLK */ RCC_PCLK2Config(RCC_HCLK_Div1); /* PCLK1 = HCLK/2 */ RCC_PCLK1Config(RCC_HCLK_Div2); /* PLLCLK = 8MHz * 9 = 72 MHz */ RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); /* Enable PLL */ RCC_PLLCmd(ENABLE); /* Wait till PLL is ready */ while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) { } /* Select PLL as system clock source */ RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); /* Wait till PLL is used as system clock source */ while(RCC_GetSYSCLKSource() != 0x08) { } } /* Enable GPIOD clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE); /* PD.08 used as USB pull-up --> EK-STM32F */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOD, &GPIO_InitStructure); USB_Cable_Config (DISABLE); // SPI_FLASH_Init(); USB_Cable_Config (ENABLE); } void USB_Cable_Config (FunctionalState NewState) { if (NewState != DISABLE) { GPIO_ResetBits(GPIOD, GPIO_Pin_8); } else { GPIO_SetBits(GPIOD, GPIO_Pin_8); } } 修改后烧入EK-STM32F学习板,果然能识别出一个DFU设备。 /******************************************************************/ 已上传移植到EKSTM32F的USB开发套件 /******************************************************************/ 由于我用的7-zip看上去和大家的winzip不太兼容,所以下面说明,重新下载。 通过与各方沟通,发现不能正确解压缩的原因是,楼主使用的压缩软件与Windows自带的不兼容。我下载并成功解压楼主的文件包,里面有两个目录,我把他们分别做了两个压缩包,因为项目文件中有相联关系,请下载后把他们放到同一个目录下(STM32F10xUSBLib)。 自建一个STM32F10xUSBLib目录 最终目录结构应为: STM32F10xUSBLib FWLib library inc src USBLib demos Device_Firmware_Upgrade 本帖介绍的DFU演示软件 JoyStickMouse Mass_Storage Virtual_COM_Port library inc src 在ST官网下载PC端驱动和应用程序 地址:http://www.st.com/stonline/products/support/micro/files/um0412.zip 安装后运行DfuSeDemo(V2.1),在DFU Device中识别到一个STM Device in DFU Mode设备。 选择Internal Flash,选择STM32 USB开发套件的DFU DEMO中的任意image, 按下Upgrade按键。 出现一个对话框:擦除操作失败 。。。。。。 DFU的代码我曾经在ST的官方开发板上测试过,没有出过错,那么现在的错误在哪里呢? 拿了USB分析仪,看USB线上数据,发现设备总在某次的DFU_GETSTATUS请求后响应一个STALL信号,导致出错。 根据USB DFU协议(下载地址:http://www.usb.org/developers/devclass_docs/DFU_1.1.pdf), 对DFU_GETSTATUS的响应应该由:bStatus(1byte) + bwPollTimeout(3Bytes,以ms为单位) + bState(1byte) + iString(1byte)组成,但看USB线上数据,设备的响应为:00 00 00 00 04 00,显然是要求的Poll Time时间太短,导致设备在擦除flash的等待时间内无法响应PC端的又一个请求。 仔细看u8 *GETSTATUS(u16 Length)的代码: case STATE_dfuDNLOAD_SYNC: if (wlength != 0) { DeviceState = STATE_dfuDNBUSY; DeviceStatus[4] = DeviceState; if ((wBlockNum == 0) && (Load_Buffer[0] == CMD_ERASE)) { if (Pointer < 0x800000) /* 64K sectors of SPI Flash */ { DeviceStatus[1] = 0xDC; /* 1.5 seconds */ DeviceStatus[2] = 0x05; DeviceStatus[3] = 0x00; } > 8) * 2 ; /* Nb of Pages(of 256 )* 2ms */ DeviceStatus[2] = 0; DeviceStatus[3] = 0; } } else /* (wlength==0)*/ { DeviceState = STATE_dfuDNLOAD_IDLE; DeviceStatus[4] = DeviceState; DeviceStatus[1] = 0; DeviceStatus[2] = 0; DeviceStatus[3] = 0; } break; 代码在分析到当前操作为CMD_ERASE命令时,仅仅对SPI FLASH的操作定义了Poll的时间,而对内部flash的操作没有定义,因此设备直接返回了0。 察看STM32F103的Datasheet: Page(1KB)erase time 为 Min20ms, Max40ms Word programming time 为 Min20us, Max40us 修改代码如下: case STATE_dfuDNLOAD_SYNC: if (wlength != 0) { DeviceState = STATE_dfuDNBUSY; DeviceStatus[4] = DeviceState; if ((wBlockNum == 0) && (Load_Buffer[0] == CMD_ERASE)) { if (Pointer < 0x800000) /* 64K sectors of SPI Flash */ { DeviceStatus[1] = 0xDC; /* 1.5 seconds */ DeviceStatus[2] = 0x05; DeviceStatus[3] = 0x00; } else { DeviceStatus[1] = 0x28; DeviceStatus[2] = 0x00; DeviceStatus[3] = 0x00; } } else { // DeviceStatus[1] = (wlength >> 8) * 2 ; /* Nb of Pages(of 256 )* 2ms */ DeviceStatus[1] = (wlength >> 8) * 10 ; /* Nb of Pages(of 256 )* 10ms */ DeviceStatus[2] = 0; DeviceStatus[3] = 0; } } else /* (wlength==0)*/ { DeviceState = STATE_dfuDNLOAD_IDLE; DeviceStatus[4] = DeviceState; DeviceStatus[1] = 0; DeviceStatus[2] = 0; DeviceStatus[3] = 0; } break; 修改后重新烧录代码,重新执行Upgrade操作,OK。 至于原先在测试DFU代码时为何没有出错,我认为是因为我刚新换了电脑的缘故,PC跑的快了,愿意等待的时间短了。。。。。 DUF搞完,开始考虑image的生成。 PC端的应用程序除了DfuSeDemo,还有个DfuFileManage(V2.1),能将S19,HEX和BIN文件生成DFU文件。 随便找了个LCD的demo,修改lnkarm_flash.xcl文件如下: // Code memory in FLASH -DROMSTART=0x8003000 -DROMEND=0x801FFFF 修改stm32f10x_nvic.h文件对于Vector Table地址的定义如下: #define NVIC_VectTab_RAM ((u32)0x20000000) #define NVIC_VectTab_FLASH ((u32)0x08003000) 使用IAR生成raw-binary文件。 运行DFU File Manager Generation程序, 选择Mullti Bin injection,输入刚才生成的bin文件,选择地址为0x08003000, 生成OK。 运行DfuSeDemo程序,将刚才生成的DFU文件烧录到内部flash中。 按下Reset按键,LCD DEMO程序如愿跑了起来,再次按下Reset按键,同时按下KEY3,PC识别到一个DFU设备。 至此,DFU设备在EK-STM32F学习板上移植成功。 出处:vigia |
stm32哪个系列芯片支持2个USB,主设备,且usb可以支持标准的uvc协议,哪里可以下载usb开发库
新手小白,SMT32 TP Tool Windows无法安装驱动怎么处理
如何用c#使用ST25R3911DISCOComm.dll来读取和写入NDEF区的数据,需要相关例程,感谢各位大佬拯救一下我啊!????
USBx配置有哪些小的需要注意的细节?
H743ZIT6 USB虚拟串口 CDC电脑无法识别(获取描述符失败)
STM32F407的高速USB,采用的是虚拟串口方式,VCP驱动有linux系统的吗
STM32H533的USB使用问题
stlink 串口驱动安装前面有叹号软件里无法找到
STM32 usb传输的时延和丢帧问题
STM32H743+USB3300传输采集的数据前几次会丢包问题
RE:在EK-STM32F学习套件上实现了USB-DFU设备功能
回复:在EK-STM32F学习套件上实现了USB-DFU设备功能