年前,买了一块LPC1768的开发板,这是我第一次真正的接触ARM,随板子一起来的还有一些例程,第一个例程是一个流水灯程序,这个程序涉及到时钟配置,节拍定时器,GPIO口配置,我决定从这个例程开始入门。程序执行的第一步是复位,复位完成后初始化时钟,这个我在《
LPC1768 学习(一)系统初始化》中提过,CPU时钟是有锁相环0和CPU时钟配置寄存器共同决定的。锁相环可以把外部时钟倍频到较高频率,PLL0输出频率是:
Fcco = (2xMxFin)/N;
M值是PLL0CFG寄存器中MSEL0(倍频值)加一,N值NSEL0(预分频值)加一。N值得取值范围是1~32,而M的取值是在较高的振荡器频率下(超过1MHz)允许范围是6~512。
得到PLL0输出值之后,在经过CPU时钟配置寄存器就可以得到CPU时钟。
在这个system_lpc17xx.c文件中,修改#define PLL0CFG_Val 0x00050063的宏定义值就可以了。
例如:00050063这个状态下PLL0输出400MHz。
M = 0x63(16进制) + 1 = 100(10进制);
N = 0x05 + 1 = 6;
Fcco = 2X12x100/6 = 400M
在经过CPU时钟配置寄存器4分频就变成100M。
在路虎的程序中我发现一个比较好的地方,就是利用时钟节拍定时器定时。
在主函数中写下如下语句就能让节拍定时器1ms中断一次。
if (SysTick_Config(SystemCoreClock / 1000))/1ms进入一次中断/
{
while (1); /* 错误情况下就停在这里,对于一个while(1)死循环表示难受,但是还是保留吧 */
}
这个函数的原型是
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk)
return (1); /* Reload value impossible */
SysTick->LOAD = ticks - 1; /* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */
SysTick->VAL = 0; /* Load the SysTick Counter Value */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
return (0); /* Function successful */
}
#define __INLINE __inline
#define __STATIC_INLINE static __inline
这个函数的修饰一看就明白,静态内连,但是编译器怎么解释还是看标准是怎么定的,inline是C99标准,想具体了解,可以移步http://blog.csdn.net/hanchaoman/article/details/7270345,这里写的比较清楚。
这个函数就不解释,就是节拍函数的初始化,需要提一下的是这个函数的形参SystemCoreClock /1000,SystemCoreClock 是CPU频率,假设是100M的情况下,100M/1000 = 100K,节拍定时器在100M的时钟下计数100K次,1S可以溢出1000次,就是说1ms溢出一次,所以就是定时1ms。如果想定时10ms,就把除数改成100。