MSPM0L1306小练 输入捕获,翻转LED

[复制链接]
1612|9
 楼主| xyz549040622 发表于 2023-9-8 22:22 | 显示全部楼层 |阅读模式
本帖最后由 xyz549040622 于 2023-9-8 23:21 编辑

程序设计:用户按键触发LED的亮灭,按下按键的时候,LED点亮,按键弹起的时候,LED熄灭,采用中断方式进行捕获。
根据原理图得知,用户LED1-PA0,按键S2-PA14。
微信截图_20230908221320.png 微信截图_20230908221403.png

根据上面原理图可以得出逻辑,挡S2低电平的时候,LED1点亮,S2悬空的时候,LED1熄灭,采用中断方式触发。
因此,我们可以配置PA0为输出,默认输出高电平,熄灭LED,不使能中断。配置PA14为输入,内部弱上拉,使能中断,双向触发,既上升沿和下降沿都可以触发中断。
使用syscfg配置。软件的配置如下:

微信截图_20230908222131.png

微信截图_20230908222013.png
微信截图_20230908222310.png

我们看看IO的初始化代码,很明显的对IO的中断进行了初始化,并使能了PA14的中断。
  1. SYSCONFIG_WEAK void SYSCFG_DL_GPIO_init(void)
  2. {

  3.     DL_GPIO_initDigitalOutput(GPIO_LEDS_USER_LED_1_IOMUX);

  4.     DL_GPIO_initDigitalInputFeatures(GPIO_SWITCHES_USER_SWITCH_1_IOMUX,
  5.                  DL_GPIO_INVERSION_DISABLE, DL_GPIO_RESISTOR_PULL_UP,
  6.                  DL_GPIO_HYSTERESIS_DISABLE, DL_GPIO_WAKEUP_DISABLE);

  7.     DL_GPIO_setPins(GPIOA, GPIO_LEDS_USER_LED_1_PIN);
  8.     DL_GPIO_enableOutput(GPIOA, GPIO_LEDS_USER_LED_1_PIN);
  9.     DL_GPIO_setLowerPinsPolarity(GPIOA, DL_GPIO_PIN_14_EDGE_RISE_FALL);
  10.     DL_GPIO_clearInterruptStatus(GPIOA, GPIO_SWITCHES_USER_SWITCH_1_PIN);
  11.     DL_GPIO_enableInterrupt(GPIOA, GPIO_SWITCHES_USER_SWITCH_1_PIN);

  12. }
然后就是在NVIC中断控制器中启用特定于设备的中断。
  1. NVIC_EnableIRQ(GPIO_SWITCHES_INT_IRQN);
这里虽然使能的是GPIOA_INT_IRQn,但其实占用的是17号异常,INT_GROUP1,所以中断函数需要在INT_GROUP1里面编辑的
  1. typedef enum IRQn
  2. {
  3.   NonMaskableInt_IRQn         = -14,    /* 2  Non Maskable Interrupt */
  4.   HardFault_IRQn              = -13,    /* 3  Hard Fault Interrupt */
  5.   SVCall_IRQn                 = -5,     /* 11 SV Call Interrupt */
  6.   PendSV_IRQn                 = -2,     /* 14 Pend SV Interrupt */
  7.   SysTick_IRQn                = -1,     /* 15 System Tick Interrupt */
  8.   FLASHCTL_INT_IRQn           = 0,      /* 16 FLASHCTL_INT Interrupt */
  9.   WWDT0_INT_IRQn              = 0,      /* 16 WWDT0_INT Interrupt */
  10.   DEBUGSS_INT_IRQn            = 0,      /* 16 DEBUGSS_INT Interrupt */
  11.   SYSCTL_INT_IRQn             = 0,      /* 16 SYSCTL_INT Interrupt */
  12.   GPIOA_INT_IRQn              = 1,      /* 17 GPIOA_INT Interrupt */
  13.   COMP0_INT_IRQn              = 1,      /* 17 COMP0_INT Interrupt */
  14.   TIMG1_INT_IRQn              = 2,      /* 18 TIMG1_INT Interrupt */
  15.   ADC0_INT_IRQn               = 4,      /* 19 ADC0_INT Interrupt */
  16.   SPI0_INT_IRQn               = 9,      /* 25 SPI0_INT Interrupt */
  17.   UART1_INT_IRQn              = 13,     /* 29 UART1_INT Interrupt */
  18.   UART0_INT_IRQn              = 15,     /* 31 UART0_INT Interrupt */
  19.   TIMG0_INT_IRQn              = 16,     /* 32 TIMG0_INT Interrupt */
  20.   TIMG2_INT_IRQn              = 18,     /* 34 TIMG2_INT Interrupt */
  21.   TIMG4_INT_IRQn              = 20,     /* 36 TIMG4_INT Interrupt */
  22.   I2C0_INT_IRQn               = 24,     /* 40 I2C0_INT Interrupt */
  23.   I2C1_INT_IRQn               = 25,     /* 41 I2C1_INT Interrupt */
  24.   DMA_INT_IRQn                = 31,     /* 47 DMA_INT Interrupt */
  25. } IRQn_Type;

