在线时间1312 小时
UID3124330
注册时间2015-11-26
NXP金币2830
TA的每日心情 | 开心 2019-3-5 08:47 |
---|
签到天数: 1 天 连续签到: 1 天 [LV.1]初来乍到
金牌会员
 
- 积分
- 9004
- 最后登录
- 2025-7-20
|
说到定时器呢,这会儿必须地方得分析时钟了,否则你都不知道定了多长时间,怎么算的,搞不明白问题就很多。LPC1768系统时钟的分析资料网上也挺多的,不管是中文的还是英文的,系统时钟的由来还是说的挺清楚的。在测试定时器的时候,TIM_ConfigStruct.PrescaleValue = 100;这个说100us让我困惑了一天多,分析了很多遍时钟,就是想不明白从25M时钟怎么就预分频100us,后来又分析了一遍函数,才搞明白原因。
关于系统时钟的参数配置在system_LPC17xx.c的宏参数定义中配置。时钟分析在使用手册的时钟一张可找到,根据参数熟悉一下寄存器,如图1所示。
#define CLKSRCSEL_Val 0x00000001 //选择主振荡器为时钟源
#define PLL0_SETUP 1
#define PLL0CFG_Val 0x00050063 //分频和倍频系数 N=5+1,M=0x63+1
#define PLL1_SETUP 1
#define PLL1CFG_Val 0x00000023
#define CCLKCFG_Val 0x00000003 //cpu时钟配置为4分频
#define USBCLKCFG_Val 0x00000000
#define PCLKSEL0_Val 0x00000000 //外设时钟配置为4分频
#define PCLKSEL1_Val 0x00000000
#define PCONP_Val 0x042887DE //外设使能
#define CLKOUTCFG_Val 0x00000000 //选择CPU时钟作为CLKOUT的时钟源
根据Fcpu =Fcco/CLKCFG+1;Fcco=(2*M*Fin)/N ;CLKCFG=3+1;所以Fcco=((2*100*12)/6)=400M,Fcpu =100M;相关外设根据PCLKSEL0寄存器可得,外设频率为25M(100M/4=25M)。
这主时钟就分析完了,分析定时器。本例使用的式定时器0,外设时钟就是25M。在程序中
// Initialize timer 0, prescale count time of 100uS
TIM_ConfigStruct.PrescaleOption = TIM_PRESCALE_USVAL;
TIM_ConfigStruct.PrescaleValue = 100;
这会必须知道100us是怎么来的?
在lpc17xx_timer.c中有一个函数
uint32_t TIM_ConverUSecToVal (uint32_t timernum, uint32_t usec)
{
uint64_t clkdlycnt;
// Get Pclock of timer
clkdlycnt = (uint64_t) TIM_GetPClock (timernum);
clkdlycnt = (clkdlycnt * usec) / 1000000;
return (uint32_t) clkdlycnt;
}
这就是由来,如果PrescaleOption是TIM_PRESCALE_TICKVAL,就是实际的分频值,即2500。如果是TIM_PRESCALE_USVAL,就是数据进行了转换,这就是来历。
其他的都比较清楚了。所以简单的完成定时1S中断,实现LED闪烁。如图2所示。
- void TIM_Configuration(void)
- {
- TIM_TIMERCFG_Type TIM_ConfigStruct;
- TIM_MATCHCFG_Type TIM_MatchConfigStruct;
-
- // Initialize timer 0, prescale count time of 100uS
- TIM_ConfigStruct.PrescaleOption = TIM_PRESCALE_USVAL;//TIM_PRESCALE_TICKVAL;//TIM_PRESCALE_USVAL;
- TIM_ConfigStruct.PrescaleValue = 100;//2500;//100;
- // use channel 0, MR0
- TIM_MatchConfigStruct.MatchChannel = 0;
- // Disable interrupt when MR0 matches the value in TC register
- TIM_MatchConfigStruct.IntOnMatch = TRUE;
- //Enable reset on MR0: TIMER will reset if MR0 matches it
- TIM_MatchConfigStruct.ResetOnMatch = TRUE;
- //Stop on MR0 if MR0 matches it
- TIM_MatchConfigStruct.StopOnMatch = FALSE;
- //Toggle MR0.0 pin if MR0 matches it
- TIM_MatchConfigStruct.ExtMatchOutputType =TIM_EXTMATCH_TOGGLE;
- // Set Match value, count value of 10000 (10000 * 100uS = 1S --> 1Hz)
- TIM_MatchConfigStruct.MatchValue = 10000;
- // Set configuration for Tim_config and Tim_MatchConfig
- TIM_Init(LPC_TIM0, TIM_TIMER_MODE,&TIM_ConfigStruct);
- TIM_ConfigMatch(LPC_TIM0,&TIM_MatchConfigStruct);
- /* preemption = 1, sub-priority = 1 */
- NVIC_SetPriority(TIMER0_IRQn, ((0x01<<3)|0x01));
- /* Enable interrupt for timer 0 */
- NVIC_EnableIRQ(TIMER0_IRQn);
- TIM_Cmd(LPC_TIM0,ENABLE);
- }
- void TIMER0_IRQHandler(void)
- {
- if (TIM_GetIntStatus(LPC_TIM0,0))
- {
- TIM_ClearIntPending(LPC_TIM0,0);
- /* toggle led status */
- if (timer0_flag)
- {
- GPIO_SetValue(0,1<<7);
- }
- else
- {
- GPIO_ClearValue (0,1<<7);
- }
- timer0_flag =! timer0_flag;
- }
- }
复制代码
|
-
图1
-
图2
|