钻石火彩评级:在Keil中通过中断向量表给STM32F103添加中断处理函数(第二种方法——超简单)(去除废话篇!)

来源:百度文库 编辑:中财网 时间:2024/04/29 09:46:12

在Keil中通过中断向量表给STM32F103添加中断处理函数(第二种方法——超简单)(去除废话篇!)  

2010-01-04 23:41:59|  分类: STM32 CortexF103 |  标签: |字号大中小 订阅

我用的是Keil自带的启动文件"STM32F10x.s"

自己写好中断处理函数,比如我写的是(给ADC用的中断处理函数):

//
#define SR_EOC 0x00000002
#define SR_AWD 0x00000001
void ADC_NATIVE_IRQHandler(void){

u16 value_adc;
 if(ADC_NATIVE->SR&SR_EOC){//EOC
  value_adc=ADC_NATIVE->DR&0x0000FFFF;
  ADC_NATIVE->SR&=(~SR_EOC);
 }
 if(ADC_NATIVE->SR&SR_AWD){//AWD
  ADC_NATIVE->SR&=(~SR_AWD);
 } 
 }
}

然后用函数名"ADC_NATIVE_IRQHandler"全部替换"STM32F10x.s"文件里的"ADC_IRQHandler"(因为这个文件默认给ADC的中断处理函数是ADC_IRQHandler)。

同时设置ADC的CR1寄存器把EOC和AWD中断使能。

我在网上找了很多例子,都没法用,只好自己摸索了。

我用的是Keil自带的启动文件"STM32F10x.s"

要自己添加中断处理函数,只要修改这个文件就可以了。当然,中断处理函数还是要自己写的,吼吼!

首先看一下这个文件的一部分代码:

; Vector Table Mapped to Address 0 at Reset

                AREA    RESET, DATA, READONLY
                EXPORT  __Vectors

__Vectors       DCD     __initial_sp              ; Top of Stack
                DCD     Reset_Handler             ; Reset Handler
                DCD     NMI_Handler               ; NMI Handler
                DCD     HardFault_Handler         ; Hard Fault Handler
                DCD     MemManage_Handler         ; MPU Fault Handler
                DCD     BusFault_Handler          ; Bus Fault Handler
                DCD     UsageFault_Handler        ; Usage Fault Handler
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     0                         ; Reserved
                DCD     SVC_Handler               ; SVCall Handler
                DCD     DebugMon_Handler          ; Debug Monitor Handler
                DCD     0                         ; Reserved
                DCD     PendSV_Handler            ; PendSV Handler
                DCD     SysTick_Handler           ; SysTick Handler

                ; External Interrupts
                DCD     WWDG_IRQHandler           ; Window Watchdog
                DCD     PVD_IRQHandler            ; PVD through EXTI Line detect
                DCD     TAMPER_IRQHandler         ; Tamper
                DCD     RTC_IRQHandler            ; RTC
                DCD     FLASH_IRQHandler          ; Flash
                DCD     RCC_IRQHandler            ; RCC
                DCD     EXTI0_IRQHandler          ; EXTI Line 0
                DCD     EXTI1_IRQHandler          ; EXTI Line 1
                DCD     EXTI2_IRQHandler          ; EXTI Line 2
                DCD     EXTI3_IRQHandler          ; EXTI Line 3
                DCD     EXTI4_IRQHandler          ; EXTI Line 4
                DCD     DMAChannel1_IRQHandler    ; DMA Channel 1
                DCD     DMAChannel2_IRQHandler    ; DMA Channel 2
                DCD     DMAChannel3_IRQHandler    ; DMA Channel 3
                DCD     DMAChannel4_IRQHandler    ; DMA Channel 4
                DCD     DMAChannel5_IRQHandler    ; DMA Channel 5
                DCD     DMAChannel6_IRQHandler    ; DMA Channel 6
                DCD     DMAChannel7_IRQHandler    ; DMA Channel 7
                DCD     ADC_IRQHandler            ; ADC
                DCD     USB_HP_CAN_TX_IRQHandler  ; USB High Priority or CAN TX
                DCD     USB_LP_CAN_RX0_IRQHandler ; USB Low  Priority or CAN RX0
                DCD     CAN_RX1_IRQHandler        ; CAN RX1
                DCD     CAN_SCE_IRQHandler        ; CAN SCE
                DCD     EXTI9_5_IRQHandler        ; EXTI Line 9..5
                DCD     TIM1_BRK_IRQHandler       ; TIM1 Break
                DCD     TIM1_UP_IRQHandler        ; TIM1 Update
                DCD     TIM1_TRG_COM_IRQHandler   ; TIM1 Trigger and Commutation
                DCD     TIM1_CC_IRQHandler        ; TIM1 Capture Compare
                DCD     TIM2_IRQHandler           ; TIM2
                DCD     TIM3_IRQHandler           ; TIM3
                DCD     TIM4_IRQHandler           ; TIM4
                DCD     I2C1_EV_IRQHandler        ; I2C1 Event
                DCD     I2C1_ER_IRQHandler        ; I2C1 Error
                DCD     I2C2_EV_IRQHandler        ; I2C2 Event
                DCD     I2C2_ER_IRQHandler        ; I2C2 Error
                DCD     SPI1_IRQHandler           ; SPI1
                DCD     SPI2_IRQHandler           ; SPI2
                DCD     USART1_IRQHandler         ; USART1
                DCD     USART2_IRQHandler         ; USART2
                DCD     USART3_IRQHandler         ; USART3
                DCD     EXTI15_10_IRQHandler      ; EXTI Line 15..10
                DCD     RTCAlarm_IRQHandler       ; RTC Alarm through EXTI Line
                DCD     USBWakeUp_IRQHandler      ; USB Wakeup from suspend


                AREA    |.text|, CO
