打印
[技术问答]

华大H32F460的MCU的中断是怎么用的呢?看了用户手册还是没...

[复制链接]
7094|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
binoo7|  楼主 | 2021-1-18 11:18 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
华大H32F460的MCU的中断是怎么用的呢?看了用户手册还是没看懂

使用特权

评论回复
沙发
binoo7|  楼主 | 2021-1-18 11:39 | 只看该作者
下面具体说说我看到的手册里的内容
首先
中断控制器(INTC)的功能有
1. 选择中断事件请求作为中断输入到 NVIC,唤醒 WFI;
2. 选择中断事件请求作为事件输入,唤醒 WFE
3. 选择中断事件请求作为低功耗模式(休眠模式和停止模式)的唤醒条件;
4. 外部管脚 NMI 和 EIRQ 的中断控制功能;
5. 软件中断的中断/事件选择功能。
这5个功能,这个是简介

使用特权

评论回复
板凳
binoo7|  楼主 | 2021-1-18 12:24 | 只看该作者
经过对比STM32的中断配置
 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
          NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
          NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;                //子优先级3
          NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQ通道使能
          NVIC_Init(&NVIC_InitStructure);        //根据指定的参数初始化VIC寄存器
NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
         NVIC_ClearPendingIRQ(stcIrqRegiCfg.enIRQn);
         NVIC_EnableIRQ(stcIrqRegiCfg.enIRQn);

这样对比的话应该是看不出什么的,别着急 继续往内部看
STM32的配置过程
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)
{
  uint32_t tmppriority = 0x00, tmppre = 0x00, tmpsub = 0x0F;
  
  /* Check the parameters */
  assert_param(IS_FUNCTIONAL_STATE(NVIC_InitStruct->NVIC_IRQChannelCmd));
  assert_param(IS_NVIC_PREEMPTION_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority));  
  assert_param(IS_NVIC_SUB_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelSubPriority));
   
  if (NVIC_InitStruct->NVIC_IRQChannelCmd != DISABLE)
  {
    /* Compute the Corresponding IRQ Priority --------------------------------*/   
    tmppriority = (0x700 - ((SCB->AIRCR) & (uint32_t)0x700))>> 0x08;
    tmppre = (0x4 - tmppriority);
    tmpsub = tmpsub >> tmppriority;

    tmppriority = (uint32_t)NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << tmppre;
    tmppriority |=  NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub;
    tmppriority = tmppriority << 0x04;
        
    NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel] = tmppriority;
   
    /* Enable the Selected IRQ Channels --------------------------------------*/
    NVIC->ISER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] =
      (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);
  }
  else
  {
    /* Disable the Selected IRQ Channels -------------------------------------*/
    NVIC->ICER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] =
      (uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);
  }
}

