新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 時鐘配置的仿真

        時鐘配置的仿真

        作者: 時間:2016-11-13 來源:網絡 收藏
        在ARM-MDK開發環境中,提供了很好用的時鐘配置仿真模式,為學習LPC1114的時鐘配置提供了方便,下面就來詳細討論一下它的用法。

        要進行仿真,必須先把程序進行編譯,正確無誤后才能進入到仿真模式。為此,先給出主函數的內容,如下。

        本文引用地址:http://www.104case.com/article/201611/316321.htm

        void SystemInit(void)

        {

        SysCLK_config();//調用時鐘配置函數

        }

        int main(void)

        {

        SystemInit ();//調用系統初始化函數

        while(1)

        {

        ;//空循環

        }

        }

        在上述程序中可以看出,主函數的寫法和普通單片機開發的沒有什么兩樣,都有一個死循環,因為這里只做時鐘配置的仿真,所以在調用時鐘配置函數后就進行一個空循環。只有三點要特別注意一下:一是這里的main函數必須是整型(int型)的;二是在程序結束的最后一行要有一個換行(即要回一下車),否則會有警告出現;三是在項目自動加載的啟動文件中規定,程序中必須要有一個系統初始化的函數(SystemInit),否則程序不能編譯鏈接。所以在上述程序中雖然只調用一個時鐘配置函數,但還是要把它放入到系統初始化函數中去供主函數調用。

        但是,把上述函數及前面的時鐘配置函數寫到主程序后,還是編譯不過的,會報兩條錯誤,說“uint8_t”和“LPC_SYSCON”沒有定義。這是因為程序沒有包含一些特定的頭文件,在這些頭文件內才有相關變量的申明。要程序順利編譯通過,必須要把這些頭文件包含進來。但是,由于開發LPC1114所需要的頭文件很多,且有些頭文件還有彼此的依賴關系,對于不同的開發環境,定義的名稱也不一致,因此,為了減小學習的挫折感,先快速的把我們的第一個程序運行起來,下面用不包含頭文件的方式,把程序所用到的內容全部都列出來,這樣只要把下面的程序復制到開發環境中,就可以順利通過編譯了。

        程序代碼如下:

        #define__IOvolatile

        #define__Ovolatile

        #define__Ivolatile const

        typedef unsignedchar uint8_t;

        typedef unsigned shortint uint16_t;

        typedef unsignedint uint32_t;

        typedef struct
        {
        __IO uint32_t SYSMEMREMAP; /*!< Offset: 0x000 (R/W) System memory remap Register */
        __IO uint32_t PRESETCTRL; /*!< Offset: 0x004 (R/W) Peripheral reset control Register */
        __IO uint32_t SYSPLLCTRL; /*!< Offset: 0x008 (R/W) System PLL control Register */
        __I uint32_t SYSPLLSTAT; /*!< Offset: 0x00C (R/ ) System PLL status Register */
        uint32_t RESERVED0[4];

        __IO uint32_t SYSOSCCTRL; /*!< Offset: 0x020 (R/W) System oscillator control Register */
        __IO uint32_t WDTOSCCTRL; /*!< Offset: 0x024 (R/W) Watchdog oscillator control Register */
        __IO uint32_t IRCCTRL; /*!< Offset: 0x028 (R/W) IRC control Register */
        uint32_t RESERVED1[1];
        __I uint32_t SYSRSTSTAT; /*!< Offset: 0x030 (R/ ) System reset status Register */
        uint32_t RESERVED2[3];
        __IO uint32_t SYSPLLCLKSEL; /*!< Offset: 0x040 (R/W) System PLL clock source select Register */
        __IO uint32_t SYSPLLCLKUEN; /*!< Offset: 0x044 (R/W) System PLL clock source update enable Register */
        uint32_t RESERVED3[10];

        __IO uint32_t MAINCLKSEL; /*!< Offset: 0x070 (R/W) Main clock source select Register */
        __IO uint32_t MAINCLKUEN; /*!< Offset: 0x074 (R/W) Main clock source update enable Register */
        __IO uint32_t SYSAHBCLKDIV; /*!< Offset: 0x078 (R/W) System AHB clock divider Register */
        uint32_t RESERVED4[1];

        __IO uint32_t SYSAHBCLKCTRL; /*!< Offset: 0x080 (R/W) System AHB clock control Register */
        uint32_t RESERVED5[4];
        __IO uint32_t SSP0CLKDIV; /*!< Offset: 0x094 (R/W) SSP0 clock divider Register */
        __IO uint32_t UARTCLKDIV; /*!< Offset: 0x098 (R/W) UART clock divider Register */
        __IO uint32_t SSP1CLKDIV; /*!< Offset: 0x09C (R/W) SSP1 clock divider Register */
        uint32_t RESERVED6[1];
        uint32_t RESERVED7[11];

        __IO uint32_t WDTCLKSEL; /*!< Offset: 0x0D0 (R/W) WDT clock source select Register */
        __IO uint32_t WDTCLKUEN; /*!< Offset: 0x0D4 (R/W) WDT clock source update enable Register */
        __IO uint32_t WDTCLKDIV; /*!< Offset: 0x0D8 (R/W) WDT clock divider Register */
        uint32_t RESERVED9[1];

        __IO uint32_t CLKOUTCLKSEL; /*!< Offset: 0x0E0 (R/W) CLKOUT clock source select Register */
        __IO uint32_t CLKOUTUEN; /*!< Offset: 0x0E4 (R/W) CLKOUT clock source update enable Register */
        __IO uint32_t CLKOUTDIV; /*!< Offset: 0x0E8 (R/W) CLKOUT clock divider Register */
        uint32_t RESERVED10[5];

        __I uint32_t PIOPORCAP0; /*!< Offset: 0x100 (R/ ) POR captured PIO status 0 Register */
        __I uint32_t PIOPORCAP1; /*!< Offset: 0x104 (R/ ) POR captured PIO status 1 Register */
        uint32_t RESERVED11[11];
        uint32_t RESERVED12[7];
        __IO uint32_t BODCTRL; /*!< Offset: 0x150 (R/W) BOD control Register */
        __IO uint32_t SYSTCKCAL; /*!< Offset: 0x154 (R/W) System tick counter calibration Register */
        uint32_t RESERVED13[1];
        uint32_t RESERVED14[5];
        uint32_t RESERVED15[2];
        uint32_t RESERVED16[34];

        __IO uint32_t STARTAPRP0; /*!< Offset: 0x200 (R/W) Start logic edge control Register 0 */
        __IO uint32_t STARTERP0; /*!< Offset: 0x204 (R/W) Start logic signal enable Register 0 */
        __O uint32_t STARTRSRP0CLR; /*!< Offset: 0x208 ( /W) Start logic reset Register 0 */
        __I uint32_t STARTSRP0; /*!< Offset: 0x20C (R/ ) Start logic status Register 0 */
        __IO uint32_t STARTAPRP1; /*!< Offset: 0x210 (R/W) Start logic edge control Register 1 (LPC11UXX only) */
        __IO uint32_t STARTERP1; /*!< Offset: 0x214 (R/W) Start logic signal enable Register 1 (LPC11UXX only) */
        __O uint32_t STARTRSRP1CLR; /*!< Offset: 0x218 ( /W) Start logic reset Register 1 (LPC11UXX only) */
        __I uint32_t STARTSRP1; /*!< Offset: 0x21C (R/ ) Start logic status Register 1 (LPC11UXX only) */
        uint32_t RESERVED17[4];

        __IO uint32_t PDSLEEPCFG; /*!< Offset: 0x230 (R/W) Power-down states in Deep-sleep mode Register */
        __IO uint32_t PDAWAKECFG; /*!< Offset: 0x234 (R/W) Power-down states after wake-up from Deep-sleep mode Register*/
        __IO uint32_t PDRUNCFG; /*!< Offset: 0x238 (R/W) Power-down configuration Register*/
        uint32_t RESERVED18[110];
        __I uint32_t DEVICE_ID; /*!< Offset: 0x3F4 (R/ ) Device ID Register */
        } LPC_SYSCON_TypeDef;

        #define LPC_APB0_BASE(0x40000000UL)

        #define LPC_AHB_BASE(0x50000000UL)

        #define LPC_SYSCON_BASE(LPC_APB0_BASE + 0x48000)

        #define LPC_SYSCON((LPC_SYSCON_TypeDef *) LPC_SYSCON_BASE)

        //************************************************************************************************

        void SysCLK_config(void)

        {

        uint8_t i;

        LPC_SYSCON->PDRUNCFG &= ~(1 << 5);//給系統振蕩器上電

        LPC_SYSCON->SYSOSCCTRL = 0x00000000;//系統振蕩器未旁路,1~12MHz輸入

        for (i = 0; i < 200; i++) __nop();//延時等待振蕩器穩定

        LPC_SYSCON->SYSPLLCLKSEL = 0x00000001;//PLL輸入選擇外部晶體振蕩

        LPC_SYSCON->SYSPLLCLKUEN = 0x00;

        LPC_SYSCON->SYSPLLCLKUEN = 0x01;//先寫0后寫1更新時鐘源

        while (!(LPC_SYSCON->SYSPLLCLKUEN & 0x01));//等待更新完成

        LPC_SYSCON->SYSPLLCTRL = 0x00000023;//M=4、P=2,倍頻后的時鐘為48MHz

        LPC_SYSCON->PDRUNCFG &= ~(1 << 7);//給PLL上電

        while (!(LPC_SYSCON->SYSPLLSTAT & 0x01));//等待PLL鎖定

        LPC_SYSCON->MAINCLKSEL = 0x00000003;//主時鐘選擇PLL倍頻后的時鐘

        LPC_SYSCON->MAINCLKUEN = 0x00;

        LPC_SYSCON->MAINCLKUEN = 0x01;//先寫0后寫1更新時鐘源

        while (!(LPC_SYSCON->MAINCLKUEN & 0x01));//等待更新完成

        LPC_SYSCON->SYSAHBCLKDIV = 0x00000001;//AHB為1分頻,AHB時鐘為48MHz

        LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);//使能GPIO時鐘

        }

        void SystemInit(void)

        {

        SysCLK_config();

        }

        int main(void)

        {

        SystemInit ();//調用時鐘配置函數

        while(1)

        {

        ;//空循環

        }

        }

        (不要忘記最后一行有一個強制換行)

        從上面可以看到,變量的申明都是以結構體的形式出現的,較為復雜,現在先不去討論它。先把上述程序編譯鏈接(點擊工具條上的“Rebuild”按鈕)無誤后,點擊工具條上的“Start/Stop Debug Session”按鈕(或按Ctrl+F5)進入到調試模式。點擊菜單Peripherals->Clocking & Power Control->Clock Generation Schematic,將會出現一個顯示時鐘結構的對話框,如下圖所示。

        從圖中可以清楚地看出配置后各時鐘的分配情況(如果時鐘不對,可能是沒有運行程序,只要點擊工具條上的“Run”按鈕(或直接按F5)就可以了),非常直觀。大家還可對照前面的程序,自行更改相關內容,再仿真看看變化,以加深對時鐘配置的了解。要更改仿真中的外部晶振的值可點擊菜單Peripherals->Clocking & Power Control->System Oscillator Control進行更改,要更改內部RC振蕩的值可點擊菜單Peripherals->Clocking & Power Control->Internal Oscillator Control進行更改,要更改看門狗振蕩的值可點擊菜單Peripherals->Clocking & Power Control->Watchdog Oscillator Control進行更改。甚至你還可以看到在設置錯誤(如把PLL倍頻后的時鐘設置了超過50MHz)的情況下,主時鐘會自動轉到默認的12MHz內部RC振蕩中去執行,真是非常了不起。

        除了仿真以外,LPC1114還提供了一個時鐘輸出端口CLKOUT,它被復用在P0.1引腳,可以通過程序控制它來輸出內部RC振蕩時鐘、系統振蕩器時鐘(外部晶振)、看門狗振蕩時鐘和主時鐘。

        下面就給出一個CLKOUT引腳輸出時鐘的函數,如下:

        void CLKOUT_EN(uint8_t CLKOUT_DIV)

        {

        LPC_SYSCON->SYSAHBCLKCTRL |= (1<<16);//使能IOCON時鐘

        LPC_IOCON->PIO0_1=0XD1;//把P0.1設置為CLKOUT引腳

        LPC_SYSCON->SYSAHBCLKCTRL &= ~(1<<16);//禁止IOCON時鐘

        LPC_SYSCON->CLKOUTDIV = CLKOUT_DIV;//輸出分頻為48/ CLKOUT_DIV

        LPC_SYSCON->CLKOUTCLKSEL= 0X00000003;//CLKOUT時鐘選擇主時鐘

        LPC_SYSCON->CLKOUTUEN =0X00;

        LPC_SYSCON->CLKOUTUEN =0X01;//先寫0后寫1更新時鐘源

        while (!(LPC_SYSCON->CLKOUTUEN & 0x01));//等待更新完成

        }

        如果使用的是48MHz的主時鐘,分頻系數CLKOUT_DIV也取48,則該函數執行完后,LPC1114的P0.1腳就會有1MHz的脈沖輸出,可通過示波器來進行觀察。

        在上述程序中可以看出,要改變一個具有復用的引腳功能時,必須先打開IOCON的時鐘,否則配置不生效!而在配置完成后,要及時關閉IOCON時鐘,以降低功耗。關于IOCON的配置將會在后面討論GPIO時進行詳細討論,這里先不贅述。下面給出的是“CLKOUT時鐘源選擇寄存器(CLKOUTCLKSEL)”的位結構。

        符號

        描述

        復位值

        1∶0

        SEL

        (CLKOUT時鐘源)

        00

        IRC振蕩器

        0

        01

        系統振蕩器

        10

        看門狗振蕩器

        11

        主時鐘

        31∶2

        -

        -

        保留

        0

        實驗時可根據上表來改變CLKOUTCLKSEL的值,從而觀察不同的時鐘頻率輸出。

        由于在CLKOUT函數中加入了一些新的寄存器(比如IOCON、GPIO等),所以程序必須在頭文件中把相關的申明包含進來,才能正確編譯通過。這里同前面一樣,為了方便,使用不包含頭文件的形式來書寫程序,下面給出其全部內容。

        #define__IOvolatile

        #define__Ovolatile

        #define__Ivolatile const

        typedef unsignedchar uint8_t;

        typedef unsigned shortint uint16_t;

        typedef unsignedint uint32_t;

        typedef struct
        {
        __IO uint32_t SYSMEMREMAP; /*!< Offset: 0x000 (R/W) System memory remap Register */
        __IO uint32_t PRESETCTRL; /*!< Offset: 0x004 (R/W) Peripheral reset control Register */
        __IO uint32_t SYSPLLCTRL; /*!< Offset: 0x008 (R/W) System PLL control Register */
        __I uint32_t SYSPLLSTAT; /*!< Offset: 0x00C (R/ ) System PLL status Register */
        uint32_t RESERVED0[4];

        __IO uint32_t SYSOSCCTRL; /*!< Offset: 0x020 (R/W) System oscillator control Register */
        __IO uint32_t WDTOSCCTRL; /*!< Offset: 0x024 (R/W) Watchdog oscillator control Register */
        __IO uint32_t IRCCTRL; /*!< Offset: 0x028 (R/W) IRC control Register */
        uint32_t RESERVED1[1];
        __I uint32_t SYSRSTSTAT; /*!< Offset: 0x030 (R/ ) System reset status Register */
        uint32_t RESERVED2[3];
        __IO uint32_t SYSPLLCLKSEL; /*!< Offset: 0x040 (R/W) System PLL clock source select Register */
        __IO uint32_t SYSPLLCLKUEN; /*!< Offset: 0x044 (R/W) System PLL clock source update enable Register */
        uint32_t RESERVED3[10];

        __IO uint32_t MAINCLKSEL; /*!< Offset: 0x070 (R/W) Main clock source select Register */
        __IO uint32_t MAINCLKUEN; /*!< Offset: 0x074 (R/W) Main clock source update enable Register */
        __IO uint32_t SYSAHBCLKDIV; /*!< Offset: 0x078 (R/W) System AHB clock divider Register */
        uint32_t RESERVED4[1];

        __IO uint32_t SYSAHBCLKCTRL; /*!< Offset: 0x080 (R/W) System AHB clock control Register */
        uint32_t RESERVED5[4];
        __IO uint32_t SSP0CLKDIV; /*!< Offset: 0x094 (R/W) SSP0 clock divider Register */
        __IO uint32_t UARTCLKDIV; /*!< Offset: 0x098 (R/W) UART clock divider Register */
        __IO uint32_t SSP1CLKDIV; /*!< Offset: 0x09C (R/W) SSP1 clock divider Register */
        uint32_t RESERVED6[1];
        uint32_t RESERVED7[11];

        __IO uint32_t WDTCLKSEL; /*!< Offset: 0x0D0 (R/W) WDT clock source select Register */
        __IO uint32_t WDTCLKUEN; /*!< Offset: 0x0D4 (R/W) WDT clock source update enable Register */
        __IO uint32_t WDTCLKDIV; /*!< Offset: 0x0D8 (R/W) WDT clock divider Register */
        uint32_t RESERVED9[1];

        __IO uint32_t CLKOUTCLKSEL; /*!< Offset: 0x0E0 (R/W) CLKOUT clock source select Register */
        __IO uint32_t CLKOUTUEN; /*!< Offset: 0x0E4 (R/W) CLKOUT clock source update enable Register */
        __IO uint32_t CLKOUTDIV; /*!< Offset: 0x0E8 (R/W) CLKOUT clock divider Register */
        uint32_t RESERVED10[5];

        __I uint32_t PIOPORCAP0; /*!< Offset: 0x100 (R/ ) POR captured PIO status 0 Register */
        __I uint32_t PIOPORCAP1; /*!< Offset: 0x104 (R/ ) POR captured PIO status 1 Register */
        uint32_t RESERVED11[11];
        uint32_t RESERVED12[7];
        __IO uint32_t BODCTRL; /*!< Offset: 0x150 (R/W) BOD control Register */
        __IO uint32_t SYSTCKCAL; /*!< Offset: 0x154 (R/W) System tick counter calibration Register */
        uint32_t RESERVED13[1];
        uint32_t RESERVED14[5];
        uint32_t RESERVED15[2];
        uint32_t RESERVED16[34];

        __IO uint32_t STARTAPRP0; /*!< Offset: 0x200 (R/W) Start logic edge control Register 0 */
        __IO uint32_t STARTERP0; /*!< Offset: 0x204 (R/W) Start logic signal enable Register 0 */
        __O uint32_t STARTRSRP0CLR; /*!< Offset: 0x208 ( /W) Start logic reset Register 0 */
        __I uint32_t STARTSRP0; /*!< Offset: 0x20C (R/ ) Start logic status Register 0 */
        __IO uint32_t STARTAPRP1; /*!< Offset: 0x210 (R/W) Start logic edge control Register 1 (LPC11UXX only) */
        __IO uint32_t STARTERP1; /*!< Offset: 0x214 (R/W) Start logic signal enable Register 1 (LPC11UXX only) */
        __O uint32_t STARTRSRP1CLR; /*!< Offset: 0x218 ( /W) Start logic reset Register 1 (LPC11UXX only) */
        __I uint32_t STARTSRP1; /*!< Offset: 0x21C (R/ ) Start logic status Register 1 (LPC11UXX only) */
        uint32_t RESERVED17[4];

        __IO uint32_t PDSLEEPCFG; /*!< Offset: 0x230 (R/W) Power-down states in Deep-sleep mode Register */
        __IO uint32_t PDAWAKECFG; /*!< Offset: 0x234 (R/W) Power-down states after wake-up from Deep-sleep mode Register*/
        __IO uint32_t PDRUNCFG; /*!< Offset: 0x238 (R/W) Power-down configuration Register*/
        uint32_t RESERVED18[110];
        __I uint32_t DEVICE_ID; /*!< Offset: 0x3F4 (R/ ) Device ID Register */
        } LPC_SYSCON_TypeDef;

        typedef struct
        {
        __IO uint32_t PIO2_6; /*!< Offset: 0x000 (R/W) I/O configuration for pin PIO2_6 */
        uint32_t RESERVED0[1];
        __IO uint32_t PIO2_0; /*!< Offset: 0x008 (R/W) I/O configuration for pin PIO2_0/DTR/SSEL1 */
        __IO uint32_t RESET_PIO0_0; /*!< Offset: 0x00C (R/W) I/O configuration for pin RESET/PIO0_0 */
        __IO uint32_t PIO0_1; /*!< Offset: 0x010 (R/W) I/O configuration for pin PIO0_1/CLKOUT/CT32B0_MAT2 */
        __IO uint32_t PIO1_8; /*!< Offset: 0x014 (R/W) I/O configuration for pin PIO1_8/CT16B1_CAP0 */
        uint32_t RESERVED1[1];
        __IO uint32_t PIO0_2; /*!< Offset: 0x01C (R/W) I/O configuration for pin PIO0_2/SSEL0/CT16B0_CAP0 */

        __IO uint32_t PIO2_7; /*!< Offset: 0x020 (R/W) I/O configuration for pin PIO2_7 */
        __IO uint32_t PIO2_8; /*!< Offset: 0x024 (R/W) I/O configuration for pin PIO2_8 */
        __IO uint32_t PIO2_1; /*!< Offset: 0x028 (R/W) I/O configuration for pin PIO2_1/nDSR/SCK1 */
        __IO uint32_t PIO0_3; /*!< Offset: 0x02C (R/W) I/O configuration for pin PIO0_3 */
        __IO uint32_t PIO0_4; /*!< Offset: 0x030 (R/W) I/O configuration for pin PIO0_4/SCL */
        __IO uint32_t PIO0_5; /*!< Offset: 0x034 (R/W) I/O configuration for pin PIO0_5/SDA */
        __IO uint32_t PIO1_9; /*!< Offset: 0x038 (R/W) I/O configuration for pin PIO1_9/CT16B1_MAT0 */
        __IO uint32_t PIO3_4; /*!< Offset: 0x03C (R/W) I/O configuration for pin PIO3_4 */

        __IO uint32_t PIO2_4; /*!< Offset: 0x040 (R/W) I/O configuration for pin PIO2_4 */
        __IO uint32_t PIO2_5; /*!< Offset: 0x044 (R/W) I/O configuration for pin PIO2_5 */
        __IO uint32_t PIO3_5; /*!< Offset: 0x048 (R/W) I/O configuration for pin PIO3_5 */
        __IO uint32_t PIO0_6; /*!< Offset: 0x04C (R/W) I/O configuration for pin PIO0_6/SCK0 */
        __IO uint32_t PIO0_7; /*!< Offset: 0x050 (R/W) I/O configuration for pin PIO0_7/nCTS */
        __IO uint32_t PIO2_9; /*!< Offset: 0x054 (R/W) I/O configuration for pin PIO2_9 */
        __IO uint32_t PIO2_10; /*!< Offset: 0x058 (R/W) I/O configuration for pin PIO2_10 */
        __IO uint32_t PIO2_2; /*!< Offset: 0x05C (R/W) I/O configuration for pin PIO2_2/DCD/MISO1 */

        __IO uint32_t PIO0_8; /*!< Offset: 0x060 (R/W) I/O configuration for pin PIO0_8/MISO0/CT16B0_MAT0 */
        __IO uint32_t PIO0_9; /*!< Offset: 0x064 (R/W) I/O configuration for pin PIO0_9/MOSI0/CT16B0_MAT1 */
        __IO uint32_t SWCLK_PIO0_10; /*!< Offset: 0x068 (R/W) I/O configuration for pin SWCLK/PIO0_10/SCK0/CT16B0_MAT2 */
        __IO uint32_t PIO1_10; /*!< Offset: 0x06C (R/W) I/O configuration for pin PIO1_10/AD6/CT16B1_MAT1 */
        __IO uint32_t PIO2_11; /*!< Offset: 0x070 (R/W) I/O configuration for pin PIO2_11/SCK0 */
        __IO uint32_t R_PIO0_11; /*!< Offset: 0x074 (R/W) I/O configuration for pin TDI/PIO0_11/AD0/CT32B0_MAT3 */
        __IO uint32_t R_PIO1_0; /*!< Offset: 0x078 (R/W) I/O configuration for pin TMS/PIO1_0/AD1/CT32B1_CAP0 */
        __IO uint32_t R_PIO1_1; /*!< Offset: 0x07C (R/W) I/O configuration for pin TDO/PIO1_1/AD2/CT32B1_MAT0 */

        __IO uint32_t R_PIO1_2; /*!< Offset: 0x080 (R/W) I/O configuration for pin nTRST/PIO1_2/AD3/CT32B1_MAT1 */
        __IO uint32_t PIO3_0; /*!< Offset: 0x084 (R/W) I/O configuration for pin PIO3_0/nDTR */
        __IO uint32_t PIO3_1; /*!< Offset: 0x088 (R/W) I/O configuration for pin PIO3_1/nDSR */
        __IO uint32_t PIO2_3; /*!< Offset: 0x08C (R/W) I/O configuration for pin PIO2_3/RI/MOSI1 */
        __IO uint32_t SWDIO_PIO1_3; /*!< Offset: 0x090 (R/W) I/O configuration for pin SWDIO/PIO1_3/AD4/CT32B1_MAT2 */
        __IO uint32_t PIO1_4; /*!< Offset: 0x094 (R/W) I/O configuration for pin PIO1_4/AD5/CT32B1_MAT3 */
        __IO uint32_t PIO1_11; /*!< Offset: 0x098 (R/W) I/O configuration for pin PIO1_11/AD7 */
        __IO uint32_t PIO3_2; /*!< Offset: 0x09C (R/W) I/O configuration for pin PIO3_2/nDCD */

        __IO uint32_t PIO1_5; /*!< Offset: 0x0A0 (R/W) I/O configuration for pin PIO1_5/nRTS/CT32B0_CAP0 */
        __IO uint32_t PIO1_6; /*!< Offset: 0x0A4 (R/W) I/O configuration for pin PIO1_6/RXD/CT32B0_MAT0 */
        __IO uint32_t PIO1_7; /*!< Offset: 0x0A8 (R/W) I/O configuration for pin PIO1_7/TXD/CT32B0_MAT1 */
        __IO uint32_t PIO3_3; /*!< Offset: 0x0AC (R/W) I/O configuration for pin PIO3_3/nRI */
        __IO uint32_t SCK_LOC; /*!< Offset: 0x0B0 (R/W) SCK pin location select Register */
        __IO uint32_t DSR_LOC; /*!< Offset: 0x0B4 (R/W) DSR pin location select Register */
        __IO uint32_t DCD_LOC; /*!< Offset: 0x0B8 (R/W) DCD pin location select Register */
        __IO uint32_t RI_LOC; /*!< Offset: 0x0BC (R/W) RI pin location Register */
        } LPC_IOCON_TypeDef;

        #define LPC_APB0_BASE(0x40000000UL)

        #define LPC_AHB_BASE(0x50000000UL)

        #define LPC_IOCON_BASE(LPC_APB0_BASE + 0x44000)

        #define LPC_SYSCON_BASE(LPC_APB0_BASE + 0x48000)

        #define LPC_SYSCON((LPC_SYSCON_TypeDef *) LPC_SYSCON_BASE)

        #define LPC_IOCON((LPC_IOCON_TypeDef*) LPC_IOCON_BASE )

        #define LPC_GPIO0_BASE(LPC_AHB_BASE+ 0x00000)

        #define LPC_GPIO1_BASE(LPC_AHB_BASE+ 0x10000)

        #define LPC_GPIO2_BASE(LPC_AHB_BASE+ 0x20000)

        #define LPC_GPIO3_BASE(LPC_AHB_BASE+ 0x30000)

        #define LPC_GPIO0((LPC_GPIO_TypeDef*) LPC_GPIO0_BASE )

        #define LPC_GPIO1((LPC_GPIO_TypeDef*) LPC_GPIO1_BASE )

        #define LPC_GPIO2((LPC_GPIO_TypeDef*) LPC_GPIO2_BASE )

        #define LPC_GPIO3((LPC_GPIO_TypeDef*) LPC_GPIO3_BASE )

        //************************************************************************************

        void SysCLK_config(void)

        {

        uint8_t i;

        LPC_SYSCON->PDRUNCFG &= ~(1 << 5);//給系統振蕩器上電

        LPC_SYSCON->SYSOSCCTRL = 0x00000000;//系統振蕩器未旁路,1~12MHz輸入

        for (i = 0; i < 200; i++) __nop();//延時等待振蕩器穩定

        LPC_SYSCON->SYSPLLCLKSEL = 0x00000001;//PLL輸入選擇外部晶體振蕩

        LPC_SYSCON->SYSPLLCLKUEN = 0x00;

        LPC_SYSCON->SYSPLLCLKUEN = 0x01;//先寫0后寫1更新時鐘源

        while (!(LPC_SYSCON->SYSPLLCLKUEN & 0x01));//等待更新完成

        LPC_SYSCON->SYSPLLCTRL = 0x00000023;//M=4、P=2,倍頻后的時鐘為48MHz

        LPC_SYSCON->PDRUNCFG &= ~(1 << 7);//給PLL上電

        while (!(LPC_SYSCON->SYSPLLSTAT & 0x01));//等待PLL鎖定

        LPC_SYSCON->MAINCLKSEL = 0x00000003;//主時鐘選擇PLL倍頻后的時鐘

        LPC_SYSCON->MAINCLKUEN = 0x00;

        LPC_SYSCON->MAINCLKUEN = 0x01;//先寫0后寫1更新時鐘源

        while (!(LPC_SYSCON->MAINCLKUEN & 0x01));//等待更新完成

        LPC_SYSCON->SYSAHBCLKDIV = 0x00000001;//AHB為1分頻,AHB時鐘為48MHz

        LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);//使能GPIO時鐘

        }

        void SystemInit(void)

        {

        SysCLK_config();

        }

        void CLKOUT_EN(uint8_t CLKOUT_DIV)

        {

        LPC_SYSCON->SYSAHBCLKCTRL |= (1<<16);

        LPC_IOCON->PIO0_1=0XD1;

        LPC_SYSCON->SYSAHBCLKCTRL &= ~(1<<16);

        LPC_SYSCON->CLKOUTDIV = CLKOUT_DIV;

        LPC_SYSCON->CLKOUTCLKSEL= 0X00000003;

        LPC_SYSCON->CLKOUTUEN =0X00;

        LPC_SYSCON->CLKOUTUEN =0X01;

        while (!(LPC_SYSCON->CLKOUTUEN & 0x01));

        }

        int main(void)

        {

        SystemInit ();//調用時鐘配置函數

        CLKOUT_EN(48);//CLKOUT輸出1MHz的脈沖

        while(1)

        {

        ;//空循環

        }

        }

        從程序中可以看出,它加入了對“IOCON寄存器”和“GPIO寄存器”的定義,仍然使用結構體的形式。把上述程序拷貝到開發環境中編譯,然后下載到LPC1114中,就可以通過示波器觀察到P0.1腳上的波形了。至于如何通過開發環境生成下載文件,如何把它下載到LPC1114中,會在后面進行討論。



        關鍵詞: 時鐘配置仿

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 平武县| 泰和县| 涟源市| 万源市| 板桥市| 沙雅县| 康定县| 岢岚县| 武山县| 会东县| 民乐县| 丰台区| 福清市| 佳木斯市| 钟山县| 营山县| 磐石市| 香河县| 井研县| 福建省| 沽源县| 敦煌市| 邹城市| 霍山县| 宜君县| 林州市| 拜泉县| 达州市| 胶州市| 大城县| 凯里市| 任丘市| 莱阳市| 康马县| 邮箱| 崇阳县| 益阳市| 壤塘县| 白河县| 额济纳旗| 安远县|