这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » 国产MCU » 【CH582M】CH582M的定时器(3)计数模式

共1条 1/1 1 跳转至

【CH582M】CH582M的定时器(3)计数模式

专家
2026-09-04 13:39:17     打赏

设置定时器为计数功能时,操作步骤如下: 

(1)将计数用的GPIO口位引脚方向设置为输入

(2) R32_TMRx_CNT_END寄存器 中设定计数溢出终值,就是计数上限值 

3)配置模式设置寄存器(R8_TMRx_CTRL_MOD),置位 RB_TMR_MODE_IN 和 RB_TMR_CAP_COUNT,表示设置定时器为计数模式。

(4)清零模式设置寄存器(R8_TMRx_CTRL_MOD)的RB_TMR_ALL_CLEAR 位,通过 RB_TMR_CAP_EDGE 选择采样边沿方式,

(5)将模式设置寄存器(R8_TMRx_CTRL_MOD)RB_TMR_COUNT_EN 置 1,使能计数功能;

(6)可选步骤,如果需要启用中断则设置相应的中断使能寄存器位;

(7)R32_TMRx_COUNT 存放当前计数值,每次计数达到计数终值(R32_TMRx_CNT_END寄存器),中断标志寄存器(R8_TMRx_INT_FLAG)的RB_TMR_IE_CYC_END 都会置 1 并且R32_TMRx_COUNT 清 0,如果开启中断则会触发硬件中断。


测试计划如下:

1、以TMR0产生周期(1ms)脉冲,输出到指定GPIO口(PB3)

2、短接1中的GPIO口(PB3)给另一个输入用的GPIO口(PB10,由系统的功能复用指定的GPIO口),作为TMR1的外部输入脉冲

image.png

3、配置TMR1为计数模式,输入脉冲为TMR0的输出脉冲

测试代码如下:


/*********************************************************************
 * @fn      TMR0_TimerInit
 *
 * @brief   定时功能初始化
 *
 * @param   t       - 定时时间,基于当前系统时钟Tsys, 最长定时周期 67108864
 *
 * @return  none
 */
void TMR0_TimerInit(uint32_t t)
{
    R32_TMR0_CNT_END = t;
    R8_TMR0_CTRL_MOD = RB_TMR_ALL_CLEAR;
    R8_TMR0_CTRL_MOD = RB_TMR_COUNT_EN;
}
// LED 接在 PB4
#define LED_PIN     GPIO_Pin_4
int main()
{
    uint8_t i;
    SetSysClock(CLK_SOURCE_PLL_60MHz);
    /* 配置串口调试 */
    DebugInit();
    PRINT("Start @ChipID=%02X\n", R8_CHIP_ID);
    // 指定 PB3 和 PB4 为输出方式
    GPIOB_SetBits(GPIO_Pin_4 | GPIO_Pin_3);
    GPIOB_ModeCfg(GPIO_Pin_4 | GPIO_Pin_3, GPIO_ModeOut_PP_5mA);
    TMR0_TimerInit(FREQ_SYS / 1000);    // 设置定时时间 1ms ( (1/60MHz) * (60M / 1000))
    TMR0_ITCfg(ENABLE, TMR0_3_IT_CYC_END);  // 开启中断:周期结束
    PFIC_EnableIRQ(TMR0_IRQn);
    // 配置TMR1为计数模式,外部脉冲从 PB10 引入
    // 测试时,需要短接 PB3 - PB10
    // 配置 PB10 为输入模式
    GPIOB_ModeCfg(GPIO_Pin_10, GPIO_ModeIN_PD);
    // 重映射PB10为TMR1的功能复用引脚
    GPIOPinRemap(ENABLE, RB_PIN_TMR1);
    // 下降沿有效
    TMR1_EXTSingleCounterInit(FallEdge_To_FallEdge);
    TMR1_CountOverflowCfg(10); // 设置计数上限10
    /* 开启计数溢出中断,计数10个周期进入中断 */
    TMR1_ClearITFlag(TMR0_3_IT_CYC_END);
    PFIC_EnableIRQ(TMR1_IRQn);
    TMR1_ITCfg(ENABLE, TMR0_3_IT_CYC_END);
    while(1);
}
/*********************************************************************
 * @fn      TMR0_IRQHandler
 *
 * @brief   TMR0中断函数
 *
 * @return  none
 */
__INTERRUPT
__HIGH_CODE
void TMR0_IRQHandler(void) // TMR0 定时中断
{
    if(TMR0_GetITFlag(TMR0_3_IT_CYC_END)) {
        // 清除中断标志
        TMR0_ClearITFlag(TMR0_3_IT_CYC_END);
        // GOPIO口翻转
        GPIOB_InverseBits(GPIO_Pin_3);
    }
}
/*********************************************************************
 * @fn      TMR1_IRQHandler
 *
 * @brief   TMR1中断函数
 *
 * @return  none
 */
__INTERRUPT
__HIGH_CODE
void TMR1_IRQHandler(void) // TMR1 定时中断
{
    if(TMR1_GetITFlag(TMR0_3_IT_CYC_END))
    {
        TMR1_ClearITFlag(TMR0_3_IT_CYC_END);
        /* 计数器计满,硬件自动清零,重新开始计数 */
       
        // GOPIO口翻转
        GPIOB_InverseBits(GPIO_Pin_4);
    }
}

由逻辑分析仪捕捉到的PB4口的输出信号:

image.png

说明:

1、根据程序,在定时器0中,PB3每1ms翻转一次,因而在PB3上产生周期为2ms的脉冲

2、PB3上的信号经PB10,成为定时器1的外部脉冲输入信号,收集到10个脉冲后,使PB4翻转。也就是说PB4上每20ms翻转一次。这个结果与逻辑分析仪得到的结果是一致的。




关键词: CH582M     TMR     计数    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]