1. 程式人生 > >【微控制器】[STM8] - 外部時鐘 + 內部時鐘 的切換

【微控制器】[STM8] - 外部時鐘 + 內部時鐘 的切換

STM8S103K3: 外部時鐘 + 內部時鐘 的切換。

  1. 首先看一下 STM8S103K3 的時鐘結構圖,可以幫助你很好的理解。
    這裡寫圖片描述
    這裡有幾個時鐘,就是圖中標識的時鐘,需要弄清楚一下:

    • fHSE: 外部高速晶振時鐘,它是由外部晶振產生,大小由外部晶振大小決定,STM8S的外部晶振範圍:1-24M,看圖中的”HSE OSC 1-24M“。
    • fHSI:內部RC高速時鐘,它是由內部的RC震盪電路產生的,其值16M。但是可以經過後面的分頻器分頻,四個分頻係數可供選擇(1,2,4,8)。注:精準度比外部晶振的要稍差一些。
    • fMASTER:主時鐘,它是由HSE 或者 HSI提供時鐘,主要功能給外圍裝置(peripherals,如I2C,SPI,ADC等)提供時鐘,還有給CPU提供時鐘源。
    • fCPU:cpu時鐘,它是由fMASTER經過分頻得到,其作用就是給CPU提供時鐘,一個機械週期就是一個fCPU的時鐘週期。
  2. 下面是時鐘的原始碼部分,可供大家參考。
    這裡寫了四段程式,分別是:

    • 使用高速內部時鐘(暫存器版)
    • 使用高速內部時鐘(庫函式版)
    • 使用外部時鐘(暫存器版)
    • 使用外部時鐘(庫函式版)

原始碼如下,看註釋應該就可以了。


/*******************************************************************************
* Function Name  : InitCpuClock.
* Description    : Initial CPU clock, .
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
static void InitCpuClock(void) { #if 1 // 暫存器版本 - 使用高速內部時鐘 //Use HSI @8MHZ, div = 2; 8=16/2 CLK->ECKR &= ~CLK_ECKR_HSEEN; // 失能外時鐘 CLK->CKDIVR &= (uint8_t)(~CLK_CKDIVR_HSIDIV); // 清零內部時鐘預分頻 CLK->CKDIVR |= CLK_PRESCALER_HSIDIV2; // 設定內部時鐘預分頻 2; 具體可以參考資料手冊 (reference manual)
CLK->ICKR |= CLK_ICKR_HSIEN; // 使能內部高速時鐘 while(!(CLK->ICKR&CLK_ICKR_HSIRDY)); // 等待內部高速時鐘穩定, 穩定後則內部時鐘已經開跑了。 時鐘 = 16/2 M #endif #if 0 // 庫函式版本 - 使用內部高速時鐘 //Use HSI @8MHZ, div = 2; 8=16/2 CLK_HSECmd(DISABLE); // 失能外時鐘 CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV2); // 設定內部時鐘預分頻 2; 具體可以參考資料手冊 (reference manual) CLK_HSICmd(ENABLE); // 使能內部高速時鐘 while(!(CLK->ICKR&CLK_ICKR_HSIRDY)); // 等待內部高速時鐘穩定, 穩定後則內部時鐘已經開跑了。 時鐘 = 16/2 M #endif #if 0 // 暫存器版本 - 使用外部時鐘 CLK->CKDIVR |= CLK_PRESCALER_CPUDIV1; // CPU 時鐘分頻 1,CPU時鐘 = 外部時鐘(即是外部晶振頻率) CLK->ECKR |= CLK_ECKR_HSEEN; // 允許外部高速振盪器工作 while(!(CLK->ECKR & CLK_ECKR_HSERDY)); // 等待外部高速振盪器準備好 CLK->SWCR |= CLK_SWCR_SWEN; // 使能切換 CLK->SWR = CLK_SOURCE_HSE; // 選擇晶片外部的高速振盪器為主時鐘 while(!(CLK->SWCR&CLK_SWCR_SWIF)); // 等待切換成功 CLK->SWCR &= ~(CLK_SWCR_SWEN|CLK_SWCR_SWIF); // 清除切換標誌 #endif #if 0 // 庫函式版本 - 使用外部時鐘 CLK->CKDIVR |= CLK_PRESCALER_CPUDIV1; // CPU 時鐘分頻 1,CPU時鐘 = 外部時鐘(即是外部晶振頻率) CLK_ClockSwitchConfig(CLK_SWITCHMODE_AUTO, // 時鐘自動切換模式,注: 引數是自動切換,不然只使用這一個函式是不能切換成功的 CLK_SOURCE_HSE, // 要切換的時鐘(這裡是外部時鐘) DISABLE, // 是否使能切換完成中斷(這裡失能) CLK_CURRENTCLOCKSTATE_ENABLE);// 是否還使能當前時鐘(這裡選擇 關掉當前時鐘HSI) CLK->SWCR &= ~(CLK_SWCR_SWEN|CLK_SWCR_SWIF); // 清除切換標誌 #endif }

pillar peng
2016.4.29 11:51