打印
[PIC®/AVR®/dsPIC®产品]

定时器TMR-32位定时器使用

[复制链接]
9800|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
qcliu|  楼主 | 2021-8-9 12:11 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
1、PIC32参考资源

PIC32系列参考手册 中文版  


使用特权

评论回复
沙发
qcliu|  楼主 | 2021-8-9 12:13 | 只看该作者
2、32位同步时钟计数器Harmony配置
1、在左侧Available Components列表中将TMR3拖入到Project Graph中;若新建的工程则将TMR2一起拖入框内;



2、拖入后工程组件如下图所示;



3、TMR2以及TMR3初始配置信息如下;



TMR3的配置信息;



4、修改TMR2的参数,设置分频系数为1,32-Bit模式选择32位计数模式,时钟源选择内部时钟,定时时间为1毫秒,空闲模式继续工作;



5、定时器3仅需配置使能中断;



6、组件配置完成后点击左侧的Generate Code按钮生成代码;



7、生成的代码与原始代码存在差异,需进行确认;



8、代码生成后需要的操作;

        1、启动定时器;

        2、添加中断任务内容;

9、编译运行将代码烧录到开发板中;

点击编译按钮,编译提示BUILD SUCCESSFUL,点击烧录,提示Programming/Verify complete,开发板上的LED灯闪烁。



使用特权

评论回复
板凳
qcliu|  楼主 | 2021-8-9 13:07 | 只看该作者
3、工程配置分析
1、TMR2 Configuration Options配置分析



Select Prescaler 选择分频系数;

32-Bit Timer Mode Select Bit 可选Odd numbered and even numbered timers form separate 16-bit timers奇数和偶数定时器形成单独的16位定时器,以及Odd numbered and even numbered timers form a 32-bit timer奇数和偶数定时器组成一个32位定时器

Select Timer Clock Frequency 选择时钟源;

Timer Clock Frequency 时钟频率,计算得到,是分频后得到的值,定时器时钟;

Timer Period Unit 为定时器时间单位,可选millisecond、microsecond、nanosecond;也就是毫秒、微秒以及纳秒;

Time为计时时间,与上面的单位结合使用,Period Register为周期寄存器数值,通过时间计算得到;

Stop in Idle Mode bit停止在空闲模式位,可选Continue operation even in Idle mode(空闲模式下继续)或Discontinue operation when device enters Idle mode(当设备进入空闲模式时停止);

2、TMR3 Configuration Options配置分析



Enable Interrupts?使能中断服务,勾选该项后,会生成中断相关的代码及函数;


使用特权

评论回复
地板
qcliu|  楼主 | 2021-8-9 13:07 | 只看该作者
4、具体代码分析
//定时器初始化
void TMR2_Initialize(void)
{
    /* Disable Timer */
    T2CONCLR = _T2CON_ON_MASK; //禁止定时器,清零ON控制位

    /*
    SIDL = 0 //空闲模式停止位
    TCKPS =0 //预分频设置
    T32   = 1 //32定时器
    TCS = 0 //时钟源选择,内部时钟源或外部时钟源
    */
    T2CONSET = 0x8;  //TxCON与定时器相关的 16 位控制寄存器

    /* Clear counter */
    TMR2 = 0x0; //TMRx 32位定时器计数器寄存器

    /*Set period */
    PR2 = 79999U; //PRx与定时器相关的 32 位周期寄存器

    /* Enable TMR Interrupt of odd numbered timer in 32-bit mode */
    IEC0SET = _IEC0_T3IE_MASK; //TxIE中断允许控制位在IEC0中断寄存器中
}

//开启定时器
void TMR2_Start(void)
{
    T2CONSET = _T2CON_ON_MASK; //TxIF中断标志状态位在IFS0 中断寄存器中;
}

//关闭定时器
void TMR2_Stop (void)
{
    T2CONCLR = _T2CON_ON_MASK; //TxIF中断标志状态位在IFS0 中断寄存器中;
}

//设置周期寄存器
void TMR2_PeriodSet(uint32_t period)
{
    PR2  = period; //PRx与定时器相关的32位周期寄存器
}

//获取周期寄存器
uint32_t TMR2_PeriodGet(void)
{
    return PR2; //PRx与定时器相关的32位周期寄存器
}

//获取计数值
uint32_t TMR2_CounterGet(void)
{
    return (TMR2);  //TMRx 32位定时器计数器寄存器
}

//获取定时器频率
uint32_t TMR2_FrequencyGet(void)
{
    return (80000000); //返回定时器的时钟频率
}

