SAM4S Xplained Pro的PWM测试例程

作者: lanyuye
上传时间为: 2014-11-26 04:59 PM
2014-11-26
阅读:

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 是根据表的外设选择

全部评论 ()
条评论
写评论

创建讨论帖子

登录 后参与评论
系统提示