MSPM0开发学习笔记:TIMER-PWM

讲解 MSPM0 定时器 PWM 原理与 SysConfig 配置,附基础启动代码及按键切换双通道占空比的进阶示例。


MSPM0开发学习笔记

第一章 初步安装与配置
第二章 GPIO
第三章 TIMER
第四章 TIMER-PWM


一、Timer-Pwm原理与作用介绍

PWM通过定时器(TIMER)实现周期性脉冲信号的精确控制,其本质是利用计数器与比较寄存器协同工作生成可调占空比的方波。定时器以系统时钟为基准,通过分频器调整计数频率后驱动计数器循环累加(或递减),当计数值达到预设的自动重载值(ARR)时复位并触发周期更新。在此过程中,比较寄存器(CCRx)设定阈值,当计数值低于阈值时输出高电平,高于阈值时输出低电平,从而通过调节CCRx与ARR的比值动态控制高电平持续时间(占空比)。PWM的核心功能在于将数字信号转化为模拟控制量,通过调节占空比实现电压、功率或机械位置的连续控制,例如驱动电机调速、LED亮度调节、舵机角度控制等场景。多路PWM通道可共享同一定时器,在统一频率下独立调节各通道占空比


二、syscfg配置

1、TIMER-PWM

在这里插入图片描述
在TIMER-PWM中进行配置
1、可以看到,黄色的部分都是上节课TIMER中配置过的,这边就不赘述了,不了解的朋友可以在文章顶部访问上篇文章进行学习。
2、接下来看绿色部分,可以看到这边可以通过设置PWM Period Count 的值来调整生成PWM波的频率,他们的乘积是上面的Calculated Clock Frequency (Hz)
3、再看下面一个绿色的部分 PWM Mode 这个地方是对于波的相位的控制,因为是一下控制多个波输出的(下面白色部分选择了Channel0和Channel2),如果不同波的占空比不同,他们的初始相位就需要我们进行设置,这边选择的Edge-aligned Down Counting边缘对齐,初次之外还有Center-aligned(中心对齐)等方式。可以通过文档中的图来看一下二者的区别
Edge-aligned Down Counting
Edge-aligned Down Counting对齐
Center-aligned中心对齐Center-aligned中心对齐

但是除非我们使用的涉及到无刷电机,否则这个其实并没有什么影响,所以我们这边先选择默认的Edge-aligned Down Counting就好

4、再往下看,灰色部分的就是可以对其中的一个波形进行单独调整的地方,值得注意的是,在同一个TIMER控制的PWM输出不同波中,频率是一定相同的,能改变的只有占空比之类的数据
在这里插入图片描述
5、再继续看一下这边的红色部分,可以配置pwm波的具体输出引脚

配置完之后就可以开始程序的设计了


三、程序设计

具体代码如下:

#include "ti_msp_dl_config.h"

int main(void)
{
    SYSCFG_DL_init();

    DL_TimerG_startCounter(PWM_0_INST);

    while (1) {
        //__WFI();
    }
}

这个的代码还是比较简单的
SYSCFG_DL_init()进行初始化
DL_TimerG_startCounter(PWM_0_INST)开始计时
值得一提的是为什么我要将例程中的__WFI()给注释掉,原因是这个实际上是让板子进入一个低功耗的状态,是好事但是我们在电赛的控制题中是不注重这个低功耗的,并且如果经常在状态转换中出现意想不到的错误,为了避免不必要的麻烦,我们就直接选择不考虑低功耗相关问题了。

四、进阶:按钮控制PWM占空比

我们可以基于这个改一个比较难一点的项目

1、syscfg配置

首先肯定要添加一个按钮的GPIO,这个具体内容在第二章GPIO里面已经讲过了,这边也再过一下,只需要设置下图中圈起来的几个地方就可以了。我们就把GPIO连接到这个PB21上面去了
在这里插入图片描述

2、程序设计

