本帖最后由 yang_alex 于 2015-3-15 10:34 编辑
GPIO在应用中经常用到的场景就是点灯(LED)和按键(SW)。其它的应用和这两种很类似,可以很方便的移植过来。
现在就跟着ATMEL的例程学习一下怎么增加自己的LED和KEY。
首先相关的定义:
文件:samr21_xplained_pro.h
对于LED,我们首先要知道它接在哪个GPIO引脚上,亮的时候是接地还是接电源。这些在通过下面的宏定义来完成的。
- /** \name LED0 definitions
- * @{ */
- #define LED0_PIN PIN_PA19
- #define LED0_ACTIVE false
- #define LED0_INACTIVE !LED0_ACTIVE
- #define LED0 LED0_PIN
- /** @} */
复制代码
LED0_PIN是指LED接到哪个GPIO引脚;LED0_ACTIVE是指LED亮(有效)时,对应GPIO的状态---false(0)/true(1)。 LED0_INACTIVE不用说,就是LED灭(无效)时,对应GPIO的状态,和LED0_ACTIVE正好相反。LED0 不用管它吧,只是多了一个名字而已。
接下来为了能够很方便的借用ASF中已经有的代码,我们要把自己的定义和ASF中已经有的代码关联起来。同样的,也是通过宏定义来实现。
- /**
- * \name LED #0 definitions
- *
- * Wrapper macros for LED0, to ensure common naming across all Xplained Pro
- * boards.
- *
- * @{ */
- #define LED_0_NAME "LED0 (yellow)"
- #define LED_0_PIN LED0_PIN
- #define LED_0_ACTIVE LED0_ACTIVE
- #define LED_0_INACTIVE LED0_INACTIVE
- #define LED0_GPIO LED0_PIN
- #define LED_0_PWM_MODULE TC3
- #define LED_0_PWM_CHANNEL 1
- #define LED_0_PWM_OUTPUT 1
- #define LED_0_PWM_PIN PIN_PA19E_TC3_WO1
- #define LED_0_PWM_MUX MUX_PA19E_TC3_WO1
- #define LED_0_PWM_PINMUX PINMUX_PA19E_TC3_WO1
- #define LED_0_PWM4CTRL_MODULE TCC0
- #define LED_0_PWM4CTRL_CHANNEL 3
- #define LED_0_PWM4CTRL_OUTPUT 3
- #define LED_0_PWM4CTRL_PIN PIN_PA19F_TCC0_WO3
- #define LED_0_PWM4CTRL_MUX MUX_PA19F_TCC0_WO3
- #define LED_0_PWM4CTRL_PINMUX PINMUX_PA19F_TCC0_WO3
- /** @} */
复制代码
前面5项就不用说了,我们来看看LED_0_PWM_XXXX,顾名思义,这是要通过PWM来控制LED的闪烁和亮度,是和PWM相关的。首先LED_0_PWM_MODULE是指定LED的PWM用哪一个定时器,LED_0_PWM_CHANNEL是使用指定的定时器的哪一个通道, LED_0_PWM_OUTPUT是 ,LED_0_PWM_PIN、LED_0_PWM_MUX和LED_0_PWM_PINMUX是前面所说的通道,连到那个引脚;
最后我们要知道系统中有几个LED,以方便在状态更新程序中全部都处理到。
- /** Number of on-board LEDs */
- #define LED_COUNT 1
复制代码
对于按键(SW)来说,按键不会涉及到PWM,但会涉及到中断。对于按键(SW),我们首先要知道它接在哪个GPIO引脚上,按下的时候是接地还是接电源。这些在通过下面的宏定义来完成的。
- /** \name SW0 definitions
- * @{ */
- #define SW0_PIN PIN_PA28
- #define SW0_ACTIVE false
- #define SW0_INACTIVE !SW0_ACTIVE
- #define SW0_EIC_PIN PIN_PA28A_EIC_EXTINT8
- #define SW0_EIC_MUX MUX_PA28A_EIC_EXTINT8
- #define SW0_EIC_PINMUX PINMUX_PA28A_EIC_EXTINT8
- #define SW0_EIC_LINE 8
- /** @} */
复制代码
前3项和LED类似,SW0_PIN定义了按键接到哪个GPIO引脚;LED0_ACTIVE是指按键按下(有效)时,对应GPIO的状态---false(0)/true(1)。 SW0_INACTIVE不用说,就是按键释放(无效)时,对应GPIO的状态,和LED0_ACTIVE正好相反。
接下来我们看SW0_EIC_XXXX,我们前面说到,按键会用到外部中断控制器(EIC),在这里SW0_EIC_PIN、SW0_EIC_MUX、SW0_EIC_PINMUX和SW0_EIC_LINE指定了SW0使用哪一个外部中断。
和LED类似,为了能够很方便的借用ASF中已经有的代码,我们要把自己的定义和ASF中已经有的代码关联起来。同样的,也是通过宏定义来实现。
- /**
- * \name Button #0 definitions
- *
- * Wrapper macros for SW0, to ensure common naming across all Xplained Pro
- * boards.
- *
- * @{ */
- #define BUTTON_0_NAME "SW0"
- #define BUTTON_0_PIN SW0_PIN
- #define BUTTON_0_ACTIVE SW0_ACTIVE
- #define BUTTON_0_INACTIVE SW0_INACTIVE
- #define BUTTON_0_EIC_PIN SW0_EIC_PIN
- #define BUTTON_0_EIC_MUX SW0_EIC_MUX
- #define BUTTON_0_EIC_PINMUX SW0_EIC_PINMUX
- #define BUTTON_0_EIC_LINE SW0_EIC_LINE
- /** @} */
复制代码
同样的,我们也要知道系统中有几个按键(SW),以方便在状态更新程序中全部都处理到。
- /** Number of on-board buttons */
- #define BUTTON_COUNT 1
复制代码
现在我们定义好了点灯(LED)和按键(SW)的连接关系,接下来要做的事就是在正常运行前对它们初始化。这是在下面的文件中实现的:
board_init.c
- struct port_config pin_conf;
- port_get_config_defaults(&pin_conf);
- /* Configure LEDs as outputs, turn them off */
- pin_conf.direction = PORT_PIN_DIR_OUTPUT;
- port_pin_set_config(LED_0_PIN, &pin_conf);
- port_pin_set_output_level(LED_0_PIN, LED_0_INACTIVE);
- /* Set buttons as inputs */
- pin_conf.direction = PORT_PIN_DIR_INPUT;
- pin_conf.input_pull = PORT_PIN_PULL_UP;
- port_pin_set_config(BUTTON_0_PIN, &pin_conf);
复制代码
最后我们就是在应用程序中开始使用它们了。下面是一个例子:
首先我们使用外部中断,那么就先配置一下外部中断:
- static void configure_extint(void)
- {
- struct extint_chan_conf eint_chan_conf;
- extint_chan_get_config_defaults(&eint_chan_conf);
- eint_chan_conf.gpio_pin = BUTTON_0_EIC_PIN;
- eint_chan_conf.gpio_pin_mux = BUTTON_0_EIC_MUX;
- eint_chan_conf.detection_criteria = EXTINT_DETECT_BOTH;
- eint_chan_conf.filter_input_signal = true;
- extint_chan_set_config(BUTTON_0_EIC_LINE, &eint_chan_conf);
-
- }
- /** Configures and registers the External Interrupt callback function with the
- * driver.
- */
- static void configure_eic_callback(void)
- {
- extint_register_callback(extint_callback,
- BUTTON_0_EIC_LINE,
- EXTINT_CALLBACK_TYPE_DETECT);
- extint_chan_enable_callback(BUTTON_0_EIC_LINE,
- EXTINT_CALLBACK_TYPE_DETECT);
-
- }
复制代码
外部中断响应时调用
- /** Callback function for the EXTINT driver, called when an external interrupt
- * detection occurs.
- */
- static void extint_callback(void)
- {
- update_led_state();
- }
复制代码
具体的按键和LED的处理程序:
- /** Updates the board LED to the current button state. */
- static void update_led_state(void)
- {
- bool pin_state = port_pin_get_input_level(BUTTON_0_PIN);
- port_pin_set_output_level(LED_0_PIN, pin_state);
-
-
- }
复制代码