TA的每日心情 | 开心 2018-3-22 09:19 |
---|
签到天数: 144 天 连续签到: 1 天 [LV.7]常住居民III
|
PWM宏控制独立4通道,每个通道控制两个互补的多输出波形.通过用户界面进行配置输出波形的的特性例如周期,占空比,极性和死区时间等。
根据官方文档
程序流程:
● Initialize the system clock and pin setting on the evaluation kit
● Initialize the PWM clock
● Configure the PIN_PWM_LED0_CHANNEL
● Configure the PIN_PWM_LED1_CHANNEL
● Enable the interrupt on counter event for the PIN_PWM_LED0_CHANNEL and
PIN_PWM_LED1_CHANNEL channels
● Change the duty cycle in the ISR
PWM时钟是MCK经分频后输出clkA和clkB
然后就是配置使用的2通道PWM
PWM框图
程序方面
:实现效果,占空比慢慢变大,到达最大后,占空比慢慢变小
/* 使能PWM外围时钟 */
pmc_enable_periph_clk(ID_PWM);
/* 禁用PWM通道 for LEDs */
pwm_channel_disable(PWM, PIN_PWM_LED0_CHANNEL);
pwm_channel_disable(PWM, PIN_PWM_LED1_CHANNEL);
/* 设置PWM时钟A为pwm_frequency * period_value(时钟B不使用) */
pwm_clock_t clock_setting = {
.ul_clka = PWM_FREQUENCY * PERIOD_VALUE,
.ul_clkb = 0,
.ul_mck = sysclk_get_cpu_hz()
};
//初始化PWM时钟(时钟A和时钟B)
pwm_init(PWM, &clock_setting);
/* Initialize PWM channel for LED0 */
/***********************************/
/* 周期左对齐 */
g_pwm_channel_led.alignment = PWM_ALIGN_LEFT;
/* 输出波形开始一个低电平 */
g_pwm_channel_led.polarity = PWM_LOW;
/* 使用PWM的时钟A的时钟源 */
g_pwm_channel_led.ul_prescaler = PWM_CMR_CPRE_CLKA;
/* 输出波形的周期值*/
g_pwm_channel_led.ul_period = PERIOD_VALUE;
/* 输出波形的占空比的值 */
g_pwm_channel_led.ul_duty = INIT_DUTY_VALUE;
g_pwm_channel_led.channel = PIN_PWM_LED0_CHANNEL;
//一个PWM通道初始化
pwm_channel_init(PWM, &g_pwm_channel_led);
/* 使能通道计数器事件中断 */
pwm_channel_enable_interrupt(PWM, PIN_PWM_LED0_CHANNEL, 0);
/* Initialize PWM channel for LED1 */
/***********************************/
/* 周期中间对齐 */
g_pwm_channel_led.alignment = PWM_ALIGN_CENTER;
/* 输出波形开始一个高电平 */
g_pwm_channel_led.polarity = PWM_HIGH;
/* 使用PWM的时钟A的时钟源 */
g_pwm_channel_led.ul_prescaler = PWM_CMR_CPRE_CLKA;
/* 输出波形的周期值 */
g_pwm_channel_led.ul_period = PERIOD_VALUE;
/* 输出波形的占空比的值 */
g_pwm_channel_led.ul_duty = INIT_DUTY_VALUE;
g_pwm_channel_led.channel = PIN_PWM_LED1_CHANNEL;
//一个PWM通道初始化
pwm_channel_init(PWM, &g_pwm_channel_led);
/* 禁止通道计数器事件中断 */
pwm_channel_disable_interrupt(PWM, PIN_PWM_LED1_CHANNEL, 0);
/* 配置中断,使能PWM中断 */
NVIC_DisableIRQ(PWM_IRQn);
NVIC_ClearPendingIRQ(PWM_IRQn);
NVIC_SetPriority(PWM_IRQn, 0);
NVIC_EnableIRQ(PWM_IRQn);
/* 使能PWM通道 for LEDs */
pwm_channel_enable(PWM, PIN_PWM_LED0_CHANNEL);
pwm_channel_enable(PWM, PIN_PWM_LED1_CHANNEL);
//一个通道的PWM中断函数
void PWM_Handler(void)
{
static uint32_t ul_count = 0; /* PWM counter value */
static uint32_t ul_duty= INIT_DUTY_VALUE; /* PWM duty cycle rate */
static uint8_t fade_in = 1; /* LED fade in flag */
uint32_t events = pwm_channel_get_interrupt_status(PWM);
/* PIN_PWM_LED0_CHANNEL 中断 */
if ((events & (1 << PIN_PWM_LED0_CHANNEL)) ==(1 << PIN_PWM_LED0_CHANNEL))
{
ul_count++;
/* Fade in/out */
if (ul_count == (PWM_FREQUENCY / (PERIOD_VALUE - INIT_DUTY_VALUE))) {
/* Fade in */
if (fade_in) {
ul_duty++;
if (ul_duty == PERIOD_VALUE) {
fade_in = 0;
}
} else {
/* Fade out */
ul_duty--;
if (ul_duty == INIT_DUTY_VALUE) {
fade_in = 1;
}
}
/* 设置新的占空比*/
ul_count = 0;
g_pwm_channel_led.channel = PIN_PWM_LED0_CHANNEL;
pwm_channel_update_duty(PWM, &g_pwm_channel_led, ul_duty);
g_pwm_channel_led.channel = PIN_PWM_LED1_CHANNEL;
pwm_channel_update_duty(PWM, &g_pwm_channel_led, ul_duty);
}
}
}
这里尝试把同个通道的2路互补输出
程序修改部分
board_init();函数
#ifdef CONF_BOARD_PWM_LED0
/* Configure PWM LED0 pin */
//PIO_PA19_IDX,(PIO_PERIPH_B | PIO_DEFAULT)
gpio_configure_pin(PIN_PWM_LED0_GPIO, PIN_PWM_LED0_FLAGS);
gpio_configure_pin(PIO_PA23_IDX, (PIO_PERIPH_B | PIO_DEFAULT));
#endif
#ifdef CONF_BOARD_PWM_LED1
/* Configure PWM LED1 pin */
//PIO_PA20_IDX,(PIO_PERIPH_B | PIO_DEFAULT)
gpio_configure_pin(PIN_PWM_LED1_GPIO, PIN_PWM_LED1_FLAGS);
gpio_configure_pin(PIO_PC19_IDX, (PIO_PERIPH_B | PIO_DEFAULT));
#endif
PIO_PCxx_IDX 对应PWM管脚
PIO_PERIPH_B 是根据表的外设选择
|
|