我们要如何在程序中设置/修改PWM波的占空比呢,这个是之前没有涉及到的内容,我们在syscfg中配置之后,我们可以按以下步骤在Debug/ti_msp_dl_config.c中找到我们需要的函数:
在这里插入图片描述
在这里插入图片描述
可以看到这边的DL_TimerG_setCaptureCompareValue就是我们需要的函数

#include "ti_msp_dl_config.h"

int main(void)
{
    SYSCFG_DL_init();

    DL_TimerG_startCounter(PWM_0_INST);

    while (1) {
        if(DL_GPIO_readPins(GPIO_GRP_0_PORT, GPIO_GRP_0_PIN_0_PIN))
        {
            DL_TimerG_setCaptureCompareValue(PWM_0_INST, 22400, DL_TIMER_CC_0_INDEX);
            DL_TimerG_setCaptureCompareValue(PWM_0_INST, 9599, DL_TIMER_CC_1_INDEX);
        }
        else
         {
            DL_TimerG_setCaptureCompareValue(PWM_0_INST, 9599, DL_TIMER_CC_0_INDEX);
            DL_TimerG_setCaptureCompareValue(PWM_0_INST, 22400, DL_TIMER_CC_1_INDEX);
        }
    }
}

DL_TimerG_setCaptureCompareValue的传入参数不会写得话,可以直接在syscfg里面配置完然后按刚才的方法去Debug/ti_msp_dl_config.c里面复制一份就可以,在syscfg里面配置成30% 70%这样然后过去复制 就得到9599 22400这样的Value数据

GPIO按钮那边的传入参数不知道名称的话可以在Debug/ti_msp_dl_config.h里面进行查找(配置完需要编译下才可以)
在这里插入图片描述
这个代码的逻辑还是比较清晰的,按下按钮和松开按钮来调节Channel1和Channel0的占空比。

MSPM0開發學習筆記:TIMER-PWM

講解 MSPM0 定時器 PWM 原理與 SysConfig 配置,附基礎啟動程式碼及按鍵切換雙通道占空比的進階範例。

來源:https://blog.csdn.net/2403_87969572/article/details/148110990

抓取時間(ISO本地):2026-05-18 05:16:58


MSPM0開發學習筆記

第一章 初步安裝與配置
第二章 GPIO
第三章 TIMER
第四章 TIMER-PWM


文章目錄


一、Timer-Pwm原理與作用介紹

PWM通過定時器(TIMER)實現週期性脈衝信號的精確控制,其本質是利用計數器與比較寄存器協同工作生成可調佔空比的方波。定時器以系統時鐘為基準,通過分頻器調整計數頻率後驅動計數器循環累加(或遞減),當計數值達到預設的自動重載值(ARR)時復位並觸發週期更新。在此過程中,比較寄存器(CCRx)設定閾值,當計數值低於閾值時輸出高電平,高於閾值時輸出低電平,從而通過調節CCRx與ARR的比值動態控制高電平持續時間(佔空比)。PWM的核心功能在於將數字信號轉化為模擬控制量,通過調節佔空比實現電壓、功率或機械位置的連續控制,例如驅動電機調速、LED亮度調節、舵機角度控制等場景。多路PWM通道可共享同一定時器,在統一頻率下獨立調節各通道佔空比


二、syscfg配置

1、TIMER-PWM

在這裡插入圖片描述
在TIMER-PWM中進行配置
1、可以看到,黃色的部分都是上節課TIMER中配置過的,這邊就不贅述了,不瞭解的朋友可以在文章頂部訪問上篇文章進行學習。
2、接下來看綠色部分,可以看到這邊可以通過設置PWM Period Count 的值來調整生成PWM波的頻率,他們的乘積是上面的Calculated Clock Frequency (Hz)
3、再看下面一個綠色的部分 PWM Mode 這個地方是對於波的相位的控制,因為是一下控制多個波輸出的(下面白色部分選擇了Channel0和Channel2),如果不同波的佔空比不同,他們的初始相位就需要我們進行設置,這邊選擇的Edge-aligned Down Counting邊緣對齊,初次之外還有Center-aligned(中心對齊)等方式。可以通過文檔中的圖來看一下二者的區別
Edge-aligned Down Counting
Edge-aligned Down Counting對齊
Center-aligned中心對齊Center-aligned中心對齊