微信截图_20230908231243.png

微信截图_20230908231321.png

最后就是中断处理函数了:
  1. void GROUP1_IRQHandler(void)
  2. {
  3.     switch (DL_Interrupt_getPendingGroup(DL_INTERRUPT_GROUP_1)) {
  4.         case GPIO_SWITCHES_INT_IIDX:
  5.             /* If SW is high, turn the LED off */
  6.             if (DL_GPIO_readPins(
  7.                     GPIO_SWITCHES_PORT, GPIO_SWITCHES_USER_SWITCH_1_PIN)) {
  8.                 DL_GPIO_setPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
  9.             }
  10.             /* Otherwise, turn the LED on */
  11.             else {
  12.                 DL_GPIO_clearPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
  13.             }
  14.             break;
  15.     }
  16. }
我们需要在void GROUP1_IRQHandler(void)中进行函数的编辑。
首先是获取IIDX索引,GPIO中断的IIDX==1。也就是CPUSS_INT_GROUP_IIDX_STAT_INT0,然后读取PA14的输入电平,进行LED的操作。
这样把读取电平,然后翻转LED的程序放到中断的好处是,减少了CPU的开销,不需要一直循环读取电平的状态。


 楼主| xyz549040622 发表于 2023-9-9 15:30 | 显示全部楼层
如果需要轮询读取按键状态,然后切换LED的代码,可以参考官方的例程
微信截图_20230909152916.png


  1. #include "ti_msp_dl_config.h"

  2. int main(void)
  3. {
  4.     SYSCFG_DL_init();

  5.     /* LED on by default */

  6.     while (1) {
  7.         if (!DL_GPIO_readPins(
  8.                 GPIO_SWITCHES_PORT, GPIO_SWITCHES_USER_SWITCH_1_PIN)) {
  9.             DL_GPIO_setPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
  10.         } else {
  11.             DL_GPIO_clearPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
  12.         }
  13.     }
  14. }


tpgf 发表于 2023-10-7 14:35 | 显示全部楼层
是使用的io对边沿的触发中断进行捕获吗
nawu 发表于 2023-10-7 15:54 | 显示全部楼层
可以直接使用这种外来的电平反转led吗
aoyi 发表于 2023-10-7 16:57 | 显示全部楼层
这种情况下还需要做防抖的算法吗
zljiu 发表于 2023-10-7 17:27 | 显示全部楼层
可以让小灯亮起来的同时采集这个电平不
 楼主| xyz549040622 发表于 2023-10-8 08:34 | 显示全部楼层
zljiu 发表于 2023-10-7 17:27
可以让小灯亮起来的同时采集这个电平不

在中断中读取IO的电平状态是可以的,例程中也是这么干的,因为是众多IO共用一个中断入口的。
gwsan 发表于 2023-10-9 14:43 | 显示全部楼层
这种应用的情况引脚需要配置成什么模式呢
tfqi 发表于 2023-10-9 15:11 | 显示全部楼层
中断处理函数里边用复杂的语句是不是不太好啊
zwsam 发表于 2023-10-22 08:01 | 显示全部楼层
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:qq群: 嵌入式系统arm初学者 224636155←← +→→点击-->小 i 精品课全集,21ic公开课~~←←→→点击-->小 i 精品课全集,给你全方位的技能策划~~←←

2841

主题

19330

帖子

110

粉丝
快速回复 在线客服 返回列表 返回顶部