lisingch 发表于 2020-6-27 23:23

【华大测评】四、TIMER0

      使用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定时器实验,对定时器最基础的使用方法有了一定的了解,为之后定时器其他功能的学习尝试创造了条件。

zeshoufx 发表于 2020-6-28 08:24

谢谢分享,,,,,,,

lisingch 发表于 2020-6-28 12:19

zeshoufx 发表于 2020-6-28 08:24
谢谢分享,,,,,,,
谢谢捧场!

kiwis66 发表于 2021-11-15 13:18

恩,感谢,
很详细了

lvyunhua 发表于 2022-5-21 22:00

不错,学习了

skyred 发表于 2022-7-10 19:23

逻辑分析仪抓的么

andygirl 发表于 2022-8-18 20:56

霍,不错啊

littlelida 发表于 2022-9-3 14:30

定时器~~好东西
页: [1]
查看完整版本: 【华大测评】四、TIMER0