至此我们知道Fclkout = M× Fclkin = (FCCO) ⁄ (2 × P),我们要找出这个公式的两个未知量,首先是M(MSEL),存放于以下寄存器:
7.jpg (49.52 KB)
2010-5-26 07:31
以及以下语句:
LPC_SYSCON->SYSPLLCTRL
= SYSPLLCTRL_Val;//★★★★★
#define SYSPLLCTRL_Val
0x00000025
所以MESL=0x101,同时PSEL=0x01。
LPC_SYSCON->SYSPLLCLKSEL
= SYSPLLCLKSEL_Val;/*选择PLL输入★★★★*/
#define SYSPLLCLKSEL_Val
0x00000001
8.jpg (32.03 KB)
2010-5-26 07:31
可以看出,Fclkin来自系统外部振荡器,也就是外部12MHz晶振。
Fclkout = M× Fclkin = (FCCO) ⁄ (2 × P)=72MHz
这个就是主时钟频率,也是LPC1343可以达到的最大工作频率。前文亦提到,APB设备时钟来自主时钟经过分频器提供,所以AHB分频数来自:
LPC_SYSCON->SYSAHBCLKDIV
= SYSAHBCLKDIV_Val;//选择AHB分频数★★★
#define SYSAHBCLKDIV_Val
0x00000001
结论是1分频,所以到达定时器时钟入口处的时钟就是72MHz/1=72MHz。
接下来就是定时器内部的事情了,接下来要得到定时器内部的预分频值,但是在定时器初始化语句里面并没有看到相应的设置,于是翻阅user.manual.lpc13xx,找到如下描述
9.jpg (16.92 KB)
2010-5-26 07:31
This causes the TC to increment on every PCLK when PR = 0, every 2 PCLKs when PR = 1, etc
所以我们知道两点,第一,预分频值PR默认为0,第二,当预分配值PR=0时,causes the TC to increment on every PCLK,即分频数为1。
所以我们最终得到32位定时器的计数时钟为72MHz。计数一次所需要的时间是(1/72000000)s。
init_timer32(0, TIME_INTERVAL*10);
#define TIME_INTERVAL
(720000-1)//减1是因为计数值为0~719999而不是1~720000
PS:在此原宏定义为:
#define TIME_INTERVAL
(SystemCoreClock/100 - 1)
笔者其实在此将SystemCoreClock/100计算出来了,因为SystemCoreClock是72MHz。
T=1 x 10 x 720000 / 72000000=0.01=100ms
将定时器中断服务作如下修改:
void TIMER32_0_IRQHandler(void)
if ( LPC_TMR32B0->IR & 0x01 )
LPC_TMR32B0->IR = 1;
/* clear interrupt flag */
if ( LPC_TMR32B0->IR & (0x1<<4) )
LPC_TMR32B0->IR = 0x1<<4;
/* clear interrupt flag */
编译,运行,每隔100ms便进入一次中断服务函数,LED以100ms间隔闪烁。
|