In this use case, the PWM module is configured to:
- Output a square wave on PWM channel 0
- The frequency of the square wave is 1KHz
- The duty cycle is changed in the PWM ISR
- Clock A as the source clock
- The output wave can be checked on the selected output pin
Setup steps
Prerequisites
Example code
Add to application C-file:
Input parameters when configuring a PWM channel mode.
{
static uint32_t ul_duty = 0;
uint32_t ul_status;
static uint8_t uc_countn = 0;
static uint8_t uc_flag = 1;
uc_count++;
if (uc_count == 10) {
if (uc_flag) {
ul_duty++;
if (ul_duty == 100) {
uc_flag = 0;
}
} else {
ul_duty--;
if (ul_duty == 0) {
uc_flag = 1;
}
}
uc_count = 0;
}
}
}
uint32_t pwm_channel_update_duty(Pwm *p_pwm, pwm_channel_t *p_channel, uint32_t ul_duty)
Change the duty cycle of the PWM channel.
uint32_t pwm_channel_get_interrupt_status(Pwm *p_pwm)
Get channel counter event and fault protection trigger interrupt status.
#define PWM
(PWM ) Base Address
uint32_t channel
Channel number.
pmc_enable_periph_clk(
ID_PWM);
.ul_clka = 1000 * 100,
.ul_clkb = 0,
.ul_mck = 48000000
};
#define PWM_CMR_CPRE_CLKA
(PWM_CMR) Clock A
uint32_t pwm_init(Pwm *p_pwm, pwm_clock_t *clock_config)
Initialize the PWM source clock (clock A and clock B).
void pwm_channel_enable_interrupt(Pwm *p_pwm, uint32_t ul_event, uint32_t ul_fault)
Enable the interrupt of a channel counter event and fault protection.
void pwm_channel_disable(Pwm *p_pwm, uint32_t ul_channel)
Disable the PWM channel.
uint32_t pwm_channel_init(Pwm *p_pwm, pwm_channel_t *p_channel)
Initialize one PWM channel.
#define ID_PWM
Pulse Width Modulation (PWM).
uint32_t ul_period
Period Cycle Value.
uint32_t ul_prescaler
Channel prescaler.
uint32_t ul_duty
Duty Cycle Value.
Input parameters when initializing PWM.
Workflow
- Define the PWM channel instance in order to configure channel 0:
- Define the PWM interrupt handler in the application:
- In PWM_Handler(), get PWM interrupt status:
- In PWM_Handler(), check whether the PWM channel 0 interrupt has occurred:
- In PWM_Handler(), if the PWM channel 0 interrupt has occurred, update the ul_duty value:
uc_count++;
if (uc_count == 10) {
if (uc_flag) {
ul_duty++;
if (ul_duty >= 100) {
uc_flag = 0;
}
} else {
ul_duty--;
if (ul_duty == 0) {
uc_flag = 1;
}
}
}
- In PWM_Handler(), if the ul_duty value has been updated, change the square wave duty:
- Enable the PWM clock:
pmc_enable_periph_clk(
ID_PWM);
- Disable PWM channel 0:
- Setup clock for PWM module:
.ul_clka = 1000 * 100,
.ul_clkb = 0,
.ul_mck = 48000000
};
- Note
- 1. Only Clock A is configured (clock B is not used).
- The expected frequency is 1KHz, system main clock is assumed to be 48Mhz.
- Initialize channel instance and configure PWM channel 0, selecting clock A as its source clock and setting the initial ducy as 0%:
- Note
- 1. Period is left-aligned and output waveform starts at a low level.
- The pwm_channel_instance can be re-used to configure other PWM channels after setting the required parameters.
- Enable channel 0 interrupt:
- Note
- 1.In order to enable the PWM interrupt, the NVIC must be configured to enable the PWM interrupt. 2. When the channel 0 counter reaches the channel period, the interrupt (counter event) will occur.
Usage steps
Example code
void pwm_channel_enable(Pwm *p_pwm, uint32_t ul_channel)
Enable the PWM channel.
Workflow
- Enable PWM channel 0 and output square wave on this channel: