新塘M0Timer定时器篇

2011年12月1日星期四

今天结束了大学的最后一场考试,终于有时间来发菜农大叔的贴了,非常兴奋啊!

开始着手定时器的学习,先看芯片手册。

芯片内部集成定时器控制器,定时器模块包括4组32位的定时器。TIMER0~TIMER3,提供用户便捷的计数定时功能。定时器模块可支持频率测量,计数,间隔时间测量,时钟产生,延迟时间等功能,定时器可在计时溢出时产生中断信号,也可在操作的过程中提供计数的当前值。

在看看系统内存映射:

地址空间 标志 控制器

Flash & SRAM内存空间

0x0000_0000 – 0x0001_FFFF FLASH_BA Flash内存控制空间

0x2000_0000 - 0x2000_3FFF SRAM_BA SRAM内存空间

0x6000_0000 - 0x6001_FFFF EXTMEM_BA 外部存储空间

AHB控制器空间(0x5000_0000-0x501F_FFFF)

0x5000_0000-0x5000_01FF GCR_BA 系统全局控制寄存器

0x5000_0200-0x5000_02FF CLK_BA 时钟控制寄存器

0x5000_0300-0x5000_03FF INT_BA 多路中断控制寄存器

0x5000_4000-0x5000_7FFF GPIO_BA GPIO控制寄存器

0x5000_8000-0x5000_BFFF PDMA_BA 外设DMA控制寄存器

0x5000_C000-0x5000_FFFF FMC_BA Flash内存控制寄存器

0x5001_0000-0x5001_03FF EBI_BA 外部总线接口控制寄存器

clip_image002

clip_image004

clip_image006

上图就是片上控制器的地址空间分配

从上表中我们就可以找到定时器的控制器的地址了:

clip_image008

clip_image010

下面一幅图是定时器的特征图:

clip_image012

但是由于现在还不是很明白,就只能硬着头皮上了。

先吃饭17:15后面再补:

现在看看特征也就是说明是32位定时器而已,可以计数2^32下。

在这里我还是没有找到寄存器配置说明,再找找,

只找到这个函数库说明文件:

clip_image014

The timer module includes four channels, TIMER0~TIMER3, which allow you to easily implement a counting scheme for use. The timer can perform functions like frequency measurement, event counting, interval measurement, clock generation, delay timing, and so on. The timer can generate an interrupt signal upon timeout, or provide the current value of count during operation. And for external count and capture functions, only NUC1x0xxxBx and NUC1x0xxxCx series supported, ex:NUC140RD2BN and NUC140VE3CN. Please refer to NuMicroTM NUC100 Series Products Selection Guide of Appendix in details.

上面是函数库的说明部分,我找GOOGLE翻译试试,

定时器模块包括四个通道,定时器0〜TIMER3,这让您能够轻松地实现一个使用计数方案。计时器可以执行功能,如频率测量,事件计数,间隔测量,时钟发生器,延迟时间等。定时器可以产生一个中断信号后,超时,或在操作过程中提供的计数当前值。而对于外部计数和捕捉功能,只有NUC1x0xxxBx NUC1x0xxxCx一系列支持,如:NUC140RD2BN和NUC140VE3CN。请参阅NuMicroTM NUC100系列产品选择指南附录。

E_TIMER_CHANNEL

Enumeration Identifier Value Description

E_TMR0 0x0 Specify the timer channel – 0

E_TMR1 0x1 Specify the timer channel – 1

E_TMR2 0x2 Specify the timer channel - 2

E_TMR3 0x3 Specify the timer channel – 3

E_TIMER_OPMODE

Enumeration Identifier Value Description

E_ONESHOT_MODE 0x0 Set timer to One-Shot mode

E_PERIODIC_MODE 0x1 Set timer to Periodic mode

E_TOGGLE_MODE 0x2 Set timer to Toggle mode

E_CONTINUOUS_MODE 0x3 Set timer to Continuous Counting mode

算了这样抄手册也不是办法,还是自己看吧^_^

参考下网上帖子的配置步骤,

clip_image016

