PWM LED Brightness Control Using MSPM0G3507 and Keil

Project Overview

This project demonstrates controlling LED brightness through PWM (Pulse Width Modulation) on the MSPM0G3507 microcontroller using Keil MDK. Two push buttons adjust the brightness level up and down.

Project Setup

Creating the Project

Obtain the MSPM0 SDK from the officiall Texas Instruments website. Navigate to the driver library examples:

mspm0_sdk_x_xx_xx_xx\examples\nortos\LP_MSPM0G3507\driverlib

Locate the empty project template and create a copy named pwm_led_control. Open the Keil project file (uvprojx) from the project folder.

If project files show warning icons, rebuild the project to resolve any configuration issues.

Sysconfig Configuration

Launch Sysconfig from the Keil project by clicking Tools → Syscnofig.

GPIO Button Configuration

Add a GPIO group named BUTTONS with two pin configurations:

Button 1 (S1):

  • Direction: Input
  • Internal Resistor: Pull-Down
  • Port: PORTA
  • Pin: PA18
  • Interrupt: Enabled
  • Trigger: Rising Edge

Button 2 (S2):

  • Direction: Input
  • Internal Resistor: Pull-Up
  • Port: PORTB
  • Pin: PB21
  • Interrupt: Enabled
  • Trigger: Falling Edge

PWM Configuration

Add a TIMER_PWM module with the following parameters:

  • Timer Clock Prescaler: 32
  • PWM Period Count: 1000
  • PWM Mode: Edge-Aligned Up Counting
  • PWM Channel: Channel 1
  • Initial Compare Value: 200 (20% duty cycle)
  • Output Pin: PB22

Save the configuration and close Sysconfig. The generated configuration files will appear in the Keil project.

Implementation

Main Function

#include "ti_msp_dl_config.h"

volatile uint16_t brightness = 200;

int main(void)
{
    SYSCFG_DL_init();
    
    NVIC_EnableIRQ(BUTTONS_GPIOA_INT_IRQN);
    NVIC_EnableIRQ(BUTTONS_GPIOB_INT_IRQN);
    
    DL_TimerG_startCounter(PWM_0_INST);
    
    while (1) {
        __WFI();
    }
}

Interrupt Handler

void GROUP1_IRQHandler(void)
{
    uint32_t pendingA = DL_GPIO_getPendingInterrupt(GPIOA);
    uint32_t pendingB = DL_GPIO_getPendingInterrupt(GPIOB);
    
    if (pendingA == BUTTONS_KEY_S1_IIDX) {
        delay_cycles(80000);
        
        if (brightness >= 1000) {
            brightness = 200;
        } else {
            brightness += 200;
        }
        
        DL_TimerG_setCaptureCompareValue(
            PWM_0_INST, 
            brightness, 
            DL_TIMERG_CAPTURE_COMPARE_1_INDEX
        );
        
        delay_cycles(80000);
        while (DL_GPIO_readPins(BUTTONS_KEY_S1_PORT, BUTTONS_KEY_S1_PIN));
    }
    
    if (pendingB == BUTTONS_KEY_S2_IIDX) {
        delay_cycles(80000);
        
        if (!DL_GPIO_readPins(BUTTONS_KEY_S2_PORT, BUTTONS_KEY_S2_PIN)) {
            if (brightness <= 200) {
                brightness = 1000;
            } else {
                brightness -= 200;
            }
            
            DL_TimerG_setCaptureCompareValue(
                PWM_0_INST, 
                brightness, 
                DL_TIMERG_CAPTURE_COMPARE_1_INDEX
            );
        }
        
        delay_cycles(80000);
        while (!DL_GPIO_readPins(BUTTONS_KEY_S2_PORT, BUTTONS_KEY_S2_PIN));
    }
}

Building and Programming

  1. Open Project → Options for Target
  2. Select the Debug tab
  3. Choose CMSIS-DAP Debugger
  4. Build the project (F7)
  5. Download to target (F8)

Key Functions

  • DL_TimerG_startCounter(): Activates the PWM generator
  • DL_TimerG_setCaptureCompareValue(): Modifies the duty cycle by updating the compare register

The duty cycle is calculated as: (compare value / period count) × 100%. With a period of 1000 and compare value of 200, the LED operates at 20% brightness.

Tags: MSPM0G3507 PWM LED Keil Embedded Systems

Posted on Thu, 07 May 2026 23:53:42 +0000 by phphelpme