1. 程式人生 > >STM32之時鐘輸出功能

STM32之時鐘輸出功能

很多時候,我們想讓ARM發出固定頻率的脈衝,作為另一個晶片的時鐘時,有兩個方法一個是定時器或者時鐘輸出功能,利用定時器輸出會吃中斷源並且不利於發出高頻率脈衝,所以選擇第二個方法對應時鐘源的時鐘,並且可以進行分頻之後再輸出。

STM32F4手冊說明:
時鐘輸出功能
共有兩個微控制器時鐘輸出 (MCO) 引腳:
 MCO1
使用者可通過可配置的預分配器(從 1 到 5)向 MCO1 引腳 (PA8) 輸出四個不同的時鐘源:
— HSI 時鐘
— LSE 時鐘
— HSE 時鐘
— PLL 時鐘
所需的時鐘源通過 RCC  時鐘配置暫存器 (RCC_CFGR) 中的 MCO1PRE[2:0] 和 MCO1[1:0]
位選擇。
 MCO2
使用者可通過可配置的預分配器(從 1 到 5)向 MCO2 引腳 (PC9) 輸出四個不同的時鐘源:
— HSE 時鐘
— PLL 時鐘
— 系統時鐘 (SYSCLK)
— PLLI2S 時鐘
所需的時鐘源通過 RCC  時鐘配置暫存器 (RCC_CFGR) 中的 MCO2PRE[2:0] 和 MCO2
位選擇。
對於不同的 MCO 引腳,必須將相應的 GPIO 埠在複用功能模式下進行設定。
MCO 輸出時鐘不得超過 100 MHz(最大 I/O 速度)。

如圖所示;

比較簡單:直接說具體配置示例僅用MCO1進行示例
配置取主時鐘168MHz再進行5分頻後輸出
void MCO1_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_ClockSecuritySystemCmd(ENABLE);
 
    /* Enable GPIOs clocks */
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_MCO);//開啟引腳複用功能
         
    /* Configure MCO (PA8) */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;  //UP
    GPIO_Init(GPIOA, &GPIO_InitStructure);
//輸出時鐘
    RCC_MCO1Config(RCC_MCO1Source_PLLCLK, RCC_MCO1Div_5);
}

如上初始化過後,引腳就可以輸出響應的時鐘了。

庫函式中RCC_MCO1Config()解釋如下

形參1:填入要選擇的時鐘源
RCC_MCO1Source_HSI
 RCC_MCO1Source_LSE
RCC_MCO1Source_HSE
RCC_MCO1Source_PLLCLK
從時鐘樹上很容易看出該每個時鐘源
形參2:分頻係數
RCC_MCO1Div_1
 RCC_MCO1Div_2
RCC_MCO1Div_3
RCC_MCO1Div_4
RCC_MCO1Div_5
分別是對時鐘源進行1-5分頻之後輸出的時鐘

 

 

/*

  * @brief  Selects the clock source to output on MCO1 pin(PA8).
  * @note   PA8 should be configured in alternate function mode.
  * @param  RCC_MCO1Source: specifies the clock source to output.
  *          This parameter can be one of the following values:
  *            @arg RCC_MCO1Source_HSI: HSI clock selected as MCO1 source
  *            @arg RCC_MCO1Source_LSE: LSE clock selected as MCO1 source
  *            @arg RCC_MCO1Source_HSE: HSE clock selected as MCO1 source
  *            @arg RCC_MCO1Source_PLLCLK: main PLL clock selected as MCO1 source
  * @param  RCC_MCO1Div: specifies the MCO1 prescaler.
  *          This parameter can be one of the following values:
  *            @arg RCC_MCO1Div_1: no division applied to MCO1 clock
  *            @arg RCC_MCO1Div_2: division by 2 applied to MCO1 clock
  *            @arg RCC_MCO1Div_3: division by 3 applied to MCO1 clock
  *            @arg RCC_MCO1Div_4: division by 4 applied to MCO1 clock
  *            @arg RCC_MCO1Div_5: division by 5 applied to MCO1 clock
  * @retval None
  */
void RCC_MCO1Config(uint32_t RCC_MCO1Source, uint32_t RCC_MCO1Div)
{
  uint32_t tmpreg = 0;
  
  /* Check the parameters */
  assert_param(IS_RCC_MCO1SOURCE(RCC_MCO1Source));
  assert_param(IS_RCC_MCO1DIV(RCC_MCO1Div));  

  tmpreg = RCC->CFGR;

  /* Clear MCO1[1:0] and MCO1PRE[2:0] bits */
  tmpreg &= CFGR_MCO1_RESET_MASK;

  /* Select MCO1 clock source and prescaler */
  tmpreg |= RCC_MCO1Source | RCC_MCO1Div;

  /* Store the new value */
  RCC->CFGR = tmpreg;  
}

=======================================================

如有不對之處望指出。一起學習共同進步

郵箱:[email protected]

——十五