下面是华大的配置过程
__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
  if ((int32_t)(IRQn) >= 0)
  {
    NVIC->IP[((uint32_t)IRQn)]               = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
  }
  else
  {
    SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
  }
}
__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn)
{
  if ((int32_t)(IRQn) >= 0)
  {
    NVIC->ICPR[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
  }
}
__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn)
{
  if ((int32_t)(IRQn) >= 0)
  {
    __COMPILER_BARRIER();
    NVIC->ISER[(((uint32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
    __COMPILER_BARRIER();
  }
}

使用特权

评论回复
地板
binoo7|  楼主 | 2021-1-18 12:29 | 只看该作者
通过上面的对比应该看出来了吧 ,首先都是要给NVIC->IP赋值 从STM32那应该能猜出是NVIC_InitStruct->NVIC_IRQChannel 这个是选择的IRQ通道号
其实第二步直接使能就行了 因为在STM32里有一个步骤是如果不使能会清除标志位,但是在华大里他没有这么用,而是在每次使能前清除相应的标志位
这样反过来看华大的用户手册里 他是这么写的
1. 需要使用 NMI 管脚时,先将 INT_NMICR.NFEN 位清“0”,禁止数字滤波器;设定
INT_NMICR 寄存器的 NMITRG 位,选择 NMI 触发边沿;设定 SMPCLK 位选择
数字滤波器的采样时钟;设定 NFEN 位,使能数字滤波器。
2. 使用其他不可屏蔽中断事件请求时,请配置相应的功能。
3. 对 INT_NMICFR 各寄存器位写“1”,清除 INT_NMIFR 标志寄存器位,防止误动
作。
4. 通过设定 INT_NMIENR 选择寄存器来使能不可屏蔽中断事件。
注意:
– 一旦INT_NMIENR相应位被设定为“1”后,将不能被更改,除非用RESET 来复位。
ICG 设定只针对外部 NMI 管脚,通过配置 ICG 寄存器 ICG1.NMIICGENA 位,使能
HC32F460 系列用户手册 Rev1.21  Page 283 of 1141
ICG 设定。设定 ICG1.NMITRG 选择 NMI 触发边沿;设定 ICG1.SMPCLK 位选择数字
滤波器采样时钟;设定 ICG1.NFEN 位,使能数字滤波器;设定 ICG1.NMIENR 位,使
能 NMI 管脚中断。ICG 设定后,寄存器设定无效。ICG1 的寄存器说明,请参考初始
化配置(ICG)章节。
10.4.2  外部管脚中断事件请求
需要使用外部管脚中断事件请求时,请按照如下流程设定:
1. 清除 INT_EIRQCRm.EFEN 位(m=0~15),禁止数字滤波器。
2. 设定 INT_EIRQCRm 的 IRQTRG[1:0]位,选择触发边沿或电平;设定 SMPCLK[1:0]
位,选择数字滤波器采样时钟;设定 EFEN 位,使能数字滤波器。

使用特权

评论回复
5
binoo7|  楼主 | 2021-1-18 12:32 | 只看该作者
本来挺简单的中断优先级配置,却让他的用户手册搞的那么复杂,结贴了,感谢各位大神观看了

使用特权

评论回复
6
binoo7|  楼主 | 2021-1-22 11:06 | 只看该作者
本帖最后由 binoo7 于 2021-1-22 23:10 编辑

#申请原创#
现在又经过了几天的学习,再来说一下中断的事儿吧
首先HC32F460用的是Cortex-M4的内核,这个内核有16个异常,也就是ARM的M4自带的叫做异常

还有多达 256 级的可编程优先级,并且支持 128级抢占,这个就是芯片厂商负责的部分了,例如HC32F460 定义了144个中断向量
因为用的是Cortex-M4的内核,支持中断优先级分组,分组的方式见图片
根据HC32F460的例程给出的定义
#define __NVIC_PRIO_BITS          4       /*!< HC32F46X uses 4 Bits for the Priority Levels         */
他们用了前4位来配置优先级分组
但是这个分组不知道能不能配置,因为例程里设置的是一个固定的分组  组0  也就是所有的中断都在同一个抢占优先级,而大家都在剩余的亚优先级内,举个例子比如
以下转自野火教程

中断向量具有两个属性,一个为抢占属性,另一个为响应属性,其属性编号越小,表明它的优先级别越高。
抢占,是指打断其他中断的属性,即因为具有这个属性会出现嵌套中断(在执行中断服务函数A 的过程中被中断B 打断,执行完中断服务函数B 再继续执行中断服务函数A)

中断向量                              抢占优先级                                        亚优先级(响应优先级)

A                                             0                                                              0

B                                             1                                                              0

C                                             1                                                              1

若内核正在执行C 的中断服务函数,则它能被抢占优先级更高的中断A 打断,

由于B和C 的抢占优先级相同,所以C 不能被B 打断。

但如果B 和C 中断是同时到达的,内核就会首先响应响应优先级别更高的B 中断。


这样的解释大家应该都清楚了吧


SCB->AIRCR的配置,可以配置中断优先级分组,HC32F460的配置是这样的

<font color="rgb(77,77,77)"><font face="-apple-system,"><font size="3">__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
{
  uint32_t reg_value;
  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);             /* only values 0..7 are used          */

  reg_value  =  SCB->AIRCR;                                                   /* read old register configuration    */
  reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change               */
  reg_value  =  (reg_value                                   |
                ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
                (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos)  );              /* Insert write key and priority group */
  SCB->AIRCR =  reg_value;
}
</font></font></font>




但是这个函数并没有用到,而是在这个函数里配置了
/**
  \brief   System Reset
  \details Initiates a system reset request to reset the MCU.
*/
__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void)
{
  __DSB();                                                          /* Ensure all outstanding memory accesses included
                                                                       buffered write are completed before reset */
  SCB->AIRCR  = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos)    |
                           (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
                            SCB_AIRCR_SYSRESETREQ_Msk    );         /* Keep priority group unchanged */
  __DSB();                                                          /* Ensure completion of memory access */

  for(;;)                                                           /* wait until reset */
  {
    __NOP();
  }
}




解释一下华大用的这个配置函数,他将SCB->AIRCR寄存器&上了0x700,在权威指南里对于SCB->AIRCR优先级分组在复位后所有的数据都会是0,也就说在每次复位后,SCB->AIRCR寄存器&0x700=0,也就是将中断优先级分组配置成了组4
第04组: 所有4 位用来配置抢占优先级。
是不是大家有疑惑了,他才有16个抢占中断优先级,他的中断向量表不是有144个啊,这也不够用啊
别担心,这144个中断向量不是说每一个向量都要占一个中断优先级,可以几个中断向量占同一个中断优先级,谁先来,就先响应谁,等这个中断结束了,再依次响应其他优先级低的中断,如果优先级高的中断来了,就会响应高优先级的中断,这样就形成了中断的嵌套,这么说的话大家就清楚了吧。
可以根据自己的需要来修改#define SCB_AIRCR_PRIGROUP_Msk             (7UL << SCB_AIRCR_PRIGROUP_Pos)                /*!< SCB AIRCR: PRIGROUP Mask */是7还是6/5/4/3 这样的话就可以得到响应的中断优先级分组了,还有可以调用




__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
{
  uint32_t reg_value;
  uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL);             /* only values 0..7 are used          */

  reg_value  =  SCB->AIRCR;                                                   /* read old register configuration    */
  reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change               */
  reg_value  =  (reg_value                                   |
                ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
                (PriorityGroupTmp << SCB_AIRCR_PRIGROUP_Pos)  );              /* Insert write key and priority group */
  SCB->AIRCR =  reg_value;
}







