华大 HC32F460 Timer0基本计数器实验代码详解

文章详细介绍了HC32F460微控制器中Timer0的配置,包括时钟源设置为XTAL32,启用计数匹配中断,每0.5秒中断一次以切换LED状态,并配置按键触发事件停止计数。代码分析部分展示了如何初始化Timer0,设置比较匹配中断以及中断服务函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

声明:以下内容为本人学习心得。

一、基础知识

HC32F460的Timer0提供了2个单元,每个单元下有A、B通道,即Time0一共有4个通道,具有同步计数和异步计数方式,特别注意的是:单元1通道A的比较匹配中断TMR_U1_GCMA仅在异步计数方式时使用。

二、代码分析

本实验设置Timer0时钟源为XTAL32,使能计数匹配中断,每0.5S中断一次并切换LED_BLUE的亮灭状态;同时使能按键K10的下降沿产生内部触发事件,该事件可以使定时器停止计数。

main.c

①定义变量声明,具体解释在后面。

#define EXAMPLE_PERIPH_WE               (LL_PERIPH_GPIO | LL_PERIPH_EFM | LL_PERIPH_FCG | \
                                         LL_PERIPH_PWC_CLK_RMU | LL_PERIPH_SRAM)
#define EXAMPLE_PERIPH_WP               (LL_PERIPH_EFM | LL_PERIPH_FCG | LL_PERIPH_SRAM)

/* TMR0 unit and channel definition */
#define TMR0_UNIT                       (CM_TMR0_1)//Timer0通道1基地址
#define TMR0_CLK                        (FCG2_PERIPH_TMR0_1)//使能Timer0时钟,通过寄存器PWC_FCG2(功能时钟控制器2)设置
#define TMR0_CH                         (TMR0_CH_B)//使用Timer0的CH_B通道
#define TMR0_TRIG_CH                    (AOS_TMR0)//AOS:自动运行系统,TMR0_HTSSR(Timer0硬件触发事件选择寄存器)地址
#define TMR0_CH_INT                     (TMR0_INT_CMP_B)//设置CH_B通道 比较匹配中断使能
#define TMR0_CH_FLAG                    (TMR0_FLAG_CMP_B)//设置 比较匹配中断完成标志位,通过TMRO_STFLR(状态标志寄存器),第16位置1
#define TMR0_INT_SRC                    (INT_SRC_TMR0_1_CMP_B)//中断序号65
#define TMR0_IRQn                       (INT006_IRQn)//中断源
/* Period = 1 / (Clock freq / div) * (Compare value + 1) = 500ms */
#define TMR0_CMP_VALUE                  (XTAL32_VALUE / 16U / 2U - 1U)//设置基准值 2048

②Time0定时器配置

static void TMR0_Config(void)
{
    stc_tmr0_init_t stcTmr0Init;//定时器0配置结构体
    stc_irq_signin_config_t stcIrqSignConfig;//中断配置结构体

    /* Enable timer0 and AOS clock */
    FCG_Fcg2PeriphClockCmd(TMR0_CLK, ENABLE);//打开TIME0使能时钟
    FCG_Fcg0PeriphClockCmd(FCG0_PERIPH_AOS, ENABLE);//打开AOS使能时钟

    /* TIMER0 configuration */
    (void)TMR0_StructInit(&stcTmr0Init);
    stcTmr0Init.u32ClockSrc     = TMR0_CLK_SRC_XTAL32;//选择XTAL32为时钟源
    stcTmr0Init.u32ClockDiv     = TMR0_CLK_DIV16;//设置16分频
    stcTmr0Init.u32Func         = TMR0_FUNC_CMP;//设置为 比较匹配中断模式
    stcTmr0Init.u16CompareValue = (uint16_t)TMR0_CMP_VALUE;//基准值为2048
    (void)TMR0_Init(TMR0_UNIT, TMR0_CH, &stcTmr0Init);
    /* Asynchronous clock source, writing to TMR0 register requires waiting for three asynchronous clocks. */
    DDL_DelayMS(1U);
    TMR0_HWStopCondCmd(TMR0_UNIT, TMR0_CH, ENABLE);
    /* Asynchronous clock source, writing to TMR0 register requires waiting for three asynchronous clocks. */
    DDL_DelayMS(1U);
    TMR0_IntCmd(TMR0_UNIT, TMR0_CH_INT, ENABLE);
    /* Asynchronous clock source, writing to TMR0 register requires waiting for three asynchronous clocks. */
    DDL_DelayMS(1U);
    AOS_SetTriggerEventSrc(TMR0_TRIG_CH, BSP_KEY_KEY10_EVT);

    /* Interrupt configuration */
    stcIrqSignConfig.enIntSrc    = TMR0_INT_SRC;
    stcIrqSignConfig.enIRQn      = TMR0_IRQn;
    stcIrqSignConfig.pfnCallback = &TMR0_CompareIrqCallback;
    (void)INTC_IrqSignIn(&stcIrqSignConfig);
    NVIC_ClearPendingIRQ(stcIrqSignConfig.enIRQn);
    NVIC_SetPriority(stcIrqSignConfig.enIRQn, DDL_IRQ_PRIO_DEFAULT);
    NVIC_EnableIRQ(stcIrqSignConfig.enIRQn);
}