//定时器中断服务函数,32位定时器中断控制由Slave定时器处理
void TIMER_3_InterruptHandler (void)
{
    uint32_t status  = 0U;
    status = IFS0bits.T3IF;
    IFS0CLR = _IFS0_T3IF_MASK; //清零IFSx寄存器中的TxIF中断标志位

/*可在这添加中断处理内容*/

    if((tmr2Obj.callback_fn != NULL))
    {
        tmr2Obj.callback_fn(status, tmr2Obj.context);
    }
}

//中断使能
void TMR2_InterruptEnable(void)
{
    IEC0SET = _IEC0_T3IE_MASK; //TxIE中断允许控制位在IEC0中断寄存器
}

//禁止中断
void TMR2_InterruptDisable(void)
{
    IEC0CLR = _IEC0_T3IE_MASK; //TxIE中断允许控制位在IEC0中断寄存器
}

//
void TMR2_CallbackRegister( TMR_CALLBACK callback_fn, uintptr_t context )
{
    /* Save callback_fn and context in local memory */
    tmr2Obj.callback_fn = callback_fn;
    tmr2Obj.context = context;
}

//中断服务函数,在interrupts.c中,调用TIMER_3_InterruptHandler
void __ISR(_TIMER_3_VECTOR, ipl1SOFT) TIMER_3_Handler (void)
{
    TIMER_3_InterruptHandler();
}


使用特权

评论回复
5
qcliu|  楼主 | 2021-8-9 13:09 | 只看该作者
5、32位定时器说明
1、B类32位定时器框图



32 位模式

只有 B 类定时器模块支持 32 位工作模式。 32 位定时器模块通过将偶编号 B 类定时器 (称为TimerX)与相邻奇编号 B 类定时器 (称为 TimerY)组合而构成。例如, 32 位定时器组合有Timer2 与 Timer3 和 Timer4 与 Timer5 等。

Timer2 和 Timer4:这些位代表 32 位定时器的低半字 (16 位)。

Timer3 和 Timer5:这些位代表 32 位定时器的高半字 (16 位)。

32 位定时器模式由以下位决定:

• T32 (TxCON<3>):32 位定时器模式选择位 (仅适用于 TimerX)

• TCS (TxCON<1>):定时器时钟源选择位

• TGATE (TxCON<7>):定时器门控时间累加使能位

32 位定时器模式下的具体行为:

• TimerX 是主定时器; TimerY 是从定时器

• TMRx 计数寄存器是 32 位定时器值的低半字

• TMRy 计数寄存器是 32 位定时器值的高半字

• PRx 周期寄存器是 32 位周期值的低半字

• PRy 周期寄存器是 32 位周期值的高半字

• TimerX 控制位 (TxCON)配置 32 位定时器对的操作

• TimerY 控制位 (TyCON)没有任何作用

• TimerX 中断和状态位会被忽略

• TimerY 提供中断允许、中断标志和中断优先级控制位

使用 32 位定时器时,需要考虑以下事项:

• 在向 TMRxy 计数寄存器或 PRxy 周期寄存器中写入任意 32 位值之前,确保先将定时器对配置为 32 位模式,方法是设置 T32 (TxCON<3>) = 1。

• 所有定时器模块的 SFR 都可以按字节 (8 位)、半字 (16 位)或字 (32 位)进行写操作。

• 所有定时器模块的 SFR 都可以按字节、半字或字进行读操作。

• TMRx 和 TMRy 计数寄存器对可以按单个 32 位值的形式进行读写。

• PRx 和 PRy 周期寄存器对可以按单个 32 位值的形式进行读写。


使用特权

评论回复
6
qcliu|  楼主 | 2021-8-9 13:10 | 只看该作者
6、32位定时器初始化步骤
1. 清零 ON 控制位 (TxCON<15> = 0)以禁止定时器。

2. 清零 TCS 控制位 (TxCON<1> = 0)以选择内部 PBCLK 源。

3. 将 T32 控制位置 1 (TxCON<3> = 1)以选择 32 位工作。

4. 选择所需的定时器输入时钟预分频比。

5. 装载 / 清零定时器寄存器 TMRxy。

6. 将所需的 32 位匹配值装入周期寄存器 PRxy。

7. 如果使用了中断:

        a) 清零 IFSx 寄存器中的 TyIF 中断标志位。

        b) 在 IPCx 寄存器中配置中断优先级和子优先级。

        c) 将 IECx 寄存器中的 TyIE 中断允许位置 1。

8. 将 ON 控制位置 1 (TxCON<15> = 1)以使能定时器。


使用特权

评论回复
7
qcliu|  楼主 | 2021-8-9 13:11 | 只看该作者
7、实验验证

点击编译按钮,编译提示BUILD SUCCESSFUL,点击烧录,提示Programming/Verify complete,开发板上的LED灯闪烁。


使用特权

评论回复
8
pzsh| | 2021-8-16 19:44 | 只看该作者
成功

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

62

主题

3308

帖子

4

粉丝