3524|0

1305

帖子

0

TA的资源

纯净的硅(高级)

楼主
 

【Atmel SAM R21创意大赛周计划】(3) GPIO学习-按键、外部中断和点亮LED [复制链接]

本帖最后由 yang_alex 于 2015-3-15 10:34 编辑

        GPIO在应用中经常用到的场景就是点灯(LED)和按键(SW)。其它的应用和这两种很类似,可以很方便的移植过来。

        现在就跟着ATMEL的例程学习一下怎么增加自己的LED和KEY。
首先相关的定义:
文件:samr21_xplained_pro.h

        对于LED,我们首先要知道它接在哪个GPIO引脚上,亮的时候是接地还是接电源。这些在通过下面的宏定义来完成的。
  1. /** \name LED0 definitions
  2. *  @{ */
  3. #define LED0_PIN                  PIN_PA19
  4. #define LED0_ACTIVE               false
  5. #define LED0_INACTIVE             !LED0_ACTIVE
  6. #define LED0                 LED0_PIN
  7. /** @} */
复制代码


         LED0_PIN是指LED接到哪个GPIO引脚;LED0_ACTIVE是指LED亮(有效)时,对应GPIO的状态---false(0)/true(1)。 LED0_INACTIVE不用说,就是LED灭(无效)时,对应GPIO的状态,和LED0_ACTIVE正好相反。LED0 不用管它吧,只是多了一个名字而已。

        接下来为了能够很方便的借用ASF中已经有的代码,我们要把自己的定义和ASF中已经有的代码关联起来。同样的,也是通过宏定义来实现。
  1. /**
  2. * \name LED #0 definitions
  3. *
  4. * Wrapper macros for LED0, to ensure common naming across all Xplained Pro
  5. * boards.
  6. *
  7. *  @{ */
  8. #define LED_0_NAME                "LED0 (yellow)"
  9. #define LED_0_PIN                 LED0_PIN
  10. #define LED_0_ACTIVE              LED0_ACTIVE
  11. #define LED_0_INACTIVE            LED0_INACTIVE
  12. #define LED0_GPIO                 LED0_PIN

  13. #define LED_0_PWM_MODULE          TC3
  14. #define LED_0_PWM_CHANNEL         1
  15. #define LED_0_PWM_OUTPUT          1
  16. #define LED_0_PWM_PIN             PIN_PA19E_TC3_WO1
  17. #define LED_0_PWM_MUX             MUX_PA19E_TC3_WO1
  18. #define LED_0_PWM_PINMUX          PINMUX_PA19E_TC3_WO1

  19. #define LED_0_PWM4CTRL_MODULE     TCC0
  20. #define LED_0_PWM4CTRL_CHANNEL    3
  21. #define LED_0_PWM4CTRL_OUTPUT     3
  22. #define LED_0_PWM4CTRL_PIN        PIN_PA19F_TCC0_WO3
  23. #define LED_0_PWM4CTRL_MUX        MUX_PA19F_TCC0_WO3
  24. #define LED_0_PWM4CTRL_PINMUX     PINMUX_PA19F_TCC0_WO3
  25. /** @} */
复制代码

       前面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,以方便在状态更新程序中全部都处理到。
  1. /** Number of on-board LEDs */
  2. #define LED_COUNT                 1
复制代码


      对于按键(SW)来说,按键不会涉及到PWM,但会涉及到中断。对于按键(SW),我们首先要知道它接在哪个GPIO引脚上,按下的时候是接地还是接电源。这些在通过下面的宏定义来完成的。
  1. /** \name SW0 definitions
  2. *  @{ */
  3. #define SW0_PIN                   PIN_PA28
  4. #define SW0_ACTIVE                false
  5. #define SW0_INACTIVE              !SW0_ACTIVE

  6. #define SW0_EIC_PIN               PIN_PA28A_EIC_EXTINT8
  7. #define SW0_EIC_MUX               MUX_PA28A_EIC_EXTINT8
  8. #define SW0_EIC_PINMUX            PINMUX_PA28A_EIC_EXTINT8
  9. #define SW0_EIC_LINE              8
  10. /** @} */
