前情提要:
老久之前调的NXP lpc-845板子,现在都不搞嵌入式了,也许有人有需要,所以写上了,当时IIC的一块键盘板用逻辑分析仪抓出来的数据不对,未知原因内部晶振不准,频率配的是对的,出来的频率就是不对,板子奇奇怪怪的问题太多了,遂用外部晶振
以下就是配置过程,代码块就是实际代码
查询数据手册,对着手册进行配置
1.使能SWM() 和 IOCON(输入/输出控制) 寄存器(SYSAHBCLKCTRL寄存器)
1.使能SWM bit 7 ----- 1 << 7
2.使能IOCON bit 18 — 1 << 18
LPC_SYSCON->SYSAHBCLKCTRL[0]|= (SWM | IOCON);
2.寄存器控制断电模式(PDRUNCFG 寄存器)–PowerDown
POWER_DisablePD
LPC_SYSCON->PDRUNCFG &= ~(0x20U);
- 配置IO口的输入情况(PIO0_8、PIO0_9 寄存器)
LPC_IOCON->PIO0_8 &= ~0x18U; // 00 为无上拉、下拉电阻
LPC_IOCON->PIO0_9 &= ~0x18U;
4.开启外部晶振输入(PINENABLE0 寄存器)
LPC_SWM->PINENABLE0 &= ~(0x80U | 0x100U); //使能
5.配置系统震荡寄存器(SYSOSCCTRL)
LPC_SYSCON->SYSOSCCTRL &= 0x1U ;
6.选择外部时钟源(EXTCLKSEL 寄存器)
因为CLK_IN 是有源外部晶振,当前只用无源外部晶振,所以选0;
SYSCON->EXTCLKSEL &= ~SYSCON_EXTCLKSEL_SEL_MASK; // SYSCON_EXTCLKSEL_SEL_MASK 为0x1U;
7.使能系统震荡寄存器(PDRUNCFG)
SYSCON->PDRUNCFG &= ~SYSCON_PDRUNCFG_SYSOSC_PD_MASK;
//SYSCON_PDRUNCFG_SYSOSC_PD_MASK = 0x20U;
8.控制锁相环的电源(PDRUNCFG 寄存器)
SYSCON->PDRUNCFG |= SYSCON_PDRUNCFG_SYSPLL_PD_MASK;
//其中SYSCON_PDRUNCFG_SYSPLL_PD_MASK = 0x80
9.设置锁相环时钟源(SYSPLLCLKSEL 寄存器)
LPC_SYSCON->SYSPLLCLKSEL |= (LPC_SYSCON->SYSPLLCLKSEL & (~0x3U)) | 1U;
10.更新PLL时钟源(SYSPLLCLKUEN )
LPC_SYSCON->SYSPLLCLKUEN = 0; // Toggle update register
LPC_SYSCON->SYSPLLCLKUEN = 1;
while (!(LPC_SYSCON->SYSPLLCLKUEN & 1)) __NOP(); // 等待寄存器稳定
- 配置锁相环的值(SYSPLLCTRL 寄存器)
锁相环去配想要的时钟
具体说明如下
LPC_SYSCON->SYSPLLCTRL = SYSPLLCTRL_VAL;
// SYSPLLCTRL_VAL = 0x41 我配的0x41
12.配置电源(PDRUNCFG )
/* Power up PLL after setup changes */
SYSCON->PDRUNCFG &= ~SYSCON_PDRUNCFG_SYSPLL_PD_MASK;
// SYSCON_PDRUNCFG_SYSPLL_PD_MASK = 0x80;
13.等待锁相环稳定(SYSPLLSTAT)
while ((SYSCON->SYSPLLSTAT & SYSCON_SYSPLLSTAT_LOCK_MASK) == 0U)
{
}
// SYSCON_SYSPLLSTAT_LOCK_MASK = 0x1;
14.设置系统时钟分频系数(SYSAHBCLKDIV 寄存器)
LPC_SYSCON->SYSAHBCLKDIV = 1;
15.设置主时钟参考源(MAINCLKSEL)
LPC_SYSCON->MAINCLKSEL = 1; // Update the actual register
LPC_SYSCON->MAINCLKUEN = 0; // Toggle update register
LPC_SYSCON->MAINCLKUEN = 1;
while (!(LPC_SYSCON->MAINCLKUEN & 1)) __NOP(); // Wait until updated
16.选择主函数时钟源
LPC_SYSCON->MAINCLKPLLSEL = 1;
LPC_SYSCON->MAINCLKPLLUEN = 0; // Toggle update register
LPC_SYSCON->MAINCLKPLLUEN = 1;
while (!(LPC_SYSCON->MAINCLKPLLUEN & 1)) __NOP(); // Wait until updated
至此就切换到外部时钟了,亲测有跑起来了,波形用示波器测过了,准准的