LPC2103芯片的时钟系统

更新时间:2023-11-24 09:46:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

了解LPC2103芯片的时钟系统。分清晶振频率(FOSC)、处理器时钟(Fcclk)、系统外设时钟(Fpclk)、CCO时钟。

通过对锁相环PLL和VPB分频器的配置,实现我们想要的时钟系统。

我们开始。先看下面的图。

(图一 几种频率的关系。括号里是有关的寄存器名) PLL锁相环:可以通过PLL升频和增强抗干扰性能。

VPB分频器: 对PLL时钟分频,供给片上外设使用。

区分下面四种时钟频率的概念:

晶振频率(FOSC):外部晶振的频率,我们的板子焊的是11.0592M的。

处理器时钟(Fcclk):芯片执行指令的频率。Fcclk = FOSC × PLL倍频。相关寄存器:PLLCFG[4:0]。 VPB时钟(Fpclk):给片内外设提供的时钟频率。Fpclk=Fcclk/PLL分频。相关寄存器:APBDIV CCO时钟:不用管它是干什么的。只要把它设置成156MHz~320MHz就行。相关寄存器:PLLCFG[6:5]

PLL配置需要的寄存器如下:

PLLCON:PLL控制寄存器。控制PLL使能和PLL连接的状态。 PLLCFG:PLL配置寄存器。设置PLL倍频和PLL分频。 PLLSTAT:PLL状态寄存器。只读寄存器,读出PLL状态。

PLLFEED:PLL馈送寄存器。将值0xAA、0x55写入PLLFEED,才能使PLLCON和 PLLCFG的配置生效。

VPB配置需要的寄存器 APBDIV:VPB分频器。

计算频率值:

Fosc = 11.0592MHz //外部晶振频率

Fcclk = 11.0592*6 = 66.3552MHz //处理器时钟(Fcclk)必须低于芯片的最高频率70MHz Fpclk = Fcclk/4 = 16.5888MHz //VPB时钟(Fpclk) Fcco = 66.3552*2*P = 265.4208MHz //必须在156MHz~320MHz之间

设置过程。

先对PLLCFG设置,PLLCON置成使能,但不连接的状态。等待PLL频率锁定以后,最后把PLL设置成连接入状态,把经过PLL倍增的频率接入,作为系统时钟使用。