用户必须调用DrvTIMER_Init()函数在系统启动的时候

1. 第一步就是初始化定时器。

DrvTIMER_Init(); //初始化定时器

2. 设定时钟源。

DrvSYS_SelectIPClockSource(E_SYS_TMR0_CLKSRC,0); //设定IP 时钟源

从时钟源获取时钟

现在看看这个函数原型:

/*---------------------------------------------------------------------------------------------------------*/

/* Function: DrvSYS_SelectIPClockSource */

/* */

/* Parameters: */

/* eIpClkSrc - [in] E_SYS_WDT_CLKSRC / E_SYS_ADC_CLKSRC / E_SYS_TMR0_CLKSRC */

/* E_SYS_TMR1_CLKSRC / E_SYS_TMR2_CLKSRC / E_SYS_TMR3_CLKSRC */

/* E_SYS_UART_CLKSRC / E_SYS_CAN_CLKSRC / E_SYS_PWM01_CLKSRC */

/* E_SYS_PWM23_CLKSRC / E_SYS_PWM45_CLKSRC/ E_SYS_PWM67_CLKSRC */

/* E_SYS_FRQDIV_CLKSRC/ E_SYS_I2S_CLKSRC */

/* */

/* u8ClkSrcSel - [in] Corresponding clock source */

/* */

/* Returns: */

/* 0: Success */

/* < 0: Incorrect value */

/* */

/* Description: */

/* This function is used to select IP clock source */

/*---------------------------------------------------------------------------------------------------------*/

int32_t DrvSYS_SelectIPClockSource(E_SYS_IP_CLKSRC eIpClkSrc, uint8_t u8ClkSrcSel)

在这里匹配

case E_SYS_TMR0_CLKSRC:

SYSCLK->CLKSEL1.TMR0_S = u8ClkSrcSel;

break;

从而配置Tmer0的时钟来源:SYSCLK->CLKSEL1.TMR0_S = u8ClkSrcSel;

这里有个参数是u8ClkSrcSel

再看看u8ClkSrcSel是哪里定义的:

/*---------------------------------------------------------------------------------------------------------*/

/* Function: DrvSYS_SelectSysTickSource */

/* */

/* Parameters: */

/* u8ClkSrcSel - [in] 0: External 12M clock */

/* 1: External 32K clock */

/* 2: External 12M clock / 2 */

/* 3: HCLK / 2 */

/* 4~7: Internal 22M clock / 2 */

/* */

/* Returns: */

/* 0: Success */

/* < 0: Incorrect value */

/* */

/* Description: */

/* This function is used to select sysyem tick clock source */

/*---------------------------------------------------------------------------------------------------------*/

int32_t DrvSYS_SelectSysTickSource(uint8_t u8ClkSrcSel)

{

if (u8ClkSrcSel > 7)

{

return E_DRVSYS_ERR_ARGUMENT;

}

else

{

SYSCLK->CLKSEL0.STCLK_S = u8ClkSrcSel;

}

return 0;

}

这里选的是0所以选择的是 0: External 12M clock 作为时钟源!

3. 配置定时器tick及模式:DrvTIMER_Open(E_TMR0,1000,E_PERIODIC_MODE);

DrvTIMER_Open(E_TMR0,1000,E_PERIODIC_MODE); //设定定时器 tick 周期并且启动定时器:定时器通道 TMR0 每秒1000次 周期模式

4. DrvTIMER_SetTimerEvent(E_TMR0,1,(TIMER_CALLBACK) Timer0_Callback,0); //安装一个定时处理事件到 timer0, timer1, timer2, timer3通道

5. DrvTIMER_EnableInt(E_TMR0); //enable the specified timer interrupt

使能定时器中断

6. 启动定时器

DrvTIMER_Start(E_TMR0); //Start to count the specified timer channel

到这里所以关于定时器的都已设置完毕,就等待定时器一直计数,计满了就响应然后进入void Timer0_Callback (void)函数执行,执行完毕会主函数。

原文地址:https://www.cnblogs.com/tao560532/p/2271097.html