3870|0

172

帖子

3

TA的资源

一粒金砂(高级)

楼主
 

TI【LP_MSPM0L1306开发板】测评——Timer使用以及示例学习 [复制链接]

 

Timers使用以及示例学习

MSPM0L1306中有四个16位通用定时器,每个计时器具有两个捕捉/比较寄存器,支持待机模式下的低功耗运行,总共支持 8 个 PWM 通道。定时器 (TIM) 还具有广泛的事件生成功能,可生成不同的计数器事件(如溢出事件、重新加载事件以及来自每个捕获/比较寄存器的事件)。通用定时器的特性包括:

• 具有重复重新加载模式的 16 位递减、递增/递减或递增计数器

• 具有重复重新加载模式的 32 位递减、递增/递减或递增计数器

• 可选和可配置的时钟源

• 用于对计数器时钟频率进行分频的 8 位可编程预分频器

• 两个独立通道,用于:

– 输出比较

– 输入捕捉

– PWM 输出

– 单稳态模式

• 支持用于定位和移动检测的正交编码器接口 (QEI)

• 支持同一电源域中不同 TIMx 实例之间的同步和交叉触发

• 支持中断/DMA 触发生成以及跨外设(例如 ADC)触发功能

• 霍尔传感器输入的交叉触发事件逻辑

通过查看数据手册可知MSPM0L1306的具体定时器配置如下

定时器计数功能

定时器的一个重要功能就是定时功能,通用定时器可在两种不同模式下计时/计数:向上、向下和向上/向下。相应模式通过 TIMx.CTRCTL.CM 进行选择。通过查看数据手册可知,定时器支持计数模式如下图所示。

当计数值到达0或者预装载值时,会触发相应的事件,配和中断功能可以实现周期性触发事件的功能。同时,MSPM0的定时器支持了CVAE功能,可以指定在使能后的计数器的值,使定时器的使用更为灵活。

定时器的工作模式位分为单次计数和周期计数两种,在手册中给出了两种不同模式的示意图,并在图中给出了相应寄存器的配置。

示例代码中的timx_timer_mode_periodic_sleep演示了使用定时器的计数中断功能,当计数器到达设定的周期数时,中断触发,PA0上的LED被翻转。

在SysConfig中对定义的配置使用预先定义好的周期配置。定时器时钟源设定为BUSCLK,预分频系数为256。定时器的周期设置为500ms。

同时开启了计数至0的中断。

 

在SysConfig自动生成的代码文件中可以看到设定的定时器的装载值为62499,结合之前的时钟主频为32MHz,分频系数256,可以计算得出定时器的计数频率为2Hz,即周期为500ms。SysConfig工具这里做了自动的转换,将定时器周期转换为计数器的自动装载值。

在主程序中,对系统进行初始化、启用中断。SYSCFG_DL_init() 用于系统初始化,包括 GPIO 和计时器初始化。 NVIC_EnableIRQ(TIMER_INST_INT_IRQN) 启用 TimerG0 全局中断。使用 DL_SYSCTL_enableSleepOnExit() 退出睡眠模式。DL_TimerG_startCounter(TIMER_INST) 是计时器开始计时的软件触发器。__WFI() 正在等待中断发生,然后进入低功耗模式(通过先前设置进入睡眠模式)。主函数的代码如下:


#include "ti_msp_dl_config.h"

int main(void)
{
    SYSCFG_DL_init();

    NVIC_EnableIRQ(TIMER_0_INST_INT_IRQN);
    DL_SYSCTL_enableSleepOnExit();

    DL_TimerG_startCounter(TIMER_0_INST);

    while (1) {
        __WFI();
    }
}

void TIMER_0_INST_IRQHandler(void)
{
    switch (DL_TimerG_getPendingInterrupt(TIMER_0_INST)) {
        case DL_TIMER_IIDX_ZERO:
            DL_GPIO_togglePins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
            break;
        default:
            break;
    }
}

在定时器的中断函数中,对LED1的控制引脚的状态进行翻转。

将PA0的输出接到示波器上可以确定其翻转的速率为500ms,与程序设定的逻辑一致。

定时器PWM输出功能

