SLAAE78A August 2024 – August 2025 MSPM0C1105 , MSPM0C1106 , MSPM0G1105 , MSPM0G1106 , MSPM0G1107 , MSPM0G1505 , MSPM0G1506 , MSPM0G1507 , MSPM0G3105 , MSPM0G3106 , MSPM0G3107 , MSPM0G3505 , MSPM0G3506 , MSPM0G3507 , MSPM0H3216 , MSPM0L1105 , MSPM0L1106 , MSPM0L1303 , MSPM0L1304 , MSPM0L1304-Q1 , MSPM0L1305 , MSPM0L1305-Q1 , MSPM0L1306 , MSPM0L1306-Q1 , MSPM0L1343 , MSPM0L1344 , MSPM0L1345 , MSPM0L1346
This example demonstrates how to convert an analog signal to a 4kHz PWM output. The analog input signal is sampled using the MSPM0 integrated ADC. The duty cycle of the PWM output gets updated based on the ADC reading. Two timers are required for this example; one to trigger the ADC reading and another to generate the PWM output. Download the code for this example.
Figure 1-1 displays a functional block diagram of the peripherals used in this example.
This application requires 2 timers, an integrated ADC, and 2 device pins.
Sub-block functionality | Peripheral usage | Notes |
|---|---|---|
Sample triggering | (1x) Timer G | Called TIMER_0_INST in code |
PWM generation | (1x) Timer G | Called PWM_0_INST in code |
Analog signal capture | 1 ADC channel | Called ADC12_0_INST in code |
IO | 2 pins | (1x) ADC input (1x) PWM output |
Figure 1-2 shows the operations performed by application to convert an ADC reading into a PWM output.
This application's PWM output has 10bits of resolution. However, the ADC samples are 12bits, so we must convert the 12 bit ADC readings into 10 bit values that can be used to set the compare value of the PWM timer. Depending on an applications requirements different scaling can be required.
Additionally, more advanced signal processing of the incoming data can be required. For example limiting, averaging or other filtering may be important in different scenarios. These type of operations can be performed in the function below.
void updatePWMfromADCvalue(uint16_t adcValue) {
// Check to see if the adc value is above our minimum threshold
if (adcValue > PWM_DEADBAND)
{
// Convert 12bit adcValue into 10bit value by right
// shifting by 2 because the PWM resolution is 10bit
uint16_t adcValue_10bit = adcValue >> 2;
// PWM timer is configured as a down counter (i.e it
// starts counting down from PWM_LOAD_VAL) and its
// initial state is high therefore we must perform
// the following operation so that small values of
// adcValue_10bit result in small duty cycles
uint16_t ccv = PWM_LOAD_VAL - adcValue_10bit;
// Write the new ccv value into the corresponding timer
// register
DL_TimerG_setCaptureCompareValue(PWM_0_INST,
ccv,
DL_TIMER_CC_0_INDEX);
// Start the timer if it is not already running
if ( !DL_TimerG_isRunning(PWM_0_INST) ) {
DL_TimerG_startCounter(PWM_0_INST);
}
}
else {
// If adcResult is not above deadband value then disable timer
DL_TimerG_stopCounter(PWM_0_INST);
}
}
Figure 1-3 PWM output is disabled when ADC input is below deadband. When the input voltage is below a preset deadband value the output is disabled, as shown in figure 1-3.
Figure 1-4 PWM output duty cycle corresponds to input voltage. In figure 1-4 the input voltage is 2.26V. The measured duty cycle is 67.93%. A quick calculation confirms that the expected duty cycle is 68.4%.
All trademarks are the property of their respective owners.