DE, READONLY


; Reset Handler

以上是中断向量表,我用的是ADC的中断"DCD     ADC_IRQHandler            ; ADC",这里ADC_IRQHandler是一个中断处理函数的入口地址,名字可以随便起,比如我们可以把它改成My_ADC_IRQHandler。

接着往下看:

Reset_Handler   PROC
                EXPORT  Reset_Handler             [WEAK]
                IMP
ORT  __main
                LDR     R0, =__main
                BX      R0
                ENDP


; Dummy Exception Handlers (infinite loops which can be modified)               

NMI_Handler     PROC
                EXPORT  NMI_Handler               [WEAK]
                B       .
                ENDP
HardFault_Handler
                PROC
                EXPORT  HardFault_Handler         [WEAK]
                B       .
                ENDP
MemManage_Handler
                PROC
                EXPORT  MemManage_Handler         [WEAK]
                B       .
                ENDP
BusFault_Handler
                PROC
                EXPORT  BusFault_Handler          [WEAK]
                B       .
                ENDP
UsageFault_Handler
                PROC
                EXPORT  UsageFault_Handler        [WEAK]
                B       .
                ENDP
SVC_Handler     PROC
                EXPORT  SVC_Handler               [WEAK]
                B       .
                ENDP
DebugMon_Handler
                PROC
                EXPORT  DebugMon_Handler          [WEAK]
                B       .
                ENDP
PendSV_Handler  PROC
                EXPORT  PendSV_Handler            [WEAK]
                B       .
                ENDP
SysTick_Handler PROC
                EXPORT  SysTick_Handler           [WEAK]
                B       .
                ENDP

这些都是缺省的中断处理函数,只有Reset_Handler是比较完整的。

我们要模仿着上面的格式给自己写一段代码,使程序在发生中断后,能够转到相应的我们写的中断处理函数执行:

ADC_IRQHandler PROC        
    IMP
ORT  ADC_NATIVE_IRQHandler
    B  ADC_NATIVE_IRQHandler
    ENDP

其中"ADC_IRQHandler"就是在中断向量表里取的名字,如果你在中断向量表里使用了My_ADC_IRQHandler,那么这里你就要写成My_ADC_IRQHandler了;"ADC_NATIVE_IRQHandler"是你自己写的中断处理函数的函数名。

下面再改一点点就可以了:

Default_Handler PROC

                EXPORT  WWDG_IRQHandler           [WEAK]
                EXPORT  PVD_IRQHandler            [WEAK]
                EXPORT  TAMPER_IRQHandler         [WEAK]
                EXPORT  RTC_IRQHandler            [WEAK]
                EXPORT  FLASH_IRQHandler          [WEAK]
                EXPORT  RCC_IRQHandler            [WEAK]
                EXPORT  EXTI0_IRQHandler          [WEAK]
                EXPORT  EXTI1_IRQHandler          [WEAK]
                EXPORT  EXTI2_IRQHandler          [WEAK]
                EXPORT  EXTI3_IRQHandler          [WEAK]
                EXPORT  EXTI4_IRQHandler          [WEAK]
                EXPORT  DMAChannel1_IRQHandler    [WEAK]
                EXPORT  DMAChannel2_IRQHandler    [WEAK]
                EXPORT  DMAChannel3_IRQHandler    [WEAK]
                EXPORT  DMAChannel4_IRQHandler    [WEAK]
                EXPORT  DMAChannel5_IRQHandler    [WEAK]
                EXPORT  DMAChannel6_IRQHandler    [WEAK]
                EXPORT  DMAChannel7_IRQHandler    [WEAK]
                EXPORT  ADC_IRQHandler            [WEAK]
                EXPORT  USB_HP_CAN_TX_IRQHandler  [WEAK]
                EXPORT  USB_LP_CAN_RX0_IRQHandler [WEAK]
                EXPORT  CAN_RX1_IRQHandler        [WEAK]
                EXPORT  CAN_SCE_IRQHandler        [WEAK]
                EXPORT  EXTI9_5_IRQHandler        [WEAK]
                EXPORT  TIM1_BRK_IRQHandler       [WEAK]
                EXPORT  TIM1_UP_IRQHandler        [WEAK]
                EXPORT  TIM1_TRG_COM_IRQHandler   [WEAK]
                EXPORT  TIM1_CC_IRQHandler        [WEAK]
                EXPORT  TIM2_IRQHandler           [WEAK]
                EXPORT  TIM3_IRQHandler           [WEAK]
                EXPORT  TIM4_IRQHandler           [WEAK]
                EXPORT  I2C1_EV_IRQHandler        [WEAK]
                EXPORT  I2C1_ER_IRQHandler        [WEAK]
                EXPORT  I2C2_EV_IRQHandler        [WEAK]
                EXPORT  I2C2_ER_IRQHandler        [WEAK]
                EXPORT  SPI1_IRQHandler           [WEAK]
                EXPORT  SPI2_IRQHandler           [WEAK]
                EXPORT  USART1_IRQHandler         [WEAK]
                EXPORT  USART2_IRQHandler         [WEAK]
                EXPORT  USART3_IRQHandler         [WEAK]
                EXPORT  EXTI15_10_IRQHandler      [WEAK]
                EXPORT  RTCAlarm_IRQHandler       [WEAK]
                EXPORT  USBWakeUp_IRQHandler      [WEAK]
WWDG_IRQHandler
PVD_IRQHandler
TAMPER_IRQHandler
RTC_IRQHandler
FLASH_IRQHandler
RCC_IRQHandler
EXTI0_IRQHandler
EXTI1_IRQHandler
EXTI2_IRQHandler
EXTI3_IRQHandler
EXTI4_IRQHandler
DMAChannel1_IRQHandler
DMAChannel2_IRQHandler
DMAChannel3_IRQHandler
DMAChannel4_IRQHandler
DMAChannel5_IRQHandler
DMAChannel6_IRQHandler
DMAChannel7_IRQHandler
ADC_IRQHandler
USB_HP_CAN_TX_IRQHandler
USB_LP_CAN_RX0_IRQHandler
CAN_RX1_IRQHandler
CAN_SCE_IRQHandler
EXTI9_5_IRQHandler
TIM1_BRK_IRQHandler
TIM1_UP_IRQHandler
TIM1_TRG_COM_IRQHandler
TIM1_CC_IRQHandler
TIM2_IRQHandler
TIM3_IRQHandler
TIM4_IRQHandler
I2C1_EV_IRQHandler
I2C1_ER_IRQHandler
I2C2_EV_IRQHandler
I2C2_ER_IRQHandler
SPI1_IRQHandler
SPI2_IRQHandler
USART1_IRQHandler
USART2_IRQHandler
USART3_IRQHandler
EXTI15_10_IRQHandler
RTCAlarm_IRQHandler
USBWakeUp_IRQHandler


                 B       .

                ENDP

