打印
[Atmel]

用SAM-BA或JLINK跑ATSAM4E16的程序(9)寄存器PWM

[复制链接]
881|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
在这个程序里,利用PWM点亮两个LED。

而这两个LED的PWM定义及GPIO的第几功能在

以下宏中定义:


/** PWM LED1 pin definitions. */
#define PIN_PWM_LED1_GPIO     PIO_PC20_IDX
#define PIN_PWM_LED1_FLAGS    (IOPORT_MODE_MUX_B)
#define PIN_PWM_LED1_CHANNEL  PWM_CHANNEL_2

/** PWM LED0 pin definitions. */
#define PIN_PWM_LED0_GPIO     PIO_PA0_IDX
#define PIN_PWM_LED0_FLAGS    (IOPORT_MODE_MUX_A)
#define PIN_PWM_LED0_CHANNEL  PWM_CHANNEL_0

以LED1为例,其数据手册,通道B正好是PWM通道2




这样PWM就同LED连接上了。

以下是程序:

#include "asf.h"
#include "stdio_serial.h"
#include "conf_board.h"
#include "conf_clock.h"

/** PWM frequency in Hz */
#define PWM_FREQUENCY      1000
/** Period value of PWM output waveform */
#define PERIOD_VALUE       100
/** Initial duty cycle value */
#define INIT_DUTY_VALUE    0

#define STRING_EOL    "\r"
#define STRING_HEADER "-- PWM LED Example --\r\n" \
                "-- "BOARD_NAME" --\r\n" \
                "-- Compiled: "__DATE__" "__TIME__" --"STRING_EOL

/** PWM channel instance for LEDs */
pwm_channel_t g_pwm_channel_led;

/**
* \brief Interrupt handler for the PWM controller.
*/
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);

        /* Interrupt on 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;
                                }
                        }

                        /* Set new duty cycle */
                        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);
                }
        }
}

/**
*  \brief Configure the Console UART.
*/
static void configure_console(void)
{
        const usart_serial_options_t uart_serial_options = {
                .baudrate = CONF_UART_BAUDRATE,
                .paritytype = CONF_UART_PARITY
        };

        /* Configure console UART. */
        sysclk_enable_peripheral_clock(CONSOLE_UART_ID);
        stdio_serial_init(CONF_UART, &uart_serial_options);
}

/**
* \brief Application entry point for PWM with LED example.
* Output PWM waves on LEDs to make them fade in and out.
*
* \return Unused (ANSI-C compatibility).
*/
int main(void)
{
        /* Initialize the SAM system */
        sysclk_init();
        board_init();

        /* Configure the console uart for debug information */
        configure_console();

        /* Output example information */
        puts(STRING_HEADER);

        /* Enable PWM peripheral clock */
        pmc_enable_periph_clk(ID_PWM);

        /* Disable PWM channels for LEDs */
        pwm_channel_disable(PWM, PIN_PWM_LED0_CHANNEL);
        pwm_channel_disable(PWM, PIN_PWM_LED1_CHANNEL);

        /* Set PWM clock A as PWM_FREQUENCY*PERIOD_VALUE (clock B is not used) */
        pwm_clock_t clock_setting = {
                .ul_clka = PWM_FREQUENCY * PERIOD_VALUE,
                .ul_clkb = 0,
                .ul_mck = sysclk_get_cpu_hz()
        };
        pwm_init(PWM, &clock_setting);

        /* Initialize PWM channel for LED0 */
        /* Period is left-aligned */
        g_pwm_channel_led.alignment = PWM_ALIGN_LEFT;
        /* Output waveform starts at a low level */
        g_pwm_channel_led.polarity = PWM_LOW;
        /* Use PWM clock A as source clock */
        g_pwm_channel_led.ul_prescaler = PWM_CMR_CPRE_CLKA;
        /* Period value of output waveform */
        g_pwm_channel_led.ul_period = PERIOD_VALUE;
        /* Duty cycle value of output waveform */
        g_pwm_channel_led.ul_duty = INIT_DUTY_VALUE;
        g_pwm_channel_led.channel = PIN_PWM_LED0_CHANNEL;
        pwm_channel_init(PWM, &g_pwm_channel_led);

        /* Enable channel counter event interrupt */
        pwm_channel_enable_interrupt(PWM, PIN_PWM_LED0_CHANNEL, 0);

        /* Initialize PWM channel for LED1 */
        /* Period is center-aligned */
        g_pwm_channel_led.alignment = PWM_ALIGN_CENTER;
        /* Output waveform starts at a high level */
        g_pwm_channel_led.polarity = PWM_HIGH;       
        /* Period is left-aligned */
        g_pwm_channel_led.ul_prescaler = PWM_CMR_CPRE_CLKA;
        /* Period value of output waveform */
        g_pwm_channel_led.ul_period = PERIOD_VALUE;
        /* Duty cycle value of output waveform */
        g_pwm_channel_led.ul_duty = INIT_DUTY_VALUE;
        g_pwm_channel_led.channel = PIN_PWM_LED1_CHANNEL;
        pwm_channel_init(PWM, &g_pwm_channel_led);

        /* Disable channel counter event interrupt */
        pwm_channel_disable_interrupt(PWM, PIN_PWM_LED1_CHANNEL, 0);




   
       
        /* Configure interrupt and enable PWM interrupt */
        NVIC_DisableIRQ(PWM_IRQn);
        NVIC_ClearPendingIRQ(PWM_IRQn);
        NVIC_SetPriority(PWM_IRQn, 0);
        NVIC_EnableIRQ(PWM_IRQn);

        /* Enable PWM channels for LEDs */
        pwm_channel_enable(PWM, PIN_PWM_LED0_CHANNEL);
        pwm_channel_enable(PWM, PIN_PWM_LED1_CHANNEL);


  
    ioport_set_pin_level(LED2_GPIO, IOPORT_PIN_LEVEL_LOW);
        ioport_set_pin_level(LED3_GPIO, IOPORT_PIN_LEVEL_LOW);

        /* Infinite loop */
        while (1) {
               
               
               
               
               
        }
}


经测试,两个LED,渐明渐暗。




相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:http://shop34182318.taobao.com/ http://shop562064536.taobao.com

2398

主题

6955

帖子

67

粉丝