下面是程序例子,在main函数中调用。 void Init_VPB_PLL() {

//Fosc = 11.0592MHz

//Fcclk = 11.0592*6 = 66.3552MHz //Fcco = 66.3552*2*P =265.4208MHz //Fpclk =16.5888MHz

// 配置VPB分频器相关寄存器

APBDIV = 0x00; // Fcclk * 1/4

//配置PLL锁相环相关寄存器

PLLCFG = 0x25; // 0 01 00101 分频器值(P=2) 倍增器值(M=6)

//PLLCFG=(6-1)|(1<<5);

PLLCON = 0x01; // PLLE=1 PLL使能 但PLL未连接

PLLFEED = 0xAA;// 0xAA 和0x55,为固定数据,写入以后。配置才会生效。 PLLFEED = 0x55;

while((PLLSTAT&(1<<10))==0); //等待解锁;PLLSTAT第十位0为未锁1为锁住

PLLCON = 0x03; //PLLE=1 PLLC=1 PLL使能并连接 PLLFEED = 0xAA; PLLFEED = 0x55; }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 配置

/* 系统设置, Fosc、Fcclk、Fcco、Fpclk必须定义*/

#define Fosc 11059200 //晶振频率,10MHz~25MHz,应当与实际一至

#define Fcclk (Fosc * 6) //系统频率,必须为Fosc的整数倍(1~32),且<=60MHZ #define Fcco (Fcclk * 4) //CCO频率,必须为Fcclk的2、4、8、16倍,范围为156MHz~320MHz #define Fpclk (Fcclk / 4) * 1 //VPB时钟频率,只能为(Fcclk / 4)的1, 2 ,4倍

PLLCON = 1;//PLL工作 但是没有连接 /*设定VPBDIV的时钟*/

#if ((Fcclk / 4) / Fpclk) == 1 VPBDIV = 0;//APB 总线时钟为处理器时钟的1/4 #endif

#if ((Fcclk / 4) / Fpclk) == 2

VPBDIV = 2;//APB 总线时钟为处理器时钟的1/2 #endif

#if ((Fcclk / 4) / Fpclk) == 4

VPBDIV = 1;//APB 总线时钟与处理器时钟相同 #endif

/*设定分频和倍频系数*/

#if (Fcco / Fcclk) == 2

PLLCFG = ((Fcclk / Fosc) - 1) | (0 << 5);//分频为1倍频为1 #endif

#if (Fcco / Fcclk) == 4

PLLCFG = ((Fcclk / Fosc) - 1) | (1 << 5);//分频为2倍频为2 #endif

#if (Fcco / Fcclk) == 8

PLLCFG = ((Fcclk / Fosc) - 1) | (2 << 5);//分频为4倍频为3 #endif

#if (Fcco / Fcclk) == 16

PLLCFG = ((Fcclk / Fosc) - 1) | (3 << 5);//分频为8倍频为3 #endif

PLLFEED = 0xaa;

PLLFEED = 0x55;

while((PLLSTAT & (1 << 10)) == 0);//等待解锁;PLLSTAT第十位0为未锁1为锁住 PLLCON = 3;

PLLFEED = 0xaa; PLLFEED = 0x55;

我用IAR软件

哪位大侠说一下FIQ使用的流程! #include \#include #include

#define VPBDIV (*((volatile unsigned char *) 0xE01FC100)) #define IOPIN (*((volatile unsigned long *) 0xE0028000))

#define Fosc 11059200 //外部晶振频率 11.0592M

#define Fcclk (Fosc * 4) //处理器时钟 Fosc * 4 #define Fpclk (Fcclk / 4) * 1 //VPB时钏频率 #define Fcco (Fcclk * 4) //PLL的操作频 #define LED1 1 << 17 #define LED2 1 << 18 #define LED3 1 << 19 #define LED4 1 << 20

__fiq __arm void fiq_handler(void) {

IOCLR = LED1|LED2|LED3|LED4; }

void PLL_Init() {

/* 设置系统各部分时钟 */

PLLCON = 1; //使能PLL£但不连接 PLLCON.E = 1,PLLCON.C = 0

if ((Fpclk / (Fcclk / 4)) == 1)

VPBDIV = 0; // VPBDIV = 0,则Fpclk = 1/4 Fcclk (复位值) if ((Fpclk / (Fcclk / 4)) == 2)

VPBDIV = 2; //VPBDIV = 2,则Fpclk = 1/2 Fcclk if ((Fpclk / (Fcclk / 4)) == 4)

VPBDIV = 1; //VPBDIV = 1,则Fpclk = Fcclk; if ((Fcco / Fcclk) == 2)

PLLCFG = ((Fcclk / Fosc) - 1) | (0 << 5); if ((Fcco / Fcclk) == 4)

PLLCFG = ((Fcclk / Fosc) - 1) | (1 << 5); if ((Fcco / Fcclk) == 8)

PLLCFG = ((Fcclk / Fosc) - 1) | (2 << 5); if ((Fcco / Fcclk) == 16)

PLLCFG = ((Fcclk / Fosc) - 1) | (3 << 5);

PLLFEED = 0xaa; PLLFEED = 0x55;

while((PLLSTAT & (1 << 10)) == 0); PLLCON = 0x00000011; PLLFEED = 0xaa; PLLFEED = 0x55; }

void GPIO_Init() {

PINSEL0 = 0x00000000;

PINSEL1 = 0x00000000; //设置P0.16为EINT0

IODIR = LED1|LED2|LED3|LED4; IOSET = LED1|LED2|LED3|LED4; }

void VIC_Init()

{

VICIntEnClear = 0xffffffff; //中断全部使能关闭 VICSoftIntClear = 0xffffffff; //清除软件中断 VICProtection = 0; //清除VIC保护

VICVectAddr = 0; //清除向量IRQ中断服务程序地址 VICDefVectAddr = 0; //清除非向量IRQ中断服务程序地址

//清除所有向量IRQ地址

VICVectAddr0 = VICVectAddr1 = VICVectAddr2 = VICVectAddr3 = \\ VICVectAddr4 = VICVectAddr5 = VICVectAddr6 = VICVectAddr7 = \\ VICVectAddr8 = VICVectAddr9 = VICVectAddr10 = VICVectAddr11 = \\ VICVectAddr12 = VICVectAddr13 = VICVectAddr14 = VICVectAddr15 = 0;

VICVectCntl0 = VICVectCntl1 = VICVectCntl2 = VICVectCntl3 = \\ VICVectCntl4 = VICVectCntl5 = VICVectCntl6 = VICVectCntl7 = \\ VICVectCntl8 = VICVectCntl9 = VICVectCntl10 = VICVectCntl11 = \\ VICVectCntl12 = VICVectCntl13 = VICVectCntl14 = VICVectCntl15 = 0; }

void EINT0_Init()

{

PINSEL1 = PINSEL1 | 0x01; //设定P0.16连接到EINT0

VICIntSelect = 1<<14; //选择EINT0 为FIQ中断 VICIntEnable = 1<<14;

EXTMODE = 0x00; //使用电平触发 EXTPOLAR = 0x00; //低或下降沿 EXTINT = 0x01; }

void main(void) {

//PLL_Init();

GPIO_Init();

__disable_interrupt(); VIC_Init();

EINT0_Init(); __enable_interrupt();

while(1) { }; }

设置P0.16为EINT0,低电平触发,接是按键,调试的时候怎么都进不了中断?

本文来源:https://www.bwwdw.com/article/ukzt.html

Top