在线时间58 小时
UID175586
注册时间2010-3-14
NXP金币0
TA的每日心情 | 奋斗 2017-1-17 10:45 |
---|
签到天数: 3 天 [LV.2]偶尔看看I
高级会员
- 积分
- 780
- 最后登录
- 2023-11-17
|
本帖最后由 suyong_yq 于 2016-12-30 01:42 编辑
拿到LPC824-Lite开发板有一段时间了,抽空阅读了一下LPC824的手册和相关的代码资料,非常感兴趣,打算研究一下这块板子。
看了现有的代码,无论是LPC824-Lite开发板资料中的固件库,或者是官方提供的LPCOpen的固件库,用起来都比较麻烦(build一个最简单的工程至少需要编译三次,第一次是驱动库,第二次是板子库,第三次才是应用程序)。其中各个文件的关联度比较高,想要单独提取驱动代码对原有代码改动颇多,而且解不完的编译错误让我有点头大。万般无奈之下,我不得不重新构建代码库,刚好可以完整地学习一下这款芯片。不过基础代码还是源自于官方的LPCOpen固件库。
万里之行,始于时钟,对于应用程序来讲,第一步永远是配置系统时钟。system_LPC82x.c中用于初始时钟的SystemInit()函数中的代码有点冗余(各种宏定义),配置时钟要自己搞定!通过阅读手册可以了解到,LPC824单片机系统中有一个Main Clock,系统中绝大多数模块使用的时钟都是源自于此,而这个Main Clock默认使用内部的IRC 12MHz时钟、外部晶振或是时钟发生器输出时钟或是PLL倍频时钟。PLL是个好东西,可以基于较低频率的时钟信号产生较高频率的时钟信号,但是调试过程一般比较复杂(此时想起以前调试K60的MCG模块,仍心有余悸),最好能够在调试产生时钟是通过示波器观察到PLL的输出,从而实实在在地看到PLL的输出信号。
啊哈,通过阅读手册得知,芯片的CLKOUT信号可以输出各种时钟,其中就包含Main Clock。
图1
通过使用示波器观察CLKOUT输出的时钟信号,就可以在调试时钟系统时实实在在观察时钟输出的情况啦。
经过一番调试,终于在示波器中输出基础的时钟信号了,分享代码如下。
由于没有找到配置CLKOUT相关的API,自定义一个配置CLKOUT信号的函数:
- /*!
- * @brief 定义CLKOUT信号输出时钟源选项
- */
- typedef enum
- {
- eSYSCON_ClkoutSource_IRC12MHz = 0, /*!< IRC oscillator. */
- eSYSCON_ClkoutSource_OSC = 1, /*!< Crystal oscillator (SYSOSC). */
- eSYSCON_ClkoutSource_WatchdogClock = 2, /*!< Watchdog oscillator. */
- eSYSCON_ClkoutSource_MainClock = 3, /*!< Main clock. */
- } SYSCON_ClkoutSource_T;
- /*!
- * @brief 配置CLKOUT信号输出
- *
- * CLKOUT信号需要绑定到引脚上才能真正被外部观测设备观察到,因此还需要SWM及IOCON(默认配置)配合使用.
- *
- * @param source 选择输出时钟源, 参见#SYSCON_ClkoutSource_T.
- * @param divider 设定输出时信号的分频值, 有效范围为1-255, 当为0时关闭输出.
- */
- static inline void Chip_SYSCON_ConfigClkoutOutput(SYSCON_ClkoutSource_T source, uint32_t divider)
- {
- LPC_SYSCON->CLKOUTSEL = (uint32_t)source; /* 选定时钟信号源. */
- LPC_SYSCON->CLKOUTDIV = divider; /* 设定输出分频值. */
- /* 在硬件上更新CLKOUT时钟源的设定. */
- LPC_SYSCON->CLKOUTUEN = 0x0;
- LPC_SYSCON->CLKOUTUEN = 0x1;
- }
复制代码
代码1
在system_LPC82x.c文件中清空SystemInit()函数。
- void SystemInit(void)
- {
- /* 启用访问SWM和IOCON模块的时钟。其中:
- * - SWM模块将用于通过引脚接入晶振信号到芯片内部
- * - IOCON模块将用于配置时钟系统
- */
- LPC_SYSCON->SYSAHBCLKCTRL |= ( (1 << 7) | /* Enables SWM clock */
- (1 << 18) ); /* Enables IOCON clock */
- /* 配置引脚引入晶振信号 */
- LPC_IOCON->PIO0_8 &= ~(3 << 3); /* no pull-down/pull-up */
- LPC_IOCON->PIO0_9 &= ~(3 << 3); /* no pull-down/pull-up */
- LPC_SWM->PINENABLE0 &= ~(3 << 6); /* enable XTALIN/XTALOUT func.*/
- }
复制代码
代码2
配置晶振部分的代码可以用于在CLKOUT上观察外部晶振产生的OSC时钟信号。
然后编写main.c文件如下:
- /* main.c */
- #include "app_inc.h"
- #include "chip_swm_8xx.h"
- #include "chip_syscon_8xx.h"
- #include "chip_iocon_8xx.h"
- #include "chip_clock_8xx.h"
- void App_ClkoutOutputMainClock(void);
- /*
- * 应用程序入口.
- */
- int main(void)
- {
- /* 配置CLKOUT输出Main Clock. */
- App_ClkoutOutputMainClock();
- while (1)
- {
- __NOP();
- }
- }
- /* 设定CLKOUT在PIO0_6引脚输出主时钟信号. */
- void App_ClkoutOutputMainClock(void)
- {
- /* 在SWM中配置关联引脚. */
- Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_SWM); /* 使用SWM之前启用接口访问时钟. */
- Chip_SWM_DisableFixedPin(SWM_FIXED_ADC1); /* 关闭PIO0_6引脚的模拟信号功能. */
- Chip_SWM_MovablePinAssign(SWM_CLKOUT_O, 6U); /* 将CLKOUT输出信号绑定到PIO0_6引脚上. */
- Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_SWM); /* 关闭SWM时钟以省电. */
- /* 配置CLKOUT输出.
- * 设定CLKOUT输出Main Clock, 分频值为1. */
- Chip_SYSCON_ConfigClkoutOutput(eSYSCON_ClkoutSource_MainClock, 1U);
- }
- /* EOF. */
复制代码
代码3
实际使用的是开发板Analog插座的的A0位,也就是LPC824单片机的PIO0_6引脚。测量时,用示波器探针夹持该引脚。如图2所示。
图2
下载程序到开发板,运行程序,观察示波器可以看到振幅大约500mV,频率为12MHz的时钟信号波形。
图3
到此为止,已经搭建好了片内时钟的调试环境。
后续的工作是在SystemInit()函数中调试PLL,参考官方提供的代码把Core Clock搞到LPC824标称上限的30MHz,然后还可以试试看能不能超频。但无论如何,现在得睡觉了。。。
|
|