这个函数来改变中断优先级  。
在权威指南里还说了这样一句话大家要注意:
其实在绝大多数情况下,优先级的分组都要预先经过计算论证,并且在开机初始化时一次性地设置好,以后就再也不动它了。
只有在绝对需要且绝对有把握时,才小心地更改,并且要经过尽可能充分的测试。

另外,优先级组所在的寄存器 AIRCR也基本上是“一次成型”,只是需要手工产生复位时才写里面相应的位。


异常.jpg (166.5 KB )

异常

异常

优先级分组.jpg (61.96 KB )

优先级分组

优先级分组

使用特权

评论回复
7
flycamelaaa| | 2021-1-22 14:16 | 只看该作者
学习了,哈哈,楼主研究的很透彻

使用特权

评论回复
8
binoo7|  楼主 | 2021-1-22 15:19 | 只看该作者
flycamelaaa 发表于 2021-1-22 14:16
学习了,哈哈,楼主研究的很透彻

现在流行,给点个赞再走啊

使用特权

评论回复
9
binoo7|  楼主 | 2021-2-25 00:00 | 只看该作者
今天再补充一点,关于中断的
 /* Set USART RX error IRQ */
    stcIrqRegiCfg.enIRQn = Int001_IRQn;


这次我用串口中断来举例子
    stcIrqRegiCfg.enIRQn = Int001_IRQn;
这个是要配置的这里IrqHandler[pstcIrqRegiConf->enIRQn] = pstcIrqRegiConf->pfnCallback;
这里的stcIrqRegiCfg.enIRQn = Int001_IRQn在通过配置文件后就相当于上面蓝色的部分,
IrqHandler[]一看以为是个数组,其实不然,他是一个指针,数组类型的函数指针,为什么这么说呢
func_ptr_t IrqHandler[IRQ_NUM_MAX] = {NULL};
func_ptr_t是什么呢 查看原型能发现
typedef void (*func_ptr_t)(void);
看这个定义眼熟吗? 如果还没看明白的话看下面这个函数的定义
void delay (void)
{
   //
}
是不是一样啊?