这是缺省的中断处理函数入口地址,因为我们都自己实现了一个ADC的中断处理函数,所以就把EXPORT  "ADC_IRQHandler            [WEAK]"和"ADC_IRQHandler"都注释掉,注释的方法是在每一句的前面加一个分号:";ADC_IRQHandler            [WEAK]"和";ADC_IRQHandler",然后你再在随便一个文件里实现那个中断处理函数就行了,比如我用的是"ADC_NATIVE_IRQHandler",所以我就在随便的一个文件里写:

//
#define SR_EOC 0x00000002
#define SR_AWD 0x00000001
void ADC_NATIVE_IRQHandler(void){

u16 value_adc;
 if(ADC_NATIVE->SR&SR_EOC){//EOC
  value_adc=ADC_NATIVE->DR&0x0000FFFF;
  ADC_NATIVE->SR&=(~SR_EOC);
 }
 if(ADC_NATIVE->SR&SR_AWD){//AWD
  ADC_NATIVE->SR&=(~SR_AWD);
 } 
 }
}

最后一件事是要指定NVIC中断向量表的地址,同时在本例中要打开ADC中断通道:

/*******************************************************************************
* Function Name  : NVIC_Configuration
* Description    : Configures NVIC and Vector Table base location.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;

#ifdef  VECT_TAB_RAM 
  /* Set the Vector Table base location at 0x20000000 */
  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else  /* VECT_TAB_FLASH  */
  /* Set the Vector Table base location at 0x08000000 */
  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);  
#endif

  /* Configure and enable ADC interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQChannel;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

运行上面的函数,其中" ADC1_2_IRQChannel"是本例中的ADC中断通道号," ADC1_2_IRQChannel"是在"stm32f10x_nvic.h"里定义的宏,函数"NVIC_Init(&NVIC_InitStructure);"是在STM32F10xR.lib或STM32F10xD.lib里定义的(R代表Release,D代表Debug)。

更正一下,确切的说这种方法是一种间接添加的方法,因为例子中我使用的ADC_NATIVE_IRQHandler不是中断处理函数,它只是在中断处理函数中被调用了而已。真正的中断处理函数是ADC_IRQHandler(当然你也可以把它改成My_ADC_IRQHandler)。

行了。

cpu用什么方法在向量表中寻找中断向量? 为什么处理器采用中断运行机制?并且设置中断向量表? 8086中断类型号为40H的中断服务程序入口地址存放在中断向量表的起始地址是: [汇编程序]输出一份中断向量表到屏幕或文件 keil 在多个文件中查找 某中断源的中断类型码为2AH,该中断源的中断服务入口地址为2000H:FF23H,试画出中断向量表图 将中断类型码乘4,指向中断向量表中的中断处理子程序的入口地址,为什么要乘以4? 怎样在KEIL环境中,在汇编语言里添加C的子函数啊!!! 在TC3中中断怎么用? 缴纳的个人所得税,在现金流量表中怎么反映? 摊销在现金流量表中属于那个项目的? 固定资产折旧在现金流量表中属于那个项目的? 请问购进低值易耗品在现金流量表中如何列示? Keil 不能给SBUF附值 如何在gb2312页面中通过response.redirect向utf-8传中文参数? 在8086的汇编中,int 21 属于软件中断还是硬件中断,为什么? 在VC中如何调用及更改中断优先级? 为什么我的电脑在使用过程中易中断 [JSP]如何在For中,中断While的循环? P2P TV记录器经常在记录中中断 在中断处理函数中为什么要加static关键字? 如何通过程序向数据库中追加信息?因为我在进行软件测试,信息量太大了,通过手工填写不可能填完 怎么通过数据线向手机中下载MP3 怎么通过数据线向手机中传游戏