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

【分享】STM32L151晶振掉了~~~

[复制链接]
跟风和天空对话 发布时间:2019-7-8 17:25
最近有个项目,用到STM32L151,原设计者使用外部8MHz晶振。有一天晚上调试过程中,突然发现程序跑不动了,翻到背面瞧见HSE脱落了~~~再用RCC_GetClocksFreq(&RCC_ClockFreq);观察RCC_ClockFreq.SYSCLK_Frequency,只有2.09MHz。手扶着HSE重新上电,单片机运转正常。看来就是它的锅。


但是,家里没有电烙铁。

那怎么办呢?只能换用16MHz的HSI了,MSI非整就不考虑了。我从来都只是用SystemInit();初始化的,除了修改一下HSE的频率,从来没碰过里面的其他语句。
一开始,我写了一个HSI倍频到32MHz的程序,替换掉.s文件里的SystemInit,结果失败。可能是因为我写的程序本身有问题。


后来想想,不如向SystemInit();里面添加HSE启动失败后的代码。它里面负责将HSE倍频到32MHz的程序是


/* Configure the System clock frequency, AHB/APBx prescalers and Flash settings */
  SetSysClock();


在它里面,除了详细描述了HSE+PLL的启动方式,还有下列注释:


if (HSEStatus == (uint32_t)0x01)
{
……省略……
}
else
{
    /* If HSE fails to start-up, the application will have wrong clock
       configuration. User can add here some code to deal with this error */

  //翻译:如果HSE无法启动,程序将以错误的时钟运行。用户可自行添加勘正代码
}

ST官方竟然提前留好了坑!

于是,仿照着HSE+PLL启动方式,我写了下面的代码,使用HSI+PLL,并添加到else{}中,观察RCC_ClockFreq.SYSCLK_Frequency=32000000,一次性通过。

    /* Enable HSI */
    RCC->CR |= ((uint32_t)RCC_CR_HSION);

    /* Wait till HSI is ready and if Time out is reached exit */
    do
    {
      HSIStatus = RCC->CR & RCC_CR_HSIRDY;
      StartUpCounter++;
    } while((HSIStatus == 0) && (StartUpCounter != HSI_STARTUP_TIMEOUT));

    if ((RCC->CR & RCC_CR_HSIRDY) != RESET)
    {
      HSIStatus = (uint32_t)0x01;
    }
    else
    {
      HSIStatus = (uint32_t)0x00;
    }

    if (HSIStatus == (uint32_t)0x01)
    {
      /* Turn OFF the HSE oscillator */
      RCC_HSEConfig( RCC_HSE_OFF );

      /* Enable 64-bit access */
      FLASH->ACR |= FLASH_ACR_ACC64;

      /* Enable Prefetch Buffer */
      FLASH->ACR |= FLASH_ACR_PRFTEN;

      /* Flash 1 wait state */
      FLASH->ACR |= FLASH_ACR_LATENCY;

      /* Power enable */
      RCC->APB1ENR |= RCC_APB1ENR_PWREN;

      /* Select the Voltage Range 1 (1.8 V) */
      PWR->CR = PWR_CR_VOS_0;

      /* Wait Until the Voltage Regulator is ready */
      while((PWR->CSR & PWR_CSR_VOSF) != RESET)
      {
      }

      /* HCLK = SYSCLK /1*/
      RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;

      /* PCLK2 = HCLK /1*/
      RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;

      /* PCLK1 = HCLK /1*/
      RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1;

      /*  PLL configuration */
      RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLMUL |
                                          RCC_CFGR_PLLDIV));
      RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSI | RCC_CFGR_PLLMUL4 | RCC_CFGR_PLLDIV2);

      /* Enable PLL */
      RCC->CR |= RCC_CR_PLLON;

      /* Wait till PLL is ready */
      while((RCC->CR & RCC_CR_PLLRDY) == 0)
      {
      }

      /* Select PLL as system clock source */
      RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
      RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;

      /* Wait till PLL is used as system clock source */
      while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_PLL)
      {
      }   
    }



记得在static void SetSysClock(void)的第一行添加HSIStatus的定义,即:
__IO uint32_t StartUpCounter = 0, HSEStatus = 0, HSIStatus = 0;

收藏 评论0 发布时间:2019-7-8 17:25

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版