zoukankan      html  css  js  c++  java
  • NUCLEO-L053R8 | RCC时钟树 MCO输出

    RCC时钟配置实验 


      最近玩了一下Nucleo-L053R8板子,即STM32L053R8T6。浏览了RCC章节后,顺便做了个小实验,现在给大伙分享一下。

      实验非常简单,配置一下系统时钟,可以通过肉眼观察LED的闪烁快慢,精确的话,可以通过数字示波器监控RCC的MCO引脚的输出。为了保证实验的严谨性,本次通过数字示波器监控RCC的MCO引脚的输出。

      

      开始实验之前,先给大伙稍微讲一下MCO 时钟输出的知识:

     图1 RCC时钟树

    MCO 时钟输出:

      MCO 是 microcontroller clock output 的缩写,是微控制器时钟输出引脚,在STM32L053R8T6中 由 PA8、PA9复用所得,主要作用是可以对外提供时钟,相当于一个有源晶振。

      MCO的时钟来源可以是:LSE、LSI、HSE、HSI 16、PLLCLK、SYSCLK、MSI、HSI 48,具体选哪个由时钟配置寄存器的相应位决定。除了对外提供时钟这个作用之外,我们还可以通过示波器监控 MCO 引脚的时钟输出来验证我们的系统时钟配置是否正确。

    图2 MCO时钟来源

     

    STM32CubeMx:

      了解了MCO时钟输出的知识后,我们就可以真正开始实验了。

      首先,我们通过STM32CubeMx生成我们需要的项目工程。STM32CubeMX 是意法半导体STMCube™的主动原创,可以减轻开发工作、时间和费用。STM32Cube 覆盖了 STM32 系列。STM32Cube 包括 STM32CubeMX,STM32CubeMX是一款图形化软件设置工具,允许使用图形化向导来生成 C 初始化代码。它也集成了 一个全面的软件平台,支持每一个系列(例如STM32F4系列的STM32CubeF4)。通俗地说,一方面大大减少了工作量,另一方面也有利于菜鸟的入门学习。通过STM32CubeMx生成项目工程的主要步骤如下:

    Nucleo-L053R8板子有两个RCC_MCO引脚,分别为:

      RCC_MCO1 -----> PA8

      RCC_MCO2 -----> PA9

      本次实验监控PA8引脚输出,测试的系统时钟来源于HSI,配置成32MHz。你也可以选用PA9输出或者配置不同的系统时钟。

    图3 引脚配置

     

     图4 时钟配置

     

     图5 生成项目工程

     

       到了这一步骤,就可以Open Project开始实验了。代码很简单,且项目工程都已配置好相关GPIO和RCC时钟,直接用数字示波器监控PA8引脚的输出(MCO时钟输出)来判断我们的系统时钟是否配置正确即可。

      

    部分代码如下:

     1 /** Configure pins
     2      PA8   ------> RCC_MCO
     3 */
     4 static void MX_GPIO_Init(void)
     5 {
     6 
     7   GPIO_InitTypeDef GPIO_InitStruct;
     8 
     9   /* GPIO Ports Clock Enable */
    10   __HAL_RCC_GPIOA_CLK_ENABLE();
    11 
    12   /*Configure GPIO pin : PA8 */
    13   GPIO_InitStruct.Pin = GPIO_PIN_8;
    14   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    15   GPIO_InitStruct.Pull = GPIO_NOPULL;
    16   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    17   GPIO_InitStruct.Alternate = GPIO_AF0_MCO;
    18   HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    19 
    20 }
    21 
    22 
    23 /**
    24   * @brief System Clock Configuration
    25   * @retval None
    26   */
    27 void SystemClock_Config(void)
    28 {
    29 
    30   RCC_OscInitTypeDef RCC_OscInitStruct;
    31   RCC_ClkInitTypeDef RCC_ClkInitStruct;
    32 
    33     /**Configure the main internal regulator output voltage 
    34     */
    35   __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
    36 
    37     /**Initializes the CPU, AHB and APB busses clocks 
    38     */
    39   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
    40   RCC_OscInitStruct.HSIState = RCC_HSI_ON;
    41   RCC_OscInitStruct.HSICalibrationValue = 16;
    42   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    43   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
    44   RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_6;
    45   RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3;
    46   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    47   {
    48     _Error_Handler(__FILE__, __LINE__);
    49   }
    50 
    51     /**Initializes the CPU, AHB and APB busses clocks 
    52     */
    53   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
    54                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
    55   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
    56   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    57   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
    58   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
    59 
    60   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
    61   {
    62     _Error_Handler(__FILE__, __LINE__);
    63   }
    64 
    65   HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_1);
    66 
    67     /**Configure the Systick interrupt time 
    68     */
    69   HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
    70 
    71     /**Configure the Systick 
    72     */
    73   HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
    74 
    75   /* SysTick_IRQn interrupt configuration */
    76   HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
    77 }
    78 
    79 int main(void)
    80 {
    81   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
    82   HAL_Init();
    83 
    84     /* Initialize all configured peripherals */
    85     MX_GPIO_Init();
    86     
    87   /* Configure the system clock */
    88   SystemClock_Config();
    89 
    90   while (1)
    91   {
    92   }
    93 }

      一开始,我把编译好的程序下载到开发板里,发现数字示波器无输出波形,然后看了一下代码,发现在main函数中,系统时钟配置函数SystemClock_Config()放在了GPIO配置函数MX_GPIO_Init()之前了,而RCC_MCO配置函数放置在系统时钟配置函数中,这就导致了RCC_MCO的GPIO引脚并未配置成复用推挽输出就进行了RCC_MCO配置。我把GPIO配置函数MX_GPIO_Init()放在系统时钟配置函数SystemClock_Config()之前,数字示波器就出现了波形。所以,我们平时在编写代码的时候,应养成一个良好的编程习惯。以上只是我个人对问题的解答,若有不对之处,欢迎指出,共同学习,共同进步。

       

      如果你不清楚Nucleo板子上PA8、GND具体在哪个引脚,那么你可以查阅STM32 Nucleo-64 boards的用户手册(User manual)---> Hardware layout and configuration ---> Extension connectors ---> Figure 20.NUCLEO-L053R8

    图6 Extension Connection引脚图

     

       根据上面的引脚图,用两根杜邦线从Nucleo板子上引出PA8、GND,然后用数字示波器来监控。实物连接如下:

    图7 实物连接图

     

      把编译好的程序下载到开发板,设置不同的系统时钟,用示波器监控 MCO 引脚输出的波形频率来判断我们的系统时钟是否配置正确。

    图8 数字示波器波形图

     

      从波形图可见,监控到RCC时钟频率为32MHZ,与实验时钟配置相符。以上就是RCC时钟配置的一个小实验。希望对有需要的同学有所帮助。谢谢!!!

  • 相关阅读:
    UUID含义及ubuntu配置系统默认JDK
    MYSQL 问题小总结
    纯CSS3实现常见多种相册效果
    Docker Api 实测
    Dijkstra with priority queue 分类: ACM TYPE 2015-07-23 20:12 4人阅读 评论(0) 收藏
    hash值的计算与转换 分类: ACM TYPE 2015-05-07 17:49 36人阅读 评论(0) 收藏
    NYOJ
    进制转换函数 2015-02-15 09:41 32人阅读 评论(0) 收藏
    操作系统图解 2015-02-03 23:44 71人阅读 评论(0) 收藏
    [kuangbin带你飞]专题一 简单搜索
  • 原文地址:https://www.cnblogs.com/Tuple-Joe/p/9431845.html
Copyright © 2011-2022 走看看