使用Timer0定时器两个通道产生不同的计时中断,分别驱动LED2及LED3闪烁,同时利用逻辑分析仪抓取进行观察。
一、实验资源
1、HC32F460-EVB;
2、Keil V5.28;
3、ST-LINK调试器;
4、逻辑分析仪
二、资源简介
HC32F460PETB片上配置了丰富的定时器资源,包括高级控制定时器Timer6、通用控制定时器Timer4、TimerA和Timer0,另外还有看门狗定时器SWDT和WDT、实时时钟RTC等资源。本次实验使用通用控制定时器Timer0:
从文档中可以了解到通用控制定时器“Timer0”可以实现同步计数和异步计数两种工作方式,同步计数时钟来自于“PCLK1”;异步计数时钟可以使用外部低速振荡器“XTAL32”或者内部低速振荡器“LRC,并且拥有两个独立的工作通道。使用定时器资源涉及到微控制器的时钟系统,下面对HC32F460时钟系统进行简单了解。
从上面介绍中可以看到HC32F460系统时钟有6个时钟源可供选择,通过系统内的协调将不同的时钟信号传递至各个外设资源。下面是“时钟源规格”表的局部,其中高亮文字“MPLLQ”似乎应该为“MPLLR”。“MPLL”系统可以将输入时钟源折腾到多种频率,Timer0用到的“PCLK1”即可由其折腾84MHz,实验中Timer0两个通道均使用了该时钟做为同步计数时钟。
Timer0相关寄存器比较少,配置也比较简单。实验中使能了计数匹配中断功能。
三、实验代码
16位的基准值寄存器(CMPAR、CMPBR)计数范围为0~65535,PCLK1=84MHz。准备在“Tim0_ChannelA”产生0.1ms计时中断,基准值取8399,即:(8399+1)*1/84MHz=0.1ms;在“Tim0_ChannelB”产生0.01ms计时中断,基准值取839,即:(839+1)*1/84MHz=0.1ms=10us。
代码参考了DEMO,主要代码片断如下:
void TIMER0_Config(void)
{
stc_tim0_base_init_t stcTimerCfg;
stc_irq_regi_conf_t stcIrqRegiConf;
MEM_ZERO_STRUCT(stcTimerCfg);
MEM_ZERO_STRUCT(stcIrqRegiConf);
/* Timer0 peripheral enable */
PWC_Fcg2PeriphClockCmd(PWC_FCG2_PERIPH_TIM02, Enable);
/*config register for channel A */
stcTimerCfg.Tim0_CounterMode = Tim0_Sync;
stcTimerCfg.Tim0_SyncClockSource = Tim0_Pclk1;
stcTimerCfg.Tim0_ClockDivision = Tim0_ClkDiv0;
stcTimerCfg.Tim0_CmpValue = (uint16_t)(8400-1);
TIMER0_BaseInit(M4_TMR02,Tim0_ChannelA,&stcTimerCfg);
/* Enable channel A interrupt */
TIMER0_IntCmd(M4_TMR02,Tim0_ChannelA,Enable);
/* Register TMR_INI_GCMA Int to Vect.No.001 */
stcIrqRegiConf.enIRQn = Int001_IRQn;
/* Select I2C Error or Event interrupt function */
stcIrqRegiConf.enIntSrc = INT_TMR02_GCMA;
/* Callback function */
stcIrqRegiConf.pfnCallback =&Timer0A_CallBack;
/* Registration IRQ */
enIrqRegistration(&stcIrqRegiConf);
/* Clear Pending */
NVIC_ClearPendingIRQ(stcIrqRegiConf.enIRQn);
/* Set priority */
NVIC_SetPriority(stcIrqRegiConf.enIRQn, DDL_IRQ_PRIORITY_15);
/* Enable NVIC */
NVIC_EnableIRQ(stcIrqRegiConf.enIRQn);
/*config register for channel B */
stcTimerCfg.Tim0_CounterMode = Tim0_Sync;
stcTimerCfg.Tim0_SyncClockSource = Tim0_Pclk1;
stcTimerCfg.Tim0_ClockDivision = Tim0_ClkDiv0;
stcTimerCfg.Tim0_CmpValue = (uint16_t)(840-1);
TIMER0_BaseInit(M4_TMR02,Tim0_ChannelB,&stcTimerCfg);
/* Enable channel B interrupt */
TIMER0_IntCmd(M4_TMR02,Tim0_ChannelB,Enable);
/* Register TMR_INI_GCMB Int to Vect.No.002 */
stcIrqRegiConf.enIRQn = Int002_IRQn;
/* Select I2C Error or Event interrupt function */
stcIrqRegiConf.enIntSrc = INT_TMR02_GCMB;
/* Callback function */
stcIrqRegiConf.pfnCallback = &Timer0B_CallBack;
/* Registration IRQ */
enIrqRegistration(&stcIrqRegiConf);
/* Clear Pending */
NVIC_ClearPendingIRQ(stcIrqRegiConf.enIRQn);
/* Set priority */
NVIC_SetPriority(stcIrqRegiConf.enIRQn, DDL_IRQ_PRIORITY_15);
/* Enable NVIC */
NVIC_EnableIRQ(stcIrqRegiConf.enIRQn);
/*start timer0*/
TIMER0_Cmd(M4_TMR02,Tim0_ChannelA,Enable);
TIMER0_Cmd(M4_TMR02,Tim0_ChannelB,Enable);
}
四、实验结果
五、实验总结
通过Timer0定时器实验,对定时器最基础的使用方法有了一定的了解,为之后定时器其他功能的学习尝试创造了条件。
|
DEMO在哪找呀?或者可以直接发一下吗?
我就想知道程序是1分频,最高84M没问题,但是这个84M怎么配置得来的
楼主,我很想知道PCLK1作为它的时钟,不分频就是最高84M,那么我在例程中没看到相关的代码对PCLK1进行配置,还有就是在TIME4的例程中,也是PCLK1,16分频,但是文档说明时为什么说主频是8M