时钟配置的仿真
从图中可以清楚地看出配置后各时钟的分配情况(如果时钟不对,可能是没有运行程序,只要点击工具条上的“Run”按钮(或直接按F5)就可以了),非常直观。大家还可对照前面的程序,自行更改相关内容,再仿真看看变化,以加深对时钟配置的了解。要更改仿真中的外部晶振的值可点击菜单Peripherals->Clocking & Power Control->System Oscillator Control进行更改,要更改内部RC振荡的值可点击菜单Peripherals->Clocking & Power Control->Internal Oscillator Control进行更改,要更改看门狗振荡的值可点击菜单Peripherals->Clocking & Power Control->从图中可以清楚地看出配置后各时钟的分配情况(如果时钟不对,可能是没有运行程序,只要点击工具条上的“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];
时钟配置仿 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)