你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

关于F4的 USB虚拟串口

[复制链接]
JQChirs 提问时间:2018-9-19 11:25 /
在F407上调试成功的虚拟串口程序,在F446上跑不起来!问题就是不能识别驱动,446上面D+上面都没有高电平出现(F4内部是集成1.5K上拉电阻的)。
我使用的是标准外设库,USB外设库是USB_HOST-Device_LibV2.1和V2.2。很多网友说用CubeMX一配置就配置出来,是的没错,我也试了。证明了我的硬件是OK的!
但是我已经用标准外设库把整个工程写了百分之九十,如果就是因为虚拟串口驱动装不上去,换成HAL库那就太耽误项目进度了!
贴代码分析原因吧。
如下为主函数。
  1. USB_OTG_CORE_HANDLE  USB_OTG_dev;

  2. int main(void)
  3. {
  4.   SystemInit();

  5.   USBD_Init(&USB_OTG_dev,
  6.             USB_OTG_FS_CORE_ID,
  7.             &USR_desc,
  8.             &USBD_CDC_cb,
  9.             &USR_cb);
  10.   
  11.   while(1)
  12.   {
  13.    
  14.   }

  15. }
复制代码
       宏是这么定义的!        STM32F40_41xxx
        USE_USB_OTG_FS  如果要换成F446的话直接改成STM32F446xx。
        对于两个不同的宏,预编译就只能在SystemInit();里面了。
        先看时钟配置吧!

  1. #if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F469_479xx)
  2. /* #define DATA_IN_ExtSRAM */
  3. #endif /* STM32F40_41xxx || STM32F427_437x || STM32F429_439xx || STM32F469_479xx */

  4. #if defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F446xx) || defined(STM32F469_479xx)
  5. /* #define DATA_IN_ExtSDRAM */
  6. #endif /* STM32F427_437x || STM32F429_439xx || STM32F446xx || STM32F469_479xx */

  7. #if defined(STM32F410xx) || defined(STM32F411xE)
  8. /*!< Uncomment the following line if you need to clock the STM32F410xx/STM32F411xE by HSE Bypass
  9.      through STLINK MCO pin of STM32F103 microcontroller. The frequency cannot be changed
  10.      and is fixed at 8 MHz.
  11.      Hardware configuration needed for Nucleo Board:
  12.      ?SB54, SB55 OFF
  13.      ?R35 removed
  14.      ?SB16, SB50 ON */
  15. /* #define USE_HSE_BYPASS */

  16. #if defined(USE_HSE_BYPASS)     
  17. #define HSE_BYPASS_INPUT_FREQUENCY   8000000
  18. #endif /* USE_HSE_BYPASS */   
  19. #endif /* STM32F410xx || STM32F411xE */
  20.    
  21. /*!< Uncomment the following line if you need to relocate your vector Table in
  22.      Internal SRAM. */
  23. /* #define VECT_TAB_SRAM */
  24. #define VECT_TAB_OFFSET  0x00 /*!< Vector Table base offset field.
  25.                                    This value must be a multiple of 0x200. */
  26. /******************************************************************************/

  27. /************************* PLL Parameters *************************************/
  28. #if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F401xx) || defined(STM32F469_479xx)
  29. /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */
  30. #define PLL_M      8
  31. #elif defined(STM32F412xG) || defined (STM32F446xx)
  32. #define PLL_M      8
  33. #elif defined (STM32F410xx) || defined (STM32F411xE)
  34. #if defined(USE_HSE_BYPASS)
  35.   #define PLL_M      8   
  36. #else /* !USE_HSE_BYPASS */
  37.   #define PLL_M      8
  38. #endif /* USE_HSE_BYPASS */
  39. #else
  40. #endif /* STM32F40_41xxx || STM32F427_437xx || STM32F429_439xx || STM32F401xx || STM32F469_479xx */  

  41. /* USB OTG FS, SDIO and RNG Clock =  PLL_VCO / PLLQ */
  42. #define PLL_Q      7

  43. #if defined(STM32F446xx)
  44. /* PLL division factor for I2S, SAI, SYSTEM and SPDIF: Clock =  PLL_VCO / PLLR */
  45. #define PLL_R      7
  46. #elif defined(STM32F412xG)
  47. #define PLL_R      2
  48. #else
  49. #endif /* STM32F446xx */

  50. #if defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F446xx) || defined(STM32F469_479xx)
  51. #define PLL_N 336
  52. //#define PLL_N 360
  53. /* SYSCLK = PLL_VCO / PLL_P */
  54. #define PLL_P      2
  55. #endif /* STM32F427_437x || STM32F429_439xx || STM32F446xx || STM32F469_479xx */

  56. #if defined (STM32F40_41xxx)
  57. #define PLL_N  336
  58. /* SYSCLK = PLL_VCO / PLL_P */
  59. #define PLL_P      2
  60. #endif /* STM32F40_41xxx */

  61. #if defined(STM32F401xx)
  62. #define PLL_N      336
  63. /* SYSCLK = PLL_VCO / PLL_P */
  64. #define PLL_P      4
  65. #endif /* STM32F401xx */

  66. #if defined(STM32F410xx) || defined(STM32F411xE) || defined(STM32F412xG)
  67. #define PLL_N      400
  68. /* SYSCLK = PLL_VCO / PLL_P */
  69. #define PLL_P      4   
  70. #endif /* STM32F410xx || STM32F411xE */

  71. /******************************************************************************/
