查看: 777|回复: 0

SAM4S Xplained Pro的PWM测试例程

[复制链接]
  • TA的每日心情
    开心
    2018-3-22 09:19
  • 签到天数: 144 天

    连续签到: 1 天

    [LV.7]常住居民III

    发表于 2014-11-26 16:59:03 | 显示全部楼层 |阅读模式
    分享到:
    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 是根据表的外设选择

    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-4-26 15:55 , Processed in 0.115191 second(s), 17 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.