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
- Open Project → Options for Target
- Select the Debug tab
- Choose CMSIS-DAP Debugger
- Build the project (F7)
- Download to target (F8)
Key Functions
DL_TimerG_startCounter(): Activates the PWM generatorDL_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.