PWM输出在调节指示灯亮度、控制外部电路的功率以及电机驱动等方面有着广泛的应用,单个通用定时器有两个通道,可以同时产生两路PWM波,定时器的预装载值控制产生的PWM波的周期,而定时器的比较寄存器的值用于控制产生的PWM波的占空比。PWM波的输出形式为边沿对其型和中心对其型的,另外装载寄存器和比较寄存器有影子寄存器(Shadow register)可以实现动态修改PWM波的周期和占空比。

通用定时器具有两路独立的输出通道,可以同时输出两路占空比不同的PWM波。

示例程序timx_timer_mode_pwm_edge_sleep中使用TIMG0产生频率相同,占空比不同的PWM波,定时器时钟源选择为BUSCLK,频率为32MHz,时钟分频系数为256,计数器器装载值为2000,可以确定PWM频率为62.5Hz。

两个输出通道的比较寄存器的值不同,从而实现输出占空比不同的PWM波。

在主程序中初始化外设并启动定时器,就可以输出PWM波了。\

#include "ti_msp_dl_config.h"

int main(void)
{
    SYSCFG_DL_init();

    DL_TimerG_startCounter(PWM_0_INST);

    while (1) {
        __WFI();
    }
}

在两个通道对应的输出通道上连接示波器,可以观察到输出的波形和相应的波形信息。如下图。

MSPM0的定时器的比较寄存器和装载寄存器都拥有影子寄存器功能,可以实现对输出的PWM波形的周期和占空比的实时控制。

在timx_timer_mode_pwm_edge_sleep_shadow示例程序中,选择定时器的时钟源为MFCLK,频率为4MHz,分频系数为4,初始化的装载寄存器值为1600,对应的PWM波频率为625Hz。

SysConfig中开启了影子寄存器的高级功能,用于实时修改PWM波的周期和占空比。

在程序中定义了PWM波的周期和占空比的数组,主程序中初始化使用到的外设后,使能定时器的中断,在中断函数中检测计数溢出中断,并修改相应的装载寄存器值和比较寄存器的值,从而实现修改PWM的周期和占空比。

#include "ti_msp_dl_config.h"

#define PWM_PERIOD_UPDATE_CNT (10U)

const uint32_t gPeriodVal[3] = {1599, 999, 99};
const uint32_t gDutyVal[3]   = {799, 499, 49};

volatile uint32_t gIndex;
volatile uint32_t gUpdateCnt;

int main(void)
{
    SYSCFG_DL_init();

    gIndex     = 0;
    gUpdateCnt = PWM_PERIOD_UPDATE_CNT;

    NVIC_EnableIRQ(PWM_0_INST_INT_IRQN);

    DL_TimerG_startCounter(PWM_0_INST);

    while (1) {
        __WFI();
    }
}

void PWM_0_INST_IRQHandler(void)
{
    switch (DL_TimerG_getPendingInterrupt(PWM_0_INST)) {
        case DL_TIMERG_IIDX_CC0_DN:
            if (gUpdateCnt == 0) {
                gUpdateCnt = PWM_PERIOD_UPDATE_CNT;

                if (gIndex > ((sizeof(gPeriodVal) / sizeof(uint32_t)) - 1)) {
                    gIndex = 0;
                }
                /**
                 * Updates PWM period and duty cycle during a timer capture compare
                 * interrupt in the down counting mode. Since shadow load and shadow
                 * capture compare mode are configured to trigger during a timer
                 * zero event the PWM update is synchronized until timer reaches
                 * zero.
                 */
                DL_TimerG_setLoadValue(PWM_0_INST, gPeriodVal[gIndex]);
                DL_TimerG_setCaptureCompareValue(PWM_0_INST, gDutyVal[gIndex],
                    DL_TIMERG_CAPTURE_COMPARE_0_INDEX);
                gIndex++;
            } else {
                gUpdateCnt--;
            }
        default:
            break;
    }
}

下图为装载寄存器为1599,比较寄存器位799,PWM频率为625Hz,占空比位50%的PWM波。

下图为装载寄存器为999,比较寄存器位499,PWM频率为1000Hz,占空比位50%的PWM波。

 

下图为装载寄存器为99,比较寄存器位49,PWM频率为10kHz,占空比位50%的PWM波。

总结

MSPM0的定时器可以实现定时中断、PWM输出、事件输出等功能,而且定时器模块的配置也十分灵活,可以实现复杂的应用。搭配SysConfig和MSPM0SDK,嵌入式的应用开发变得很简单。

此帖出自MSPM0 MCU论坛
点赞 关注
 
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表