但是除非我們使用的涉及到無刷電機,否則這個其實並沒有什麼影響,所以我們這邊先選擇默認的Edge-aligned Down Counting就好

4、再往下看,灰色部分的就是可以對其中的一個波形進行單獨調整的地方,值得注意的是,在同一個TIMER控制的PWM輸出不同波中,頻率是一定相同的,能改變的只有佔空比之類的數據
在這裡插入圖片描述
5、再繼續看一下這邊的紅色部分,可以配置pwm波的具體輸出引腳

配置完之後就可以開始程序的設計了


三、程序設計

具體代碼如下:

#include "ti_msp_dl_config.h"

int main(void)
{
    SYSCFG_DL_init();

    DL_TimerG_startCounter(PWM_0_INST);

    while (1) {
        //__WFI();
    }
}

這個的代碼還是比較簡單的
SYSCFG_DL_init()進行初始化
DL_TimerG_startCounter(PWM_0_INST)開始計時
值得一提的是為什麼我要將例程中的__WFI()給註釋掉,原因是這個實際上是讓板子進入一個低功耗的狀態,是好事但是我們在電賽的控制題中是不注重這個低功耗的,並且如果經常在狀態轉換中出現意想不到的錯誤,為了避免不必要的麻煩,我們就直接選擇不考慮低功耗相關問題了。

四、進階:按鈕控制PWM佔空比

我們可以基於這個改一個比較難一點的項目

1、syscfg配置

首先肯定要添加一個按鈕的GPIO,這個具體內容在第二章GPIO裡面已經講過了,這邊也再過一下,只需要設置下圖中圈起來的幾個地方就可以了。我們就把GPIO連接到這個PB21上面去了
在這裡插入圖片描述

2、程序設計

我們要如何在程序中設置/修改PWM波的佔空比呢,這個是之前沒有涉及到的內容,我們在syscfg中配置之後,我們可以按以下步驟在Debug/ti_msp_dl_config.c中找到我們需要的函數:
在這裡插入圖片描述
在這裡插入圖片描述
可以看到這邊的DL_TimerG_setCaptureCompareValue就是我們需要的函數

#include "ti_msp_dl_config.h"

int main(void)
{
    SYSCFG_DL_init();

    DL_TimerG_startCounter(PWM_0_INST);

    while (1) {
        if(DL_GPIO_readPins(GPIO_GRP_0_PORT, GPIO_GRP_0_PIN_0_PIN))
        {
            DL_TimerG_setCaptureCompareValue(PWM_0_INST, 22400, DL_TIMER_CC_0_INDEX);
            DL_TimerG_setCaptureCompareValue(PWM_0_INST, 9599, DL_TIMER_CC_1_INDEX);
        }
        else
         {
            DL_TimerG_setCaptureCompareValue(PWM_0_INST, 9599, DL_TIMER_CC_0_INDEX);
            DL_TimerG_setCaptureCompareValue(PWM_0_INST, 22400, DL_TIMER_CC_1_INDEX);
        }
    }
}

DL_TimerG_setCaptureCompareValue的傳入參數不會寫得話,可以直接在syscfg裡面配置完然後按剛才的方法去Debug/ti_msp_dl_config.c裡面複製一份就可以,在syscfg裡面配置成30% 70%這樣然後過去複製 就得到9599 22400這樣的Value數據

GPIO按鈕那邊的傳入參數不知道名稱的話可以在Debug/ti_msp_dl_config.h裡面進行查找(配置完需要編譯下才可以)
在這裡插入圖片描述
這個代碼的邏輯還是比較清晰的,按下按鈕和鬆開按鈕來調節Channel1和Channel0的佔空比。