我们再来分析这句话的意思
IrqHandler[pstcIrqRegiConf->enIRQn] = pstcIrqRegiConf->pfnCallback;
pfnCallback这个回调函数的函数指针赋值给IrqHandler[pstcIrqRegiConf->enIRQn] 这个指针
也就是说如果调用IrqHandler这个函数的话,就调用了pfnCallback这个回调函数,
有一点很关键pstcIrqRegiConf->enIRQn大家一定要记住了,不同的回调函数不能用同一个中断向量
例如两个串口的接收中断,就不能都设置成Int001_IRQn记住了啊,
而中断优先级是怎么配置的呢?因为给的库函数里没有配置中断优先级,默认是优先级4,也就是全部都是抢占优先级,没有子优先级
不过为了保险起见,还是建议大家都配置一下中断优先级分组,然后再配置中断优先级
真正在这里起作用的是NVIC_SetPriority(stcIrqRegiCfg.enIRQn, DDL_IRQ_PRIORITY_DEFAULT);
NVIC_SetPriority()就是库函数给的设置中断优先级的函数,直接调用这个函数就能配置优先级
stcIrqRegiCfg.enIRQn 是
__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
  if ((int32_t)(IRQn) >= 0)
  {
    NVIC->IP[((uint32_t)IRQn)]               = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
  }
  else
  {
    SCB->SHP[(((uint32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
  }
}


真正配置的是NVIC->IP[IRQn]
IP[IRQn]:全称是:Interrupt Priority Registers,是一个中断优先级控制的寄存器组。
IP 寄存器组由 240 个 8bit的寄存器组成,每个可屏蔽中断占用 8bit,这样总共可以表示 240 个可屏蔽中断。

而HC32F460只用到了其中的DCD     IRQ143_Handler        ; IRQ143_Handler 也就是144个。IP[143]~IP[0]分别对应中断 143~0。
而每个可屏蔽中断占用的 8bit 并没有全部使用,而是只用了高 4 位。
这 4 位,又分为抢占优先级和响应优先级。
抢占优先级在前,响应优先级在后。
而这两个优先级各占几个位又要根据 SCB->AIRCR 中的中断分组设置来决定

DDL_IRQ_PRIORITY_DEFAULT就是对应的抢占优先级和子优先级,所以记住了stcIrqRegiCfg.enIRQn千万不要设置成一样的,否则会导致只有最后一个起作用,其他的都不起作用!!!




使用特权

评论回复
10
McuPlayer| | 2021-4-8 23:03 | 只看该作者
楼主这记录学习的过程是个非常好的习惯

使用特权

评论回复
11
KingKongHJG| | 2021-4-11 23:13 | 只看该作者
都是Cortex-M4的内核,华大的库整的太复杂......

使用特权

评论回复
12
心灵的天空| | 2021-9-23 17:00 | 只看该作者
果断关注楼主

使用特权

评论回复
13
zengxing3624| | 2021-10-29 09:01 | 只看该作者
我是一直没弄明白,我配置的IO用来做中断,单起一个工程跑没有问题,加到别的工程里,就一直中断,一直响应,没按键也响应,实在找不到问题,能不能懂的帮看看。
#include "hc32_ddl.h"

#define LED1_PORT   PortD
#define LED1_Pin    Pin02

#define LED2_PORT   PortB
#define LED2_Pin    Pin03

#define LED3_PORT   PortB
#define LED3_Pin    Pin04

#define LED4_PORT   PortB
#define LED4_Pin    Pin05

#define KEY1_PORT   PortD
#define KEY1_Pin    Pin02

#define KEY2_PORT   PortC
#define KEY2_Pin    Pin12

#define KEY3_PORT   PortA
#define KEY3_Pin    Pin06

typedef struct{
        uint8_t        key1:1;
        uint8_t        key2:1;
        uint8_t        key3:1;
        uint8_t        key4:1;
        uint8_t        key5:1;
        uint8_t        key6:1;
        uint8_t        key7:1;
        uint8_t        key8:1;
}Key_IO_bit_t;

typedef union{
        Key_IO_bit_t keys;
        uint8_t status;
}KEY_status_t;

void User_Gpio_Init(void)
{
  stc_port_init_t Port_CFG;

        MEM_ZERO_STRUCT(Port_CFG);

        Port_CFG.enPinMode = Pin_Mode_Out;

        PORT_Init(LED1_PORT, LED1_Pin, &Port_CFG);
        PORT_Init(LED2_PORT, LED2_Pin, &Port_CFG);
        PORT_Init(LED3_PORT, LED3_Pin, &Port_CFG);
        PORT_Init(LED4_PORT, LED4_Pin, &Port_CFG);
   
}
static void key_1_callback(void){
                static int i = 0;
                KEY_status_t keyGroup = {0};
                if(i == 65534){
                                i = 0;
                }
                if(Set == EXINT_Irq**Get(ExtiCh01)){

                               
                        do{
                                keyGroup.keys.key1 =  PORT_GetBit(KEY1_PORT, KEY1_Pin);
                                keyGroup.keys.key2 =  PORT_GetBit(KEY2_PORT, KEY2_Pin);
                                keyGroup.keys.key3 =  PORT_GetBit(KEY3_PORT, KEY3_Pin);
                                if(keyGroup.status != 7) break;
                        }while(1);
                       
                        Ddl_Delay1ms(40);
                       
                        if((keyGroup.keys.key1 == Reset) && (Reset == PORT_GetBit(KEY1_PORT, KEY1_Pin))){
                               
                                if(i%2== 1){
                                PORT_ResetBits(LED1_PORT,LED1_Pin);
                                }else{
                                        PORT_SetBits(LED1_PORT,LED1_Pin);
                                }
                                //logDebug("key1Press! cnt:%d\n",i);
                                i++;
                        }else if((keyGroup.keys.key2 == Reset) && (Reset == PORT_GetBit(KEY2_PORT, KEY2_Pin))){
                                if(i%2== 1){
                                PORT_ResetBits(LED2_PORT,LED2_Pin);
                                }else{
                                        PORT_SetBits(LED2_PORT,LED2_Pin);
                                }
                                //logDebug("key2Press! cnt:%d\n",i);
                                i++;
                        }else if((keyGroup.keys.key3 == Reset) && (Reset == PORT_GetBit(KEY3_PORT, KEY3_Pin))){
                               
                                if(i%2== 1){
                                PORT_ResetBits(LED3_PORT,LED3_Pin);
                                }else{
                                        PORT_SetBits(LED3_PORT,LED3_Pin);
                                }
                        //        logDebug("key3Press! cnt:%d\n",i);
                                i++;
                        }
                       
       /* clear int request flag */
      EXINT_Irq**Clr(ExtiCh01);
                }
}

void Init_intruppt()
{
       
    stc_exint_config_t stcExtiConfig;        /* 外部中断配置结构体 */
    stc_irq_regi_conf_t stcIrqRegiConf; /*irq配置结构体 */
    stc_port_init_t stcPortInit;        /*管脚配置结构体 */

     /* configuration structure initialization */
    MEM_ZERO_STRUCT(stcExtiConfig);
    MEM_ZERO_STRUCT(stcIrqRegiConf);
    MEM_ZERO_STRUCT(stcPortInit);

    /* Set PD06 as External Int Ch.6 input */
    stcPortInit.enExInt = Enable;
        PORT_Init(KEY1_PORT, KEY1_Pin, &stcPortInit);
        PORT_Init(KEY2_PORT, KEY2_Pin, &stcPortInit);
        PORT_Init(KEY3_PORT, KEY3_Pin, &stcPortInit);

    stcExtiConfig.enExitCh = ExtiCh01;
        /* 过滤器配置 */
    stcExtiConfig.enFilterEn = Enable;
    stcExtiConfig.enFltClk = Pclk3Div8;
    /* 低电平触发(触发模式) */
    stcExtiConfig.enExtiLvl = ExIntLowLevel;
    EXINT_Init(&stcExtiConfig);

    /* 选择外部中断通道 Ch.1 */
    stcIrqRegiConf.enIntSrc = INT_PORT_EIRQ1;
    /*注册外部中断 to Vect.No.000 */
    stcIrqRegiConf.enIRQn = Int000_IRQn;
    /* 绑定回调函数 */
    stcIrqRegiConf.pfnCallback = &key_1_callback;
    enIrqRegistration(&stcIrqRegiConf);

    /* Clear Pending */
    NVIC_ClearPendingIRQ(stcIrqRegiConf.enIRQn);

    /* 配置优先级 */
    NVIC_SetPriority(stcIrqRegiConf.enIRQn, DDL_IRQ_PRIORITY_15);

    /* 使能 NVIC */
        NVIC_EnableIRQ(stcIrqRegiConf.enIRQn);

}

int32_t main()
{
        User_Gpio_Init();
        Init_intruppt();
        while(1)
        {
                ;;;
        }
       
}
       

使用特权

评论回复
14
wubangmi| | 2021-10-29 13:37 | 只看该作者
zengxing3624 发表于 2021-10-29 09:01
我是一直没弄明白,我配置的IO用来做中断,单起一个工程跑没有问题,加到别的工程里,就一直中断,一直响应 ...

#define KEY1_PORT   PortD
#define KEY1_Pin    Pin02

#define KEY2_PORT   PortC
#define KEY2_Pin    Pin12

#define KEY3_PORT   PortA
#define KEY3_Pin    Pin06

你所定义的IO就没有一个是Pin01的,但是你中断源却选择的是Pin01的中断,你能跑正常就奇怪了。

使用特权

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

本版积分规则

49

主题

455

帖子

9

粉丝