配置完时钟,如何验证时钟的配置准确性呢?
LPC1114带有CLKOUT引脚,此引脚专门用来输出时钟,用示波器观察此引脚,即可看到时钟的频率。
1.硬件配置
CLKOUT引脚位于LPC111X和LPC11CXX单片机的P0.1脚,如下图所示:
2. 软件设计
/*********************************************************/
/* 函数功能:使能CLKOUT脚输出频率 */
/* 入口参数:CLKOUT_DIV,即CLKOUT分频值,1~255 */
/* =0 关闭时钟输出 */
/* 说明: 此函数可用来测试时钟 */
/*********************************************************/
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; // 写CLKOUT_DIV
LPC_SYSCON->CLKOUTCLKSEL= 0X00000003; // CLKOUT时钟源选择为主时钟
LPC_SYSCON->CLKOUTUEN =0;
LPC_SYSCON->CLKOUTUEN =1;
while (!(LPC_SYSCON->CLKOUTUEN & 0x01)); // 确定时钟源更新后向下执行
}
3. CLKOUT_EN程序详解
CLKOUT_EN()函数中,涉及到了6个寄存器:
SYSAHBCLKCTRL:系统AHB时钟控制寄存器
PIO0_1:PIO0_1引脚控制寄存器
CLKOUTDIV:CLKOUT分频寄存器
CLKOUTCLKSEL:CLKOUT时钟源选择寄存器
CLKOUTUEN:CLKOUT时钟源更新寄存器
其中,PIO0_1属于IOCON模块,其他5个属于SYSCON模块。
SYSAHBCLKCTRL:系统AHB时钟控制寄存器
位 | 符号 | 值 | 描述 | 复位值 |
0 | SYS | AHB到APB桥的时钟, 只读位 | 1 | |
0 | 保留 | |||
1 | 允许 | |||
1 | ROM | ROM时钟允许位 | 1 | |
0 | 不允许 | |||
1 | 允许 | |||
2 | RAM | RAM时钟允许位 | 1 | |
0 | 不允许 | |||
1 | 允许 | |||
3 | FLASHREG | FLASH寄存器接口时钟允许位 | 1 | |
0 | 不允许 | |||
1 | 允许 | |||
4 | FLASHARRAY | FLASH阵列访问时钟允许位 | 1 | |
0 | 不允许 | |||
1 | 允许 | |||
5 | I2C | I2C时钟允许位 | 0 | |
0 | 不允许 | |||
1 | 允许 | |||
6 | GPIO | GPIO时钟允许位 | 1 | |
0 | 不允许 | |||
1 | 允许 | |||
7 | CT16B0 | 16位定时计数器0时钟允许位 | 0 | |
0 | 不允许 | |||
1 | 允许 | |||
8 | CT16B1 | 16位定时计数器1时钟允许位 | 0 | |
0 | 不允许 | |||
1 | 允许 | |||
9 | CT32B0 | 32位定时计数器0时钟允许位 | 0
| |
0 | 不允许 | |||
1 | 允许 | |||
10 | CT32B1 | 32位定时计数器1时钟允许位 | 0 | |
0 | 不允许 | |||
1 | 允许 | |||
11 | SSP0 | SPI0时钟允许位 | 1 | |
0 | 不允许 | |||
1 | 允许 | |||
12 | UART | UART时钟允许位 | 0 | |
0 | 不允许 | |||
1 | 允许 | |||
13 | ADC | ADC时钟允许位 | 0 | |
0 | 不允许 | |||
1 | 允许 | |||
14 | – | – | 保留 | 0 |
15 | WDT | WDT时钟允许位 | 0 | |
0 | 不允许 | |||
1 | 允许 | |||
16 | IOCON | IO配置模块时钟允许位 | 0 | |
0 | 不允许 | |||
1 | 允许 | |||
17 | CAN | CAN模块时钟允许位 | 0 | |
0 | 不允许 | |||
1 | 允许 | |||
18 | SSP1 | SPI1时钟允许位 | 0 | |
0 | 不允许 | |||
1 | 允许 | |||
31:19 | – | – | 保留 | 0x00 |
第9行:对SYSAHBCLKCTRL的bit16写1,即开启IOCON的时钟。因为下面我们要把P0.1脚设置为CLKOUT引脚,必须要开启IOCON时钟才可以切换引脚的功能。
第11行:对SYSAHBCLKCTRL的bit16写0,即关闭IOCON的时钟。这个时钟可以在系统初始化的时候,打开而不用关闭,之所以要关闭,是为了节省功耗。等需要改变引脚功能的时候打开,引脚功能改变后,关闭IOCON时钟。
PIO0_1寄存器:
位 | 符号 | 值 | 描述 | 复位值 |
2:0 | FUNC | 功能选择位 | 000 | |
0x0 | 选择功能PIO0_1. | |||
0x1 | 选择功能CLKOUT. | |||
0x2 | 选择功能CT32B0_MAT2. | |||
4:3 | MODE | 模式选择位 | 10 | |
0x0 | 无上拉下拉电阻 | |||
0x1 | 允许下拉电阻 | |||
0x2 | 允许上拉电阻 | |||
0x3 | 中继模式 | |||
5 | HYS | 滞后 | 0 | |
0 | 不允许 | |||
1 | 允许 | |||
9:6 | – | – | 保留 | 0011 |
10 | OD | 伪开漏模式选择 | 0 | |
0 | 标准GPIO输出 | |||
1 | 开漏输出 | |||
31:11 | – | – | 保留 | – |
第10行,给PIO0_1寄存器中写入0xD1,即把P0.1引脚设置为CLKOUT引脚。
CLKOUTDIV:CLKOUT分频寄存器
位 | 符号 | 描述 | 复位值 |
7:0 | DIV | 分频值 0: 禁止CLKOUT. 1: 分频值1. to 255: 分频值255. | 0x00 |
31:8 | – | 保留 | 0x00 |
该寄存器决定了CLKOUT时钟源输出的频率为:CLKOUT时钟源频率/DIV。
第12行,给CLKOUTDIV寄存器写入分频值。
CLKOUTCLKSEL:CLKOUT时钟源选择寄存器
位 | 符号 | 值 | 描述 | 复位值 |
1:0 | SEL | CLKOUT时钟源选择 | 0x00 | |
0x0 | IRC振荡器 | |||
0x1 | 系统振荡器 | |||
0x2 | 看门狗振荡器 | |||
0x3 | 主时钟 | |||
31:2 | – | – | 保留 | 0x00 |
第13行,给CLKOUTCLKSEL寄存器写入了0x03,即选择主时钟作为CLKOUT的输出时钟。因为我们要观察主时钟是否配置正确。
CLKOUTUEN:CLKOUT时钟源更新寄存器
位 | 符号 | 值 | 描述 | 复位值 |
0 | ENA | CLKOUT时钟源更新寄存器 | 0x0 | |
0 | 没有改变 | |||
1 | 更新时钟源 | |||
31:1 | – | – | 保留 | 0x00 |
第14、15行,当CLKOUTCLKSEL中的值改变以后,需要对此更新寄存器先写0再写1达到时钟更新的目的。
第16行,观察该寄存器的状态,确定更新成功后跳出while循环向下执行。
完成以上步骤,就可以实现CLKOUT输出时钟了。
例如:把内部IRC时钟倍频4倍后变为48MHz,利用CLKOUT函数,设置DIV为48,即在CLKOUT引脚上输出1MHz的时钟;如果DIV为96,即在CLKOUT引脚上将输出500KHz的时钟。
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』