使用STVD开发STM8S时中断的处理方法

前言

最近在使用STM8S003F这款芯片进行开发时,遇到了无法进入中断的问题,调试了很久才解决,现在将调试过程记录下来,如果可以帮助到大家,深感荣幸。

IAR中使用中断

项目中使用到了外部中断和定时器中断,这里以外部中断为例。以往使用STM8,都是使用IAR for STM8来进行开发,设置外部中断需要下面几个步骤:

  1. 初始化IO口为中断输入模式
    GPIO_Init(GPIOD, GPIO_PIN_4, GPIO_MODE_IN_PU_IT);
  2. 设置中断触发方式(00: Falling edge and low level;01: Rising edge only;10: Falling edge only;11: Rising and falling edge)
    EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOD, EXTI_SENSITIVITY_FALL_ONLY);
  3. 编写中断服务函数,在 stm8s_it.c 文件中,找到对应的中断处理函数 INTERRUPT_HANDLER(EXTI_PORTD_IRQHandler, 6),在中断处理函数中进行业务逻辑的编写
    /**
      * @brief External Interrupt PORTD Interrupt routine.
      * @param  None
      * @retval None
      */
    INTERRUPT_HANDLER(EXTI_PORTD_IRQHandler, 6)
    {
      /* In order to detect unexpected events during development,
         it is recommended to set a breakpoint on the following instruction.
      */
    
       /********************************
        * 这里是外部中断的内容
        *******************************/
    }
  4. 在main函数中初始化中断,并使能中断,然后就可以正常使用外部中断了。
    EXTI_Init();
    //...
    enableInterrupts();

    问题

  •  因为某些原因,此次使用了STVD和cosmic编译器的方式进行开发。因为是第一次使用STVD,所以在处理中断的时候,就遇到了无法进入中断的问题。
  • 一开始,我按照IAR处理中断的方式,在stm8s_it.c对应的中断处理函数(如上面的INTERRUPT_HANDLER(EXTI_PORTD_IRQHandler, 6))中处理中断,发现外部中断一直都触发不了。最后查找了资料才发现,STVD处理中断的方式和IAR有所不同。
  • STVD处理STM8S中断的步骤大致如下:
  1. 第一、二步与上面IAR相同
  2. 修改中断向量表,这个中断向量表在 stm8_interrupt_vector.c文件中,使用STM8S新建工程的时候会生成这个文件。如图,这里修改了irq3以及irq6,其中EXTI0_PORTA_Interrupte和EXTI3_PORTD_Interrupt可以根据实际命名,这个名字就是后面使用到的中断服务函数的名字。至于这里的irq3和irq6是怎么来的呢,这个要查看芯片对应的数据手册,后面会讲。
  3. 编写中断处理函数。中断处理函数可以在stm8_interrupt_vector.c文件中编写,也可以在其他工程文件中编写,比如bsp_key.c文件中。
    // @bsp_key.c
    @far @interrupt void EXTI3_PORTD_Interrupt (void)
    {
        //外部中断 中断服务函数(所有GPIOD中断都在这里)
        if(KEY_Down(KEY1_PORT, KEY1_PIN) == 0)    //判断是PORTD的哪一个中断
        {
          //中断处理
        }
    }

    在这里有一点需要说明,如果中断处理函数不在stm8_interrupt_vector.c文件中定义,需要在stm8_interrupt_vector.c文件中添加相应的函数声明:

    @far @interrupt void EXIT0_PORTA_Interrupt (void);
    @far @interrupt void EXTI3_PORTD_Interrupt (void);
    @far @interrupt void TIM2_UPD_Interrupt (void);

    然后我们就可以编译项目了,编译的时候会发现提示类似这样的报错:

    Running Linker
    clnk -l"F:\Program Files (x86)\COSMIC\FSE_Compilers\CXSTM8\Lib"  -o Debug\aif-tester.sm8 -mDebug\aif-tester.map Debug\aif-tester.lkf
    #error clnk Debug\aif-tester.lkf:86 Debug\stm8_interrupt_vector.o: symbol f_NonHandledInterrupt multiply defined (Debug\stm8s_it.o)
     The command: "clnk -l"F:\Program Files (x86)\COSMIC\FSE_Compilers\CXSTM8\Lib"  -o Debug\aif-tester.sm8 -mDebug\aif-tester.map Debug\aif-tester.lkf " has failed, the returned value is: 1
    exit code=1.

    这是因为stm8_interrupt_vector.c文件重复定义了@far @interrupt void NonHandledInterrupt (void),我们将stm8_interrupt_vector.c中NonHandledInterrupt的定义注释掉,再#include "stm8s_it.h"头文件,最后编译通过。下载程序后,发现中断可以正常触发了。

 补充

这里补充一点,前面的irq3以及irq6是怎么来的呢?这个需要查找芯片的Datasheet,里面会有一个Interrupt vector mapping章节,这个就是中断向量表,通过查表我们就可以知道中断对应的中断号。

 表格中IRQno. 栏就是中断对应的中断号,也就是我们需要在stm8_interrupt_vector.c文件的struct interrupt_vector const _vectab[]中修改的位置。

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值