钻石火彩评级:在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|, CODE, READONLY
; Reset Handler
以上是中断向量表,我用的是ADC的中断"DCD ADC_IRQHandler ; ADC",这里ADC_IRQHandler是一个中断处理函数的入口地址,名字可以随便起,比如我们可以把它改成My_ADC_IRQHandler。
接着往下看:
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT __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
IMPORT 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)。
行了。