复制代码
再看SystemInit();函数
  1.   /* FPU settings ------------------------------------------------------------*/
  2.   #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
  3.     SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
  4.   #endif
  5.   /* Reset the RCC clock configuration to the default reset state ------------*/
  6.   /* Set HSION bit */
  7.   RCC->CR |= (uint32_t)0x00000001;

  8.   /* Reset CFGR register */
  9.   RCC->CFGR = 0x00000000;

  10.   /* Reset HSEON, CSSON and PLLON bits */
  11.   RCC->CR &= (uint32_t)0xFEF6FFFF;

  12.   /* Reset PLLCFGR register */
  13.   RCC->PLLCFGR = 0x24003010;

  14.   /* Reset HSEBYP bit */
  15.   RCC->CR &= (uint32_t)0xFFFBFFFF;

  16.   /* Disable all interrupts */
  17.   RCC->CIR = 0x00000000;

  18. #if defined(DATA_IN_ExtSRAM) || defined(DATA_IN_ExtSDRAM)
  19.   SystemInit_ExtMemCtl();
  20. #endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
  21.          
  22.   /* Configure the System clock source, PLL Multiplier and Divider factors,
  23.      AHB/APBx prescalers and Flash settings ----------------------------------*/
  24.   SetSysClock();

  25.   /* Configure the Vector Table location add offset address ------------------*/
  26. #ifdef VECT_TAB_SRAM
  27.   SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
  28. #else
  29.   SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
  30. #endif
  31. }