中断结构体成员的详解在之前发布的文章有说过,这里就不多细节了,直接看定时器0结构体成员有哪些:

typedef struct {
    uint32_t u32ClockSrc;               /*!<  选择时钟源 */
    uint32_t u32ClockDiv;               /*!<  设置时钟源分频*/
    uint32_t u32Func;                   /*!<  设置定时器0功能:计数 or 输入捕获 */
    uint16_t u16CompareValue;           /*!< 设置基准值 */
} stc_tmr0_init_t;

特别注意的是:

DDL_DelayMS(1U); 在Timer0配置中的作用是:等待3个异步计数时钟。

这是因为HC32F460规定使用Timer0模块时,在选择异步计数的情况下,修改计数值、基准值、启动位、状态位时Timer()从接收到写动作后经过3个异步计数时才将修改值写入对应的寄存器。

TMR0_HWStopCondCmd(TMR0_UNIT, TMR0_CH, ENABLE);设置TMR0_BCONR(基本控制寄存器)第b29位HSTPB为1,置1:条件匹配时,定时器停止有效。

TMR0_IntCmd(TMR0_UNIT, TMR0_CH_INT, ENABLE);使能中断,设置TMR0_BOCNR(基本控制寄存器)的b18位 INTENB为1,置1:CMPBR寄存器和计数值相等时,或者发生捕获输入事件时,该中断使能。

AOS_SetTriggerEventSrc(TMR0_TRIG_CH, BSP_KEY_KEY10_EVT); 写入硬件触发的事件编号。

BSP_KEY_KEY10_EVT:对应PORT_EIRQ1外部中断,下降沿触发。

剩下的代码是中断配置,之前文章讲过,这里不多说,看看XTAL32配置和Timer0_1的通道B比较匹配中断回调函数

static void XTAL32_Config(void)
{
    stc_clock_xtal32_init_t stcXtal32Init;

     GPIO_AnalogCmd(BSP_XTAL32_PORT, BSP_XTAL32_IN_PIN | BSP_XTAL32_OUT_PIN, ENABLE);
    (void)CLK_Xtal32StructInit(&stcXtal32Init);
    /* Configure Xtal32 */
    stcXtal32Init.u8State   = CLK_XTAL32_ON;
    stcXtal32Init.u8Drv     = CLK_XTAL32_DRV_MID;
    stcXtal32Init.u8Filter  = CLK_XTAL32_FILTER_OFF;
    (void)CLK_Xtal32Init(&stcXtal32Init);
}
static void TMR0_CompareIrqCallback(void)
{
    BSP_LED_Toggle(LED_BLUE);
    TMR0_ClearStatus(TMR0_UNIT, TMR0_CH_FLAG);
}

也都是之前文章讲过,直接看主函数:

int32_t main(void)
{
    /* Peripheral registers write unprotected */
    LL_PERIPH_WE(EXAMPLE_PERIPH_WE);
    /* Configure XTAL32 */
    XTAL32_Config();
    /* BSP init */
    BSP_LED_Init();
    BSP_KEY_Init();
    /* Configure TMR0 */
    TMR0_Config();
    /* TMR0 start counting */
    TMR0_Start(TMR0_UNIT, TMR0_CH);
    /* Asynchronous clock source, writing to TMR0 register requires waiting for three asynchronous clocks. */
    DDL_DelayMS(1U);
    /* Peripheral registers write protected */
    LL_PERIPH_WP(EXAMPLE_PERIPH_WP);

    for (;;) {
        ;
    }

TMR0_Start(TMR0_UNIT, TMR0_CH); 目的是通过设置基本控制就寄存器(TMR0_BCONR)中的第b16位CSTB为1,置1时:通道B定时器启动。

到此定时器0计数实验就结束了,有什么疑问的可以私信我~

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值