复制代码


          前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中已经有的代码关联起来。同样的,也是通过宏定义来实现。   
  1. /**
  2. * \name Button #0 definitions
  3. *
  4. * Wrapper macros for SW0, to ensure common naming across all Xplained Pro
  5. * boards.
  6. *
  7. *  @{ */
  8. #define BUTTON_0_NAME             "SW0"
  9. #define BUTTON_0_PIN              SW0_PIN
  10. #define BUTTON_0_ACTIVE           SW0_ACTIVE
  11. #define BUTTON_0_INACTIVE         SW0_INACTIVE
  12. #define BUTTON_0_EIC_PIN          SW0_EIC_PIN
  13. #define BUTTON_0_EIC_MUX          SW0_EIC_MUX
  14. #define BUTTON_0_EIC_PINMUX       SW0_EIC_PINMUX
  15. #define BUTTON_0_EIC_LINE         SW0_EIC_LINE
  16. /** @} */
复制代码


         同样的,我们也要知道系统中有几个按键(SW),以方便在状态更新程序中全部都处理到。
  1. /** Number of on-board buttons */
  2. #define BUTTON_COUNT 1
复制代码


           现在我们定义好了点灯(LED)和按键(SW)的连接关系,接下来要做的事就是在正常运行前对它们初始化。这是在下面的文件中实现的:
board_init.c
  1.         struct port_config pin_conf;
  2.         port_get_config_defaults(&pin_conf);

  3.         /* Configure LEDs as outputs, turn them off */
  4.         pin_conf.direction  = PORT_PIN_DIR_OUTPUT;
  5.         port_pin_set_config(LED_0_PIN, &pin_conf);
  6.         port_pin_set_output_level(LED_0_PIN, LED_0_INACTIVE);

  7.         /* Set buttons as inputs */
  8.         pin_conf.direction  = PORT_PIN_DIR_INPUT;
  9.         pin_conf.input_pull = PORT_PIN_PULL_UP;
  10.         port_pin_set_config(BUTTON_0_PIN, &pin_conf);
复制代码


        最后我们就是在应用程序中开始使用它们了。下面是一个例子:

       首先我们使用外部中断,那么就先配置一下外部中断:
  1. static void configure_extint(void)
  2. {
  3.         struct extint_chan_conf eint_chan_conf;
  4.         extint_chan_get_config_defaults(&eint_chan_conf);

  5.         eint_chan_conf.gpio_pin           = BUTTON_0_EIC_PIN;
  6.         eint_chan_conf.gpio_pin_mux       = BUTTON_0_EIC_MUX;
  7.         eint_chan_conf.detection_criteria = EXTINT_DETECT_BOTH;
  8.         eint_chan_conf.filter_input_signal = true;
  9.         extint_chan_set_config(BUTTON_0_EIC_LINE, &eint_chan_conf);
  10.         
  11. }



  12. /** Configures and registers the External Interrupt callback function with the
  13. *  driver.
  14. */
  15. static void configure_eic_callback(void)
  16. {
  17.         extint_register_callback(extint_callback,
  18.                         BUTTON_0_EIC_LINE,
  19.                         EXTINT_CALLBACK_TYPE_DETECT);
  20.         extint_chan_enable_callback(BUTTON_0_EIC_LINE,
  21.                         EXTINT_CALLBACK_TYPE_DETECT);
  22.                                                 
  23. }
复制代码


外部中断响应时调用
  1. /** Callback function for the EXTINT driver, called when an external interrupt
  2. *  detection occurs.
  3. */
  4. static void extint_callback(void)
  5. {
  6.         update_led_state();
  7. }
复制代码


         具体的按键和LED的处理程序:
  1. /** Updates the board LED to the current button state. */
  2. static void update_led_state(void)
  3. {
  4.         bool pin_state = port_pin_get_input_level(BUTTON_0_PIN);
  5.         port_pin_set_output_level(LED_0_PIN, pin_state);
  6.         
  7.         
  8. }
复制代码
点赞 关注(1)
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表