复制代码
    再看SetSysClock();
  1. static void SetSysClock(void)
  2. {
  3. /******************************************************************************/
  4. /*            PLL (clocked by HSE) used as System clock source                */
  5. /******************************************************************************/
  6.   __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  7.   
  8.   /* Enable HSE */
  9.   RCC->CR |= ((uint32_t)RCC_CR_HSEON);

  10.   /* Wait till HSE is ready and if Time out is reached exit */
  11.   do
  12.   {
  13.     HSEStatus = RCC->CR & RCC_CR_HSERDY;
  14.     StartUpCounter++;
  15.   } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));

  16.   if ((RCC->CR & RCC_CR_HSERDY) != RESET)
  17.   {
  18.     HSEStatus = (uint32_t)0x01;
  19.   }
  20.   else
  21.   {
  22.     HSEStatus = (uint32_t)0x00;
  23.   }

  24.   if (HSEStatus == (uint32_t)0x01)
  25.   {
  26.     /* Select regulator voltage output Scale 1 mode */
  27.     RCC->APB1ENR |= RCC_APB1ENR_PWREN;
  28.     PWR->CR |= PWR_CR_VOS;

  29.     /* HCLK = SYSCLK / 1*/
  30.     RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
  31.    
  32.     /* PCLK2 = HCLK / 2*/
  33.     RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;   
  34.    
  35.     /* PCLK1 = HCLK / 4*/
  36.     RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;     //到这里没有区别


  37. #if defined(STM32F40_41xxx) || defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F401xx) || defined(STM32F469_479xx)   
  38.     /* Configure the main PLL */
  39.     RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
  40.                    (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);
  41. #endif /* STM32F40_41xxx || STM32F401xx || STM32F427_437x || STM32F429_439xx || STM32F469_479xx */

  42. #if  defined(STM32F412xG) || defined(STM32F446xx)
  43.     /* Configure the main PLL */
  44.     RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
  45.                    (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24) | (PLL_R << 28);  //这里不过是PLL_R给I2S使用
  46.    
  47. #endif /* STM32F412xG || STM32F446xx */   
  48.    
  49.     /* Enable the main PLL */
  50.     RCC->CR |= RCC_CR_PLLON; //把主PLL开启,那么给USB的第二个PLL的相关配置在哪
  51.     //答:主PLL出来时钟之后,直接去配置Q就出来给USB_OTG_FS使用,并不存在开启第二个PLL。
  52.     /* Wait till the main PLL is ready */
  53.     while((RCC->CR & RCC_CR_PLLRDY) == 0)
  54.     {
  55.     }
  56.    
  57. #if defined(STM32F427_437xx) || defined(STM32F429_439xx) || defined(STM32F446xx) || defined(STM32F469_479xx)
  58.     /* Enable the Over-drive to extend the clock frequency to 180 Mhz */
  59.     PWR->CR |= PWR_CR_ODEN;
  60.     while((PWR->CSR & PWR_CSR_ODRDY) == 0)
  61.     {
  62.     }
  63.     PWR->CR |= PWR_CR_ODSWEN;
  64.     while((PWR->CSR & PWR_CSR_ODSWRDY) == 0)
  65.     {
  66.     }                                           //这里只是针对了电源
  67.     /* Configure Flash prefetch, Instruction cache, Data cache and wait state */
  68.     FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;
  69. #endif /* STM32F427_437x || STM32F429_439xx || STM32F446xx || STM32F469_479xx */

  70. #if defined(STM32F40_41xxx)  || defined(STM32F412xG)   
  71.     /* Configure Flash prefetch, Instruction cache, Data cache and wait state */
  72.     FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;
  73. #endif /* STM32F40_41xxx  || STM32F412xG */

  74.     /* Select the main PLL as system clock source */
  75.     RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
  76.     RCC->CFGR |= RCC_CFGR_SW_PLL;

  77.     /* Wait till the main PLL is used as system clock source */
  78.     while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);
  79.     {
  80.     }
  81.   }
  82.   else
  83.   { /* If HSE fails to start-up, the application will have wrong clock
  84.          configuration. User can add here some code to deal with this error */
  85.   }
  86.   
  87. /* STM32F40_41xxx || STM32F427_437xx || STM32F429_
复制代码



收藏 评论4 发布时间:2018-9-19 11:25

举报

4个回答
JQChirs 回答时间:2018-9-19 11:31:26
       我现在也只能怀疑是时钟的问题了!因为对于同样是F4的单片机来说,相关OTG_FS无论是引脚配置,时钟,中断向量表还是寄存器肯定是相同的!
       我甚至打印对照相关OTG_FS的寄存器发现并没有什么大的区别。
      
馒头弟 回答时间:2018-9-20 09:12:36
时钟没啥问题诶,你用的高速还是全速
RCC.png

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

wenyangzeng 回答时间:2018-9-20 09:53:53
F407的主频是168MHZ,F446主频是180MHZ.楼主要检查一下F446系统时钟分频后的USB时钟频率是否正确。

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

shenxiaolin_mai 回答时间:2018-9-20 13:33:40
过来学习学习

评分

参与人数 1ST金币 -1 收起 理由
zero99 -1 求助帖不要灌水啊

查看全部评分

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版