MSPM0 Dev Notes: TIMER-PWM

Covers MSPM0 timer PWM theory, SysConfig setup, starter code, and a button-driven example that swaps duty cycles on two channels.

Captured at (local ISO): 2026-05-18 05:16:58


MSPM0 Development Notes

Chapter 1 Initial Install and Configuration
Chapter 2 GPIO
Chapter 3 TIMER
Chapter 4 TIMER-PWM


I. Timer-PWM Principle and Role

PWM uses a TIMER to generate periodic pulses. A counter runs from the system clock (optionally prescaled); when it hits the auto-reload value (ARR) it resets. A compare register (CCRx) sets the threshold: output is high while count < CCRx and low otherwise. Duty cycle = CCRx / ARR.

PWM turns digital signals into analog-like control—motor speed, LED brightness, servo angle, etc. Multiple PWM channels can share one timer at the same frequency with independent duty cycles.


II. SysConfig Setup

1. TIMER-PWM

在这里插入图片描述
Configure in TIMER-PWM:

  1. Yellow fields match the previous TIMER lesson (see the series intro).
  2. Green: PWM Period Count sets frequency together with Calculated Clock Frequency (Hz).
  3. PWM Mode controls phase when multiple channels run (e.g. Channel0 and Channel2). Edge-aligned down counting is selected here; center-aligned is another option—see the docs:
    Edge-aligned Down Counting
    Edge-aligned down counting
    Center-aligned中心对齐Center-aligned

For most uses (unless brushless motors need center alignment), edge-aligned down counting is fine.

  1. Gray area: per-channel duty settings. Channels on the same TIMER share frequency; only duty/phase differ.
    在这里插入图片描述
  2. Red: assign PWM output pins.

After configuration, write the application.


III. Application Code

#include "ti_msp_dl_config.h"

int main(void)
{
    SYSCFG_DL_init();

    DL_TimerG_startCounter(PWM_0_INST);

    while (1) {
        //__WFI();
    }
}

SYSCFG_DL_init() initializes hardware; DL_TimerG_startCounter(PWM_0_INST) starts the timer.
__WFI() is commented out—it puts the MCU in low power. For competition control tasks we skip low-power modes to avoid odd state transitions during frequent start/stop.

IV. Advanced: Button-Controlled PWM Duty Cycle

1. SysConfig

Add a button GPIO (see Chapter 2). Configure the circled options and connect to PB21.
在这里插入图片描述

2. Application Code

To change duty at runtime, find helpers in Debug/ti_msp_dl_config.c after SysConfig generate:
在这里插入图片描述
在这里插入图片描述
DL_TimerG_setCaptureCompareValue is what you need.

#include "ti_msp_dl_config.h"

int main(void)
{
    SYSCFG_DL_init();

    DL_TimerG_startCounter(PWM_0_INST);

    while (1) {
        if(DL_GPIO_readPins(GPIO_GRP_0_PORT, GPIO_GRP_0_PIN_0_PIN))
        {
            DL_TimerG_setCaptureCompareValue(PWM_0_INST, 22400, DL_TIMER_CC_0_INDEX);
            DL_TimerG_setCaptureCompareValue(PWM_0_INST, 9599, DL_TIMER_CC_1_INDEX);
        }
        else
         {
            DL_TimerG_setCaptureCompareValue(PWM_0_INST, 9599, DL_TIMER_CC_0_INDEX);
            DL_TimerG_setCaptureCompareValue(PWM_0_INST, 22400, DL_TIMER_CC_1_INDEX);
        }
    }
}

Copy argument names from SysConfig-generated code, or set 30%/70% in SysConfig and copy values (e.g. 9599, 22400).
GPIO pin macros are in Debug/ti_msp_dl_config.h after build.
在这里插入图片描述
Logic: press swaps duty on Channel0 vs Channel1.