移植STM32固件库用于HID双向通信



USB的应用中HID类是比较常见的方式。通过修改STM32 USB固件库V4.0的JOYSTICK应用,我们实现一个双向USB通信。
一、移植
使用STM32源程序为点亮LED灯程序。
首先将USB固件库中有用的函数复制到源函数中, 建立LIB文件夹其中放入USB2.0协议函数

STM32ymodem最新版本更新内容_描述符

建立CFG文件夹放入USB应用函数




STM32ymodem最新版本更新内容_LabVIEW_02


将两个文件夹都放到源工程目录下将文件添加进来,设置好,配置好KEIL软件设置。

二、修改文件
1、首先修改platform_config.h函数。
    该文件是对于多种芯片对于USB库的支持。我们使用STM32F103ZET6芯片,所以只保留与之相关的ID项,与USB_DISCONNECT线(PG11)的配置。修改之后的头文件如下所示

STM32ymodem最新版本更新内容_描述符_03

2、然后修改hw_config.c中Set_System函数

    实际上STM32F103zet6不需要对USB端口进行单独的配置,删掉Set_System函数中没用的部分,只对USB_DISCONNECT线(PG11)进行初始化。修改后的函数如下图所示。



STM32ymodem最新版本更新内容_STM32ymodem最新版本更新内容_04


3、接下来修改hw_config.c文件中USB_Cable_Config函数因为我使用的是比较老的神舟III开发板,当PG11为高电平时实现上拉,所以修改后的函数为


STM32ymodem最新版本更新内容_STM32ymodem最新版本更新内容_05


4、修改USB_Interrupt_Config函数,配置USB_LP_CAN1_RX0_IRQn和USBWakeUp_IRQn中断修改后的函数如下图所示。


STM32ymodem最新版本更新内容_LabVIEW_06


5、接下来删掉hw_config.c文件中GPIO_AINConfig函数,没有什么用,只会报错

6、删掉与按键相关的设置,因为我们并没有用到,主要是先清除JoyState和Joystick_Send函数中内容,不用管。

7、最后我们处理USB挂起相关的问题。在USB固件库中提供挂起相关的处理函数,主要有2个函数需要修改。它们是Suspend函数和Enter_LowPowerMode函数。其中,在Suspend函数中注释掉PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);语句。修改Suspend函数,如下图所示


STM32ymodem最新版本更新内容_STM32ymodem最新版本更新内容_07


OK接下来应该就没有什么需要修改的地方了(如果有的话请酌情修改)
三、描述符修改
使用USB HID类进行通信调试。所以要对USB的描述符要做部分修改(usb_desc.c)。下面我们贴程序说明(只对重要修改做说明)

设备描述符
修改idVendor和idProduct的值,为任意其他值,我里我用给的是0x0413和0x5724,修改的时候注意大小端

配置描述符集合


[cpp]  view plain  copy

 

    1. <span style="font-family:SimSun;font-size:10px;">const uint8_t Joystick_ConfigDescriptor[JOYSTICK_SIZ_CONFIG_DESC] =  
    2.   {  
    3. /* bLength: Configuration Descriptor size */  
    4. /* bDescriptorType: Configuration */  
    5.     JOYSTICK_SIZ_CONFIG_DESC,  
    6. /* wTotalLength: Bytes returned */  
    7.     0x00,  
    8. /*bNumInterfaces: 1 interface*/  
    9. /*bConfigurationValue: Configuration value*/  
    10. /*iConfiguration: Index of string descriptor describing
    11.                                      the configuration*/  
    12. /*bmAttributes: Self powered */  
    13. /*MaxPower 100 mA: this current is used for detecting Vbus*/  
    14.   
    15. /************** Descriptor of Joystick Mouse interface ****************/  
    16. /* 09 */  
    17. /*bLength: Interface Descriptor size*/  
    18. /*bDescriptorType: Interface descriptor type*/  
    19. /*bInterfaceNumber: Number of Interface*/  
    20. /*bAlternateSetting: Alternate setting*/  
    21. /*bNumEndpoints除端点0外,需要1输入1输出*/  
    22. /*bInterfaceClass: HID*/  
    23. /*bInterfaceSubClass : 1=BOOT, 0=no boot选择no boot*/  
    24. /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse选择none*/  
    25. /*iInterface: Index of string descriptor*/  
    26. /******************** Descriptor of Joystick Mouse HID ********************/  
    27. /* 18 */  
    28. /*bLength: HID Descriptor size*/  
    29. /*bDescriptorType: HID*/  
    30. /*bcdHID: HID Class Spec release number*/  
    31.     0x01,  
    32. /*bCountryCode: Hardware target country*/  
    33. /*bNumDescriptors: Number of HID class descriptors to follow*/  
    34. /*bDescriptorType*/  
    35. /*wItemLength: Total length of Report descriptor*/  
    36.     0x00,  
    37. /******************** Descriptor of Joystick Mouse endpoint ********************/  
    38. /* 27 */  
    39. /*bLength: Endpoint Descriptor size*/  
    40. /*bDescriptorType:*/  
    41.   
    42. /*bEndpointAddress: Endpoint Address (IN)*/  
    43. /*bmAttributes: Interrupt endpoint*/  
    44. /*wMaxPacketSize: 64 Byte max修改最大包大小为64字节 */  
    45.     0x00,  
    46. /*bInterval: Polling Interval (10 ms)修改轮询间隔为10ms*/  
    47. /******************** Descriptor of Joystick Mouse endpoint ********************/  
    48. /* 34 */  
    49. /*bLength: Endpoint Descriptor size*/  
    50. /*bDescriptorType:*/  
    51.   
    52. /*bEndpointAddress: Endpoint Address (OUT)*/  
    53. /*bmAttributes: Interrupt endpoint*/  
    54. /*wMaxPacketSize: 64 Byte max修改最大包大小为64字节 */  
    55.     0x00,  
    56. /*bInterval: Polling Interval (10 ms) 修改轮询间隔为10ms */  
    57. /*41 */  
    58. "font-family:SimSun;font-size:14px;">  
    59. </span>



    报告描述符


    [cpp]  view plain  copy

            
    1. <span style="font-family:SimSun;font-size:10px;">const uint8_t Joystick_ReportDescriptor[JOYSTICK_SIZ_REPORT_DESC] =  
    2.   {  
    3. /*Usage Page(User Define)*/  
    4. /*Usage(User Define)*/  
    5. /*Collection(application)*/  
    6. /*Usage Page(1)*/  
    7. /*Usage Minimum(0)*/  
    8. /*Usage Maximum(255)*/  
    9. /*Logical Minimum(0)*/  
    10. /*Logical Maximum(255)*/  
    11. /*Report Count(3)*/  
    12. /*Report Size(1)*/  
    13. 0x81, 0x02,          /*Input(Data,Var,Abs)*/  
    14. 0x05, 0x02          /*Usage Page(2)*/  
    15. 0x19, 0x00,          /*Usage Minimum(0)*/  
    16. /*Usage Maximum(255)*/  
    17. /*Logical Minimum(0)*/  
    18. /*Logical Maximum(255)*/  
    19. /*Report Count(64)*/  
    20. /*Report Size(8)*/  
    21. 0x91, 0x02,          /*Input(Data,Var,Abs)*/  
    22. 0xc0               /*关集合*/  
    23. /* Joystick_ReportDescriptor */</span><span style="font-family:SimSun;font-size:14px;">  
    24. </span>


    上面我们修改了数组内容,导致数组大小发生变化,所以根据变化做响应修改,在usb_desc.c中


    [cpp]  view plain  copy

            
    1. <span style="font-family:SimSun;font-size:10px;">#define JOYSTICK_SIZ_CONFIG_DESC                41  
    2. #define JOYSTICK_SIZ_REPORT_DESC                39</span>


    四、修改函数

        修改设备RESET函数Joystick_Reset,这个函数是在RESET中断中被调用,用于端口的初始化。因为我们增加了端点1的输出,修改了包大小,所以要做响应的修改。这个函数位于usb_prop.c中,修改后的函数为


    [cpp]  view plain  copy

            
    1. <span style="font-family:SimSun;font-size:10px;">void Joystick_Reset(void)  
    2. {  
    3. /* Set Joystick_DEVICE as not configured */  
    4.   pInformation->Current_Configuration = 0;  
    5. /*the default Interface*/  
    6.   
    7. /* Current Feature initialization */  
    8.   pInformation->Current_Feature = Joystick_ConfigDescriptor[7];  
    9.   SetBTABLE(BTABLE_ADDRESS);  
    10. /* Initialize Endpoint 0 */  
    11.   SetEPType(ENDP0, EP_CONTROL);  
    12.   SetEPTxStatus(ENDP0, EP_TX_STALL);  
    13.   SetEPRxAddr(ENDP0, ENDP0_RXADDR);  
    14.   SetEPTxAddr(ENDP0, ENDP0_TXADDR);  
    15.   Clear_Status_Out(ENDP0);  
    16.   SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);  
    17.   SetEPRxValid(ENDP0);  
    18.   
    19. /* Initialize Endpoint 1 */  
    20.   SetEPType(ENDP1, EP_INTERRUPT);  
    21.   SetEPTxAddr(ENDP1, ENDP1_TXADDR);  
    22. //修改大小为64  
    23.   SetEPTxStatus(ENDP1, EP_TX_NAK);  
    24.   
    25. /* Initialize Endpoint 1 */  
    26. //SetEPType(ENDP1, EP_INTERRUPT);  
    27.   SetEPTxAddr(ENDP1, ENDP1_RXADDR);  
    28. //修改大小为64  
    29.   SetEPRxStatus(ENDP1, EP_RX_VALID);  
    30. /* Set this device to response on default address */  
    31.   SetDeviceAddress(0);  
    32.   bDeviceState = ATTACHED;  
    33. }</span><span style="font-family:SimSun;font-size:14px;">  
    34. </span>

    在上面中ENDP1_RXADDR是我们新加的,需要我们在usb_conf.h中添加对于它的定义

    [cpp]  view plain  copy

     

    1. <span style="font-family:SimSun;font-size:10px;">/* EP1  */  
    2. /* tx buffer base address */  
    3. #define ENDP1_TXADDR        (0x100)  
    4. #define ENDP1_RXADDR        (0x140)</span><span style="font-family:SimSun;font-size:14px;">  
    5. </span>

    最后我们编写对于USB输出数据的处理函数,即


    [cpp]  view plain  copy

            
    1. <span style="font-family:SimSun;font-size:10px;">void EP1_OUT_Callback(void)  
    2. {  
    3. //kk是个64字节的数组  
    4.       
    5. if(kk[0]&&0x01 == 0x01)  
    6.         LED(LED1,1);  
    7. else  
    8.         LED(LED1,0);  
    9. if(kk[0]&&0x02 == 0x02)  
    10.         LED(LED2,1);  
    11. else  
    12.         LED(LED2,0);  
    13. if(kk[0]&&0x04 == 0x04)  
    14.         LED(LED3,1);  
    15. else  
    16.         LED(LED3,0);  
    17. if(kk[0]&&0x08 == 0x08)  
    18.         LED(LED4,1);  
    19. else  
    20.         LED(LED4,0);     
    21.     SetEPRxValid(ENDP1);  
    22. }</span><span style="font-family:SimSun;font-size:14px;">  
    23. </span>


    在主函数中我们添加USB IN的相关操作,因为设置的是interrupt端点,所以每过10ms主机就是问询设备是否有数据要发送,我们只需要在stm32的主函数中填装数据即可。具体的while循环中代码是


    [cpp]  view plain  copy

            
    1. <span style="font-family:SimSun;font-size:10px;">if(GetEPTxStatus(ENDP1)==EP_TX_NAK)  
    2. {  
    3. if(DataLen !=0)  
    4.     {  
    5.         USB_SIL_Write(ENDP1,kk,DataLen);                
    6.         SetEPTxValid(ENDP1);  
    7.         DataLen=0;  
    8.     }                 
    9. }</span><span style="font-family:SimSun;font-size:14px;">  
    10. </span>

    最后的最后不要忘了在stm32f10x_it.c中添加中断处理


    [cpp]  view plain  copy

     

    1. <span style="font-family:SimSun;font-size:10px;">void USB_LP_CAN1_RX0_IRQHandler(void)  
    2. {  
    3.   USB_Istr();  
    4. }    
    5. void USBWakeUp_IRQHandler(void)  
    6. {  
    7.    EXTI_ClearITPendingBit(EXTI_Line18);  
    8. }</span><span style="font-family:SimSun;font-size:14px;">  
    9. </span>


    至此整个移植过程就完成了,程序实现的功能是,通过电脑给USB设备发送数据,USB设备收到数据,然后再把数据发送回电脑,为了检验USB的发送与接收,使用Labview编写了一个简单的上位机。大概就是这个样子,发送哈哈,收到哈哈。

    STM32ymodem最新版本更新内容_描述符_08


    关于上位机就在下一篇博文里写吧



    USB的应用中HID类是比较常见的方式。通过修改STM32 USB固件库V4.0的JOYSTICK应用,我们实现一个双向USB通信。

    一、移植

    使用STM32源程序为点亮LED灯程序。

    首先将USB固件库中有用的函数复制到源函数中, 建立LIB文件夹其中放入USB2.0协议函数

    STM32ymodem最新版本更新内容_描述符

    建立CFG文件夹放入USB应用函数


    STM32ymodem最新版本更新内容_LabVIEW_02


    将两个文件夹都放到源工程目录下将文件添加进来,设置好,配置好KEIL软件设置。

    二、修改文件
    1、首先修改platform_config.h函数。
        该文件是对于多种芯片对于USB库的支持。我们使用STM32F103ZET6芯片,所以只保留与之相关的ID项,与USB_DISCONNECT线(PG11)的配置。修改之后的头文件如下所示

    STM32ymodem最新版本更新内容_描述符_03

    2、然后修改hw_config.c中Set_System函数

        实际上STM32F103zet6不需要对USB端口进行单独的配置,删掉Set_System函数中没用的部分,只对USB_DISCONNECT线(PG11)进行初始化。修改后的函数如下图所示。


    STM32ymodem最新版本更新内容_STM32ymodem最新版本更新内容_04


    3、接下来修改hw_config.c文件中USB_Cable_Config函数因为我使用的是比较老的神舟III开发板,当PG11为高电平时实现上拉,所以修改后的函数为


    STM32ymodem最新版本更新内容_STM32ymodem最新版本更新内容_05


    4、修改USB_Interrupt_Config函数,配置USB_LP_CAN1_RX0_IRQn和USBWakeUp_IRQn中断修改后的函数如下图所示。


    STM32ymodem最新版本更新内容_LabVIEW_06


    5、接下来删掉hw_config.c文件中GPIO_AINConfig函数,没有什么用,只会报错

    6、删掉与按键相关的设置,因为我们并没有用到,主要是先清除JoyState和Joystick_Send函数中内容,不用管。

    7、最后我们处理USB挂起相关的问题。在USB固件库中提供挂起相关的处理函数,主要有2个函数需要修改。它们是Suspend函数和Enter_LowPowerMode函数。其中,在Suspend函数中注释掉PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);语句。修改Suspend函数,如下图所示


    STM32ymodem最新版本更新内容_STM32ymodem最新版本更新内容_07


    OK接下来应该就没有什么需要修改的地方了(如果有的话请酌情修改)
    三、描述符修改
    使用USB HID类进行通信调试。所以要对USB的描述符要做部分修改(usb_desc.c)。下面我们贴程序说明(只对重要修改做说明)

    设备描述符
    修改idVendor和idProduct的值,为任意其他值,我里我用给的是0x0413和0x5724,修改的时候注意大小端

    配置描述符集合


    [cpp]  view plain  copy

     

       
    1. <span style="font-family:SimSun;font-size:10px;">const uint8_t Joystick_ConfigDescriptor[JOYSTICK_SIZ_CONFIG_DESC] =  
    2.   {  
    3. /* bLength: Configuration Descriptor size */  
    4. /* bDescriptorType: Configuration */  
    5.     JOYSTICK_SIZ_CONFIG_DESC,  
    6. /* wTotalLength: Bytes returned */  
    7.     0x00,  
    8. /*bNumInterfaces: 1 interface*/  
    9. /*bConfigurationValue: Configuration value*/  
    10. /*iConfiguration: Index of string descriptor describing
    11.                                      the configuration*/  
    12. /*bmAttributes: Self powered */  
    13. /*MaxPower 100 mA: this current is used for detecting Vbus*/  
    14.   
    15. /************** Descriptor of Joystick Mouse interface ****************/  
    16. /* 09 */  
    17. /*bLength: Interface Descriptor size*/  
    18. /*bDescriptorType: Interface descriptor type*/  
    19. /*bInterfaceNumber: Number of Interface*/  
    20. /*bAlternateSetting: Alternate setting*/  
    21. /*bNumEndpoints除端点0外,需要1输入1输出*/  
    22. /*bInterfaceClass: HID*/  
    23. /*bInterfaceSubClass : 1=BOOT, 0=no boot选择no boot*/  
    24. /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse选择none*/  
    25. /*iInterface: Index of string descriptor*/  
    26. /******************** Descriptor of Joystick Mouse HID ********************/  
    27. /* 18 */  
    28. /*bLength: HID Descriptor size*/  
    29. /*bDescriptorType: HID*/  
    30. /*bcdHID: HID Class Spec release number*/  
    31.     0x01,  
    32. /*bCountryCode: Hardware target country*/  
    33. /*bNumDescriptors: Number of HID class descriptors to follow*/  
    34. /*bDescriptorType*/  
    35. /*wItemLength: Total length of Report descriptor*/  
    36.     0x00,  
    37. /******************** Descriptor of Joystick Mouse endpoint ********************/  
    38. /* 27 */  
    39. /*bLength: Endpoint Descriptor size*/  
    40. /*bDescriptorType:*/  
    41.   
    42. /*bEndpointAddress: Endpoint Address (IN)*/  
    43. /*bmAttributes: Interrupt endpoint*/  
    44. /*wMaxPacketSize: 64 Byte max修改最大包大小为64字节 */  
    45.     0x00,  
    46. /*bInterval: Polling Interval (10 ms)修改轮询间隔为10ms*/  
    47. /******************** Descriptor of Joystick Mouse endpoint ********************/  
    48. /* 34 */  
    49. /*bLength: Endpoint Descriptor size*/  
    50. /*bDescriptorType:*/  
    51.   
    52. /*bEndpointAddress: Endpoint Address (OUT)*/  
    53. /*bmAttributes: Interrupt endpoint*/  
    54. /*wMaxPacketSize: 64 Byte max修改最大包大小为64字节 */  
    55.     0x00,  
    56. /*bInterval: Polling Interval (10 ms) 修改轮询间隔为10ms */  
    57. /*41 */  
    58. "font-family:SimSun;font-size:14px;">  
    59. </span>


    报告描述符


    [cpp]  view plain  copy

            
    1. <span style="font-family:SimSun;font-size:10px;">const uint8_t Joystick_ReportDescriptor[JOYSTICK_SIZ_REPORT_DESC] =  
    2.   {  
    3. /*Usage Page(User Define)*/  
    4. /*Usage(User Define)*/  
    5. /*Collection(application)*/  
    6. /*Usage Page(1)*/  
    7. /*Usage Minimum(0)*/  
    8. /*Usage Maximum(255)*/  
    9. /*Logical Minimum(0)*/  
    10. /*Logical Maximum(255)*/  
    11. /*Report Count(3)*/  
    12. /*Report Size(1)*/  
    13. 0x81, 0x02,          /*Input(Data,Var,Abs)*/  
    14. 0x05, 0x02          /*Usage Page(2)*/  
    15. 0x19, 0x00,          /*Usage Minimum(0)*/  
    16. /*Usage Maximum(255)*/  
    17. /*Logical Minimum(0)*/  
    18. /*Logical Maximum(255)*/  
    19. /*Report Count(64)*/  
    20. /*Report Size(8)*/  
    21. 0x91, 0x02,          /*Input(Data,Var,Abs)*/  
    22. 0xc0               /*关集合*/  
    23. /* Joystick_ReportDescriptor */</span><span style="font-family:SimSun;font-size:14px;">  
    24. </span>

    上面我们修改了数组内容,导致数组大小发生变化,所以根据变化做响应修改,在usb_desc.c中


    [cpp]  view plain  copy

     

      1. <span style="font-family:SimSun;font-size:10px;">#define JOYSTICK_SIZ_CONFIG_DESC                41  
      2. #define JOYSTICK_SIZ_REPORT_DESC                39</span>


      四、修改函数

          修改设备RESET函数Joystick_Reset,这个函数是在RESET中断中被调用,用于端口的初始化。因为我们增加了端点1的输出,修改了包大小,所以要做响应的修改。这个函数位于usb_prop.c中,修改后的函数为


      [cpp]  view plain  copy

       

      1. <span style="font-family:SimSun;font-size:10px;">void Joystick_Reset(void)  
      2. {  
      3. /* Set Joystick_DEVICE as not configured */  
      4.   pInformation->Current_Configuration = 0;  
      5. /*the default Interface*/  
      6.   
      7. /* Current Feature initialization */  
      8.   pInformation->Current_Feature = Joystick_ConfigDescriptor[7];  
      9.   SetBTABLE(BTABLE_ADDRESS);  
      10. /* Initialize Endpoint 0 */  
      11.   SetEPType(ENDP0, EP_CONTROL);  
      12.   SetEPTxStatus(ENDP0, EP_TX_STALL);  
      13.   SetEPRxAddr(ENDP0, ENDP0_RXADDR);  
      14.   SetEPTxAddr(ENDP0, ENDP0_TXADDR);  
      15.   Clear_Status_Out(ENDP0);  
      16.   SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);  
      17.   SetEPRxValid(ENDP0);  
      18.   
      19. /* Initialize Endpoint 1 */  
      20.   SetEPType(ENDP1, EP_INTERRUPT);  
      21.   SetEPTxAddr(ENDP1, ENDP1_TXADDR);  
      22. //修改大小为64  
      23.   SetEPTxStatus(ENDP1, EP_TX_NAK);  
      24.   
      25. /* Initialize Endpoint 1 */  
      26. //SetEPType(ENDP1, EP_INTERRUPT);  
      27.   SetEPTxAddr(ENDP1, ENDP1_RXADDR);  
      28. //修改大小为64  
      29.   SetEPRxStatus(ENDP1, EP_RX_VALID);  
      30. /* Set this device to response on default address */  
      31.   SetDeviceAddress(0);  
      32.   bDeviceState = ATTACHED;  
      33. }</span><span style="font-family:SimSun;font-size:14px;">  
      34. </span>

      在上面中ENDP1_RXADDR是我们新加的,需要我们在usb_conf.h中添加对于它的定义

      [cpp]  view plain  copy

              
      1. <span style="font-family:SimSun;font-size:10px;">/* EP1  */  
      2. /* tx buffer base address */  
      3. #define ENDP1_TXADDR        (0x100)  
      4. #define ENDP1_RXADDR        (0x140)</span><span style="font-family:SimSun;font-size:14px;">  
      5. </span>

      最后我们编写对于USB输出数据的处理函数,即


      [cpp]  view plain  copy

       

        1. <span style="font-family:SimSun;font-size:10px;">void EP1_OUT_Callback(void)  
        2. {  
        3. //kk是个64字节的数组  
        4.       
        5. if(kk[0]&&0x01 == 0x01)  
        6.         LED(LED1,1);  
        7. else  
        8.         LED(LED1,0);  
        9. if(kk[0]&&0x02 == 0x02)  
        10.         LED(LED2,1);  
        11. else  
        12.         LED(LED2,0);  
        13. if(kk[0]&&0x04 == 0x04)  
        14.         LED(LED3,1);  
        15. else  
        16.         LED(LED3,0);  
        17. if(kk[0]&&0x08 == 0x08)  
        18.         LED(LED4,1);  
        19. else  
        20.         LED(LED4,0);     
        21.     SetEPRxValid(ENDP1);  
        22. }</span><span style="font-family:SimSun;font-size:14px;">  
        23. </span>


        在主函数中我们添加USB IN的相关操作,因为设置的是interrupt端点,所以每过10ms主机就是问询设备是否有数据要发送,我们只需要在stm32的主函数中填装数据即可。具体的while循环中代码是


        [cpp]  view plain  copy

                
        1. <span style="font-family:SimSun;font-size:10px;">if(GetEPTxStatus(ENDP1)==EP_TX_NAK)  
        2. {  
        3. if(DataLen !=0)  
        4.     {  
        5.         USB_SIL_Write(ENDP1,kk,DataLen);                
        6.         SetEPTxValid(ENDP1);  
        7.         DataLen=0;  
        8.     }                 
        9. }</span><span style="font-family:SimSun;font-size:14px;">  
        10. </span>

        最后的最后不要忘了在stm32f10x_it.c中添加中断处理


        [cpp]  view plain  copy

         

                
        1. <span style="font-family:SimSun;font-size:10px;">void USB_LP_CAN1_RX0_IRQHandler(void)  
        2. {  
        3.   USB_Istr();  
        4. }    
        5. void USBWakeUp_IRQHandler(void)  
        6. {  
        7.    EXTI_ClearITPendingBit(EXTI_Line18);  
        8. }</span><span style="font-family:SimSun;font-size:14px;">  
        9. </span>

        至此整个移植过程就完成了,程序实现的功能是,通过电脑给USB设备发送数据,USB设备收到数据,然后再把数据发送回电脑,为了检验USB的发送与接收,使用Labview编写了一个简单的上位机。大概就是这个样子,发送哈哈,收到哈哈。

        STM32ymodem最新版本更新内容_描述符_08


        关于上位机就在下一篇博文里写吧