時鐘配置的仿真
要進(jìn)行仿真,必須先把程序進(jìn)行編譯,正確無誤后才能進(jìn)入到仿真模式。為此,先給出主函數(shù)的內(nèi)容,如下。
本文引用地址:http://m.butianyuan.cn/article/201611/316321.htmvoid SystemInit(void)
{
SysCLK_config();//調(diào)用時鐘配置函數(shù)
}
int main(void)
{
SystemInit ();//調(diào)用系統(tǒng)初始化函數(shù)
while(1)
{
;//空循環(huán)
}
}
在上述程序中可以看出,主函數(shù)的寫法和普通單片機(jī)開發(fā)的沒有什么兩樣,都有一個死循環(huán),因為這里只做時鐘配置的仿真,所以在調(diào)用時鐘配置函數(shù)后就進(jìn)行一個空循環(huán)。只有三點(diǎn)要特別注意一下:一是這里的main函數(shù)必須是整型(int型)的;二是在程序結(jié)束的最后一行要有一個換行(即要回一下車),否則會有警告出現(xiàn);三是在項目自動加載的啟動文件中規(guī)定,程序中必須要有一個系統(tǒng)初始化的函數(shù)(SystemInit),否則程序不能編譯鏈接。所以在上述程序中雖然只調(diào)用一個時鐘配置函數(shù),但還是要把它放入到系統(tǒng)初始化函數(shù)中去供主函數(shù)調(diào)用。
但是,把上述函數(shù)及前面的時鐘配置函數(shù)寫到主程序后,還是編譯不過的,會報兩條錯誤,說“uint8_t”和“LPC_SYSCON”沒有定義。這是因為程序沒有包含一些特定的頭文件,在這些頭文件內(nèi)才有相關(guān)變量的申明。要程序順利編譯通過,必須要把這些頭文件包含進(jìn)來。但是,由于開發(fā)LPC1114所需要的頭文件很多,且有些頭文件還有彼此的依賴關(guān)系,對于不同的開發(fā)環(huán)境,定義的名稱也不一致,因此,為了減小學(xué)習(xí)的挫折感,先快速的把我們的第一個程序運(yùn)行起來,下面用不包含頭文件的方式,把程序所用到的內(nèi)容全部都列出來,這樣只要把下面的程序復(fù)制到開發(fā)環(huán)境中,就可以順利通過編譯了。
程序代碼如下:
#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);//給系統(tǒng)振蕩器上電
LPC_SYSCON->SYSOSCCTRL = 0x00000000;//系統(tǒng)振蕩器未旁路,1~12MHz輸入
for (i = 0; i < 200; i++) __nop();//延時等待振蕩器穩(wěn)定
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 ();//調(diào)用時鐘配置函數(shù)
while(1)
{
;//空循環(huán)
}
}
(不要忘記最后一行有一個強(qiáng)制換行)
從上面可以看到,變量的申明都是以結(jié)構(gòu)體的形式出現(xiàn)的,較為復(fù)雜,現(xiàn)在先不去討論它。先把上述程序編譯鏈接(點(diǎn)擊工具條上的“Rebuild”按鈕)無誤后,點(diǎn)擊工具條上的“Start/Stop Debug Session”按鈕(或按Ctrl+F5)進(jìn)入到調(diào)試模式。點(diǎn)擊菜單Peripherals->Clocking & Power Control->Clock Generation Schematic,將會出現(xiàn)一個顯示時鐘結(jié)構(gòu)的對話框,如下圖所示。
從圖中可以清楚地看出配置后各時鐘的分配情況(如果時鐘不對,可能是沒有運(yùn)行程序,只要點(diǎn)擊工具條上的“Run”按鈕(或直接按F5)就可以了),非常直觀。大家還可對照前面的程序,自行更改相關(guān)內(nèi)容,再仿真看看變化,以加深對時鐘配置的了解。要更改仿真中的外部晶振的值可點(diǎn)擊菜單Peripherals->Clocking & Power Control->System Oscillator Control進(jìn)行更改,要更改內(nèi)部RC振蕩的值可點(diǎn)擊菜單Peripherals->Clocking & Power Control->Internal Oscillator Control進(jìn)行更改,要更改看門狗振蕩的值可點(diǎn)擊菜單Peripherals->Clocking & Power Control->Watchdog Oscillator Control進(jìn)行更改。甚至你還可以看到在設(shè)置錯誤(如把PLL倍頻后的時鐘設(shè)置了超過50MHz)的情況下,主時鐘會自動轉(zhuǎn)到默認(rèn)的12MHz內(nèi)部RC振蕩中去執(zhí)行,真是非常了不起。
除了仿真以外,LPC1114還提供了一個時鐘輸出端口CLKOUT,它被復(fù)用在P0.1引腳,可以通過程序控制它來輸出內(nèi)部RC振蕩時鐘、系統(tǒng)振蕩器時鐘(外部晶振)、看門狗振蕩時鐘和主時鐘。
下面就給出一個CLKOUT引腳輸出時鐘的函數(shù),如下:
void CLKOUT_EN(uint8_t CLKOUT_DIV)
{
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<16);//使能IOCON時鐘
LPC_IOCON->PIO0_1=0XD1;//把P0.1設(shè)置為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的主時鐘,分頻系數(shù)CLKOUT_DIV也取48,則該函數(shù)執(zhí)行完后,LPC1114的P0.1腳就會有1MHz的脈沖輸出,可通過示波器來進(jìn)行觀察。
在上述程序中可以看出,要改變一個具有復(fù)用的引腳功能時,必須先打開IOCON的時鐘,否則配置不生效!而在配置完成后,要及時關(guān)閉IOCON時鐘,以降低功耗。關(guān)于IOCON的配置將會在后面討論GPIO時進(jìn)行詳細(xì)討論,這里先不贅述。下面給出的是“CLKOUT時鐘源選擇寄存器(CLKOUTCLKSEL)”的位結(jié)構(gòu)。
位 | 符號 | 值 | 描述 | 復(fù)位值 |
1∶0 | SEL (CLKOUT時鐘源) | 00 | IRC振蕩器 | 0 |
01 | 系統(tǒng)振蕩器 | |||
10 | 看門狗振蕩器 | |||
11 | 主時鐘 | |||
31∶2 | - | - | 保留 | 0 |
實(shí)驗時可根據(jù)上表來改變CLKOUTCLKSEL的值,從而觀察不同的時鐘頻率輸出。
由于在CLKOUT函數(shù)中加入了一些新的寄存器(比如IOCON、GPIO等),所以程序必須在頭文件中把相關(guān)的申明包含進(jìn)來,才能正確編譯通過。這里同前面一樣,為了方便,使用不包含頭文件的形式來書寫程序,下面給出其全部內(nèi)容。
#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);//給系統(tǒng)振蕩器上電
LPC_SYSCON->SYSOSCCTRL = 0x00000000;//系統(tǒng)振蕩器未旁路,1~12MHz輸入
for (i = 0; i < 200; i++) __nop();//延時等待振蕩器穩(wěn)定
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 ();//調(diào)用時鐘配置函數(shù)
CLKOUT_EN(48);//CLKOUT輸出1MHz的脈沖
while(1)
{
;//空循環(huán)
}
}
從程序中可以看出,它加入了對“IOCON寄存器”和“GPIO寄存器”的定義,仍然使用結(jié)構(gòu)體的形式。把上述程序拷貝到開發(fā)環(huán)境中編譯,然后下載到LPC1114中,就可以通過示波器觀察到P0.1腳上的波形了。至于如何通過開發(fā)環(huán)境生成下載文件,如何把它下載到LPC1114中,會在后面進(jìn)行討論。
評論