使用 SDCC 编译器中断 STM8s 问题
Interrupt STM8s issue with SDCC compiler
我想在 SMT8S003K3 (STM8SVL-DISCOVERY) 上使用中断,但当我在我的 main() 所在的其他文件上使用中断时,不知何故无法识别它。
我做了两个测试:
- 首先我将此 code 修改为标准外设库:
uint8_t main(){
CLK->CKDIVR=0;
TIM1->PSCRH=0;
TIM1->PSCRL=0x80;
TIM1->CR1=1;
TIM1->IER=1;
GPIOD->DDR = 1;
GPIOD->CR1 = 1;
enableInterrupts();
while(1){
}
}
void TIM1_overflow_Handler() __interrupt(11)
{
TIM1->SR1 &= ~1; //reset interrupt
GPIOD->ODR ^= 1; //toggle LED
}
而且有效...
现在为了使用 UnitTests,我把这个函数放到了另一个文件中:main_internal(只是一个简单的例子):
#ifdef STM8S003
#include "stm8s.h"
#endif
#include "main_internal.h"
void main_internal() {
CLK->CKDIVR=0;
TIM1->PSCRH=0;
TIM1->PSCRL=0x80;
TIM1->CR1=1;
TIM1->IER=1;
GPIOD->DDR = 1;
GPIOD->CR1 = 1;
enableInterrupts();
while(1){
}
}
void TIM1_overflow_Handler() __interrupt(11)
{
TIM1->SR1 &= ~1; //reset interrupt
GPIOD->ODR ^= 1; //toggle LED
}
主要功能:
#include "main_internal.h"
int main(){
main_internal();
return 0;
}
它什么都不做……嗯,它在 STM8S003 的深层内存中流动(正如我在调试器中看到的那样)。这是链接问题吗?
这是我的 Makefile:
ST_TARGET = main
INCLUDEDIR = Libraries/inc include
ST_LIBSRCDIR = Libraries/src
#ST_LIBSRC = $(ST_LIBSRCDIR)/stm8s_adc1.c $(ST_LIBSRCDIR)/stm8s_awu.c
#ST_LIBSRC += $(ST_LIBSRCDIR)/stm8s_beep.c $(ST_LIBSRCDIR)/stm8s_clk.c
#ST_LIBSRC += $(ST_LIBSRCDIR)/stm8s_exti.c $(ST_LIBSRCDIR)/stm8s_flash.c
#ST_LIBSRC += $(ST_LIBSRCDIR)/stm8s_gpio.c $(ST_LIBSRCDIR)/stm8s_i2c.c
#ST_LIBSRC += $(ST_LIBSRCDIR)/stm8s_itc.c $(ST_LIBSRCDIR)/stm8s_iwdg.c
#ST_LIBSRC += $(ST_LIBSRCDIR)/stm8s_rst.c $(ST_LIBSRCDIR)/stm8s_spi.c
#ST_LIBSRC += $(ST_LIBSRCDIR)/stm8s_tim1.c $(ST_LIBSRCDIR)/stm8s_wwdg.c
SRC_DIR = src
SRC_ALL = $(shell find -L $(SRC_DIR) -name '*.c')
SRCS = $(filter-out $(SRC_DIR)/$(ST_TARGET).c,$(SRC_ALL))
ST_OBJS = $(ST_LIBSRC:.c=.rel)
ST_LIB_FILES := $(addprefix $(ST_BUILD_DIR)/,$(notdir $(ST_OBJS)))
LIBD_FILES := $(addprefix $(ST_DEBUG_DIR)/,$(notdir $(ST_OBJS)))
PR_ST_OBJS = $(SRCS:.c=.rel)
ST_SRC_FILES := $(addprefix $(ST_BUILD_DIR)/,$(notdir $(PR_ST_OBJS)))
SRCD_FILES := $(addprefix $(ST_DEBUG_DIR)/,$(notdir $(PR_ST_OBJS)))
ST_OBJS += $(PR_ST_OBJS)
STD_OBJS= $(ST_OBJS)
MCU = STM8S003
ST_COMPILER = __SDCC__
DEFINES = -D$(ST_COMPILER) -D$(MCU) -DUSE_STDPERIPH_DRIVER
ST_CFLAGS = -mstm8 $(DEFINES)
ST_LDFLAGS = $(addprefix -I ,$(INCLUDEDIR))
ST_DEBUG_FLAGS = --out-fmt-elf --all-callee-saves --debug --stack-auto --fverbose-asm --float-reent --no-peep
IHX = $(ST_BUILD_DIR)/$(ST_TARGET).ihx
ELF = $(ST_DEBUG_DIR)/$(ST_TARGET).elf
$(info $$ srcfiles is [${ST_OBJS}])
$(info $$ srcfiles is [${LIBD_FILES}])
ifdef st-debug
ST_OUT_DIR=$(ST_DEBUG_DIR)
else
ST_OUT_DIR=$(ST_BUILD_DIR)
endif
################### BUILD PROCESS ###################
.PHONY: all st-build st-clean st-flash st-debug st-wipe
#all: clean st-build
st: st-clean st-build st-flash
st-debug: $(STD_OBJS) $(ELF)# ST_CFLAGS+=$(ST_DEBUG_FLAGS)
st-debug: ST_CFLAGS+=$(ST_DEBUG_FLAGS)
st-debug: ST_OUT_DIR=$(ST_DEBUG_DIR)
$(STD_OBJS):
$(ELF): $(SRC_DIR)/$(ST_TARGET).c
@echo $(ST_OUT_DIR)
#ST_CFLAGS += $(ST_DEBUG_FLAGS)
$(ST_CC) $(ST_CFLAGS) $(ST_LDFLAGS) -o $(ST_OUT_DIR)/ $< $(SRCD_FILES) $(LIBD_FILES)
$(SIZE) $@
$(SIZE) $@ >> $(MEMORY_USAGE_DIR)/$(MEMORY_USAGE)
@echo Success!!!!\n\n
st-build: $(ST_OBJS) $(IHX)
$(ST_OBJS):
$(IHX): $(SRC_DIR)/$(ST_TARGET).c $(SRCS:.c)
$(ST_CC) $(ST_CFLAGS) $(ST_LDFLAGS) -o $(ST_OUT_DIR)/ $< $(ST_SRC_FILES) $(ST_LIB_FILES)
$(SIZE) $@
$(SIZE) $@ >> $(MEMORY_USAGE_DIR)/$(MEMORY_USAGE)
@echo Success!!!!\n\n
这将是没有标准外设库的代码:
#include <stdint.h>
#define CLK_DIVR (*(volatile uint8_t *)0x50C6)
#define TIM1_CR1 (*(volatile uint8_t *)0x5250)
#define TIM1_IER (*(volatile uint8_t *)0x5254)
#define TIM1_SR1 (*(volatile uint8_t *)0x5255)
#define TIM1_CNTRH (*(volatile uint8_t *)0x525E)
#define TIM1_CNTRL (*(volatile uint8_t *)0x525F)
#define TIM1_PSCRH (*(volatile uint8_t *)0x5260)
#define TIM1_PSCRL (*(volatile uint8_t *)0x5261)
#define PD_ODR (*(volatile uint8_t *)0x500f)
#define PD_DDR (*(volatile uint8_t *)0x5011)
#define PD_CR1 (*(volatile uint8_t *)0x5012)
void main(void)
{
CLK_DIVR = 0x00; // Set the frequency to 16 MHz
TIM1_PSCRH = 0x00; // Configure timer
TIM1_PSCRL = 0x80;
TIM1_CR1 = 0x01; //Enable timer
TIM1_IER = 0x01; //Enable interrupt - update event
PD_DDR = 1;
PD_CR1 = 1;
__asm__ ("rim");
while(1){
}
}
void TIM1_overflow_Handler() __interrupt(11)
{
TIM1_SR1 &= ~1; //reset interrupt
PD_ODR ^= 1; //toggle LED
}
这里我有两个版本的gdb的区别:
15c15
< 00008034: int 0x0080d7 ;0x80d7 <TIM1_overflow_Handler>
---
> 00008034: int 0x000000
44c44
< 00008098: ld A,(0x80fd,X) ;0x80fd <TIM1_overflow_Handler+38>
---
> 00008098: ld A,(0x8114,X) ;0x8114 <TIM1_overflow_Handler+38>
54c54
< 27 CLK_DIVR = 0x00; // Set the frequency to 16 MHz
---
> 8 main_internal();
56,163c56,136
< 000080b1: neg (0x50,SP) ;0x50
< 000080b3: ld A,0x3500 ;0x3500
< 29 TIM1_PSCRH = 0x00; // Configure timer
< 000080b4: mov 0x0052,#0x60 ;0x60
< 30 TIM1_PSCRL = 0x80;
< 000080b8: mov 0x8052,#0x61 ;0x61
< 32 TIM1_CR1 = 0x01; //Enable timer
< 000080bc: mov 0x0152,#0x50 ;0x50
< 33 TIM1_IER = 0x01; //Enable interrupt - update event
< 000080c0: mov 0x0152,#0x54 ;0x54
< 35 PD_DDR = 1;
< 000080c4: mov 0x0150,#0x11 ;0x11
< 36 PD_CR1 = 1;
< 000080c8: mov 0x0150,#0x12 ;0x12
< 37 __asm__ ("rim");
< 000080cc: rim
< 39 while(1){
< 000080cd: jp 0x80cd ;0x80cd <main+41>
< 41 }
< 000080d0: pop 0x0001 ;0x1
< 000080d3: pop 0x0002 ;0x2
< 000080d6: ret
< 43 void TIM1_overflow_Handler() __interrupt(11)
< TIM1_overflow_Handler:
< 000080d7: push 0x0002 ;0x2
< 000080da: push 0x0001 ;0x1
< 000080dd: ldw Y,SP
< 000080df: ldw 0x0001,Y ;0x1
< 45 TIM1_SR1 &= ~1; //reset interrupt
< 000080e3: ldw X,#0x5255 ;0x5255
< 000080e6: ld A,(X)
< 000080e7: and A,#0xfe ;0xfe
< 000080e9: ldw X,#0x5255 ;0x5255
< 000080ec: ld (X),A
< 46 PD_ODR ^= 1; //toggle LED
< 000080ed: ldw X,#0x500f ;0x500f
< 000080f0: ld A,(X)
< 000080f1: xor A,#0x01 ;0x1
< 000080f3: ldw X,#0x500f ;0x500f
< 000080f6: ld (X),A
< 47 }
< 000080f7: pop 0x0001 ;0x1
< 000080fa: pop 0x0002 ;0x2
< 000080fd: iret
< 000080fe: and A,#0xfe ;0xfe
< 00008100: ldw X,#0x5255 ;0x5255
< 00008103: ld (X),A
< 00008104: ldw X,#0x500f ;0x500f
< 00008107: ld A,(X)
< 00008108: xor A,#0x01 ;0x1
< 0000810a: ldw X,#0x500f ;0x500f
< 0000810d: ld (X),A
< 0000810e: pop 0x0001 ;0x1
< 00008111: pop 0x0002 ;0x2
< 00008114: iret
< 00008115: ld (X),A
< 00008116: ldw X,#0x5230 ;0x5230
< 00008119: ld A,(X)
< 0000811a: and A,#0x80 ;0x80
< 0000811c: cp A,#0x80 ;0x80
< 0000811e: jrne 0x8116 ;0x8116
< 00008120: ret
< 00008121: jra 0x8116 ;0x8116
< 00008123: ret
< 00008124: ldw X,#0x5235 ;0x5235
< 00008127: ld A,(X)
< 00008128: or A,#0x20 ;0x20
< 0000812a: ld (X),A
< 0000812b: ret
< 0000812c: ldw X,#0x5235 ;0x5235
< 0000812f: ld A,(X)
< 00008130: or A,#0x20 ;0x20
< 00008132: ld (X),A
< 00008133: ldw X,#0x5230 ;0x5230
< 00008136: ld A,(X)
< 00008137: and A,#0xd0 ;0xd0
< 00008139: ld (X),A
< 0000813a: ldw X,#0x5231 ;0x5231
< 0000813d: ld A,(X)
< 0000813e: ret
< 0000813f: sub SP,#0x08 ;0x8
< 00008141: mov 0x0050,#0xc6 ;0xc6
< 00008145: mov 0x0052,#0x60 ;0x60
< 00008149: mov 0x8052,#0x61 ;0x61
< 0000814d: mov 0x0152,#0x50 ;0x50
< 00008151: mov 0x0152,#0x54 ;0x54
< 00008155: mov 0x0150,#0x11 ;0x11
< 00008159: mov 0x0150,#0x12 ;0x12
< 0000815d: rim
< 0000815e: ldw X,#0x525e ;0x525e
< 00008161: ld A,(X)
< 00008162: ldw X,#0x5231 ;0x5231
< 00008165: ld (X),A
< 00008166: ldw X,#0x5230 ;0x5230
< 00008169: ld A,(X)
< 0000816a: and A,#0x80 ;0x80
< 0000816c: cp A,#0x80 ;0x80
< 0000816e: jrne 0x8166 ;0x8166
< 00008170: ldw X,#0x1388 ;0x1388
< 00008173: clr (0x02,SP) ;0x2
< 00008175: clr (0x01,SP) ;0x1
< 00008177: subw X,#0x0001 ;0x1
< 0000817a: ldw (0x07,SP),X ;0x7
< 0000817c: ld A,(0x02,SP) ;0x2
< 0000817e: sbc A,#0x00
< 00008180: ld (0x06,SP),A ;0x6
< 00008182: ld A,(0x01,SP) ;0x1
< 00008184: sbc A,#0x00
---
> 000080b1: iret
> ......... add A,0x5f ;0x5f
> 9 return 0;
> 000080b3: clrw X
> 10 }
> 000080b4: pop 0x0001 ;0x1
> 000080b7: pop 0x0002 ;0x2
> 000080ba: ret
> main_internal:
> 000080bb: push 0x0002 ;0x2
> 000080be: push 0x0001 ;0x1
> 000080c1: ldw Y,SP
> 000080c3: ldw 0x0001,Y ;0x1
> ......... ...
> 00ffffff: neg (0xa5,SP) ;0xa5
> 01000001: cpl (0xf9,SP) ;0xf9
> 01000003: neg (0xf7,SP) ;0xf7
> 01000005: xor A,0x6f ;0x6f
> 01000007: cpw X,#0xc9ac ;0xc9ac
> 0100000a: scf
> 0100000b: int 0x1ee2a7 ;0x1ee2a7
> 0100000f: sll 0x9b ;0x9b
> 01000011: clr (0x99,SP) ;0x99
> 01000013: jrne 0xffffef ;0xffffef
> 01000015:
> 01000016: addw SP,#0x11 ;0x11
> 01000018: or A,(0xaa,SP) ;0xaa
> 0100001a: sim
> 0100001b: mul X,A
> 0100001c: xor A,(0x3d,SP) ;0x3d
> 0100001e: sub A,0x63 ;0x63
> 01000020: adc A,0x53 ;0x53
> 01000022: ld (0xf8,SP),A ;0xf8
> 01000024: push 0xd95c ;0xd95c
> 01000027: pop A
> 01000028: sbc A,(0x53,SP) ;0x53
> 0100002a: cp A,(0x3e,SP) ;0x3e
> 0100002c: cpl 0x13 ;0x13
> 0100002e: sra (0xc0,X) ;0xc0
> 01000030: call (0xa2c9,X) ;0xa2c9
> 01000033: ld A,XH
> 01000034: tnzw X
> 01000035: subw X,#0x59cf ;0x59cf
> 01000038: ld (0x22,SP),A ;0x22
> 0100003a: decw X
> 0100003b: cpl (0xe9,X) ;0xe9
> 0100003d: and A,(0x7775,X) ;0x7775
> 01000040: sub A,(0x7e1c,X) ;0x7e1c
> 01000043: xor A,(X)
> 01000044: clrw X
> 01000045: swap 0xd5 ;0xd5
> 01000047: rlwa X,A
> 01000048: jreq 0x100006b ;0x100006b
> 0100004a: inc 0x22 ;0x22
> 0100004c:
> 0100004d: sra 0xdf ;0xdf
> 0100004f: cpw X,#0xb73f ;0xb73f
> 01000052: ld (0x0566,X),A ;0x566
> 01000055: sbc A,#0x4c ;0x4c
> 01000057: sll (X)
> 01000058: add A,0x40 ;0x40
> 0100005a: adc A,#0x05 ;0x5
> 0100005c: ld (0xc2,SP),A ;0xc2
> 0100005e: ld XL,A
> 0100005f: incw X
> 01000060: ldw (0xc8fe,X),Y ;0xc8fe
> 01000063: call 0x27e5 ;0x27e5
> 01000066: ldw X,(0xd0,X) ;0xd0
> 01000068: cpw X,0xc159 ;0xc159
> 0100006b: mov 0xc5,0xe8 ;0xe8
> 0100006e: cp A,(X)
> 0100006f: bcp A,(0xcb,SP) ;0xcb
> 01000071: cpw Y,(X)
> 01000072: xor A,(X)
> 01000073: pop CC
> 01000074: swap (0x1b,SP) ;0x1b
> 01000076: ldw X,#0x44cc ;0x44cc
> 01000079: div X,A
> 0100007a: rlc A
> 0100007b: sbc A,0xa8 ;0xa8
> 0100007d: inc (0x9b,X) ;0x9b
令人惊讶的是:
00008034: int 0x0080d7 ;0x80d7
在 main_internal.
的第二个版本中缺失
如有任何帮助,我们将不胜感激
捂脸
我没有在 main_internal.h 文件中包含中断处理程序:
void TIM1_overflow_Handler() __interrupt(11);
在 SDCC Compiler User Guide 第 40 页:
If you have multiple source files in your
project, interrupt service routines can be present in any of them, but
a prototype of the isr MUST be present or included in the file that
contains the function main.
所以请务必始终让您的 isr 对 main 函数可见。
我想在 SMT8S003K3 (STM8SVL-DISCOVERY) 上使用中断,但当我在我的 main() 所在的其他文件上使用中断时,不知何故无法识别它。
我做了两个测试: - 首先我将此 code 修改为标准外设库:
uint8_t main(){
CLK->CKDIVR=0;
TIM1->PSCRH=0;
TIM1->PSCRL=0x80;
TIM1->CR1=1;
TIM1->IER=1;
GPIOD->DDR = 1;
GPIOD->CR1 = 1;
enableInterrupts();
while(1){
}
}
void TIM1_overflow_Handler() __interrupt(11)
{
TIM1->SR1 &= ~1; //reset interrupt
GPIOD->ODR ^= 1; //toggle LED
}
而且有效...
现在为了使用 UnitTests,我把这个函数放到了另一个文件中:main_internal(只是一个简单的例子):
#ifdef STM8S003
#include "stm8s.h"
#endif
#include "main_internal.h"
void main_internal() {
CLK->CKDIVR=0;
TIM1->PSCRH=0;
TIM1->PSCRL=0x80;
TIM1->CR1=1;
TIM1->IER=1;
GPIOD->DDR = 1;
GPIOD->CR1 = 1;
enableInterrupts();
while(1){
}
}
void TIM1_overflow_Handler() __interrupt(11)
{
TIM1->SR1 &= ~1; //reset interrupt
GPIOD->ODR ^= 1; //toggle LED
}
主要功能:
#include "main_internal.h"
int main(){
main_internal();
return 0;
}
它什么都不做……嗯,它在 STM8S003 的深层内存中流动(正如我在调试器中看到的那样)。这是链接问题吗?
这是我的 Makefile:
ST_TARGET = main
INCLUDEDIR = Libraries/inc include
ST_LIBSRCDIR = Libraries/src
#ST_LIBSRC = $(ST_LIBSRCDIR)/stm8s_adc1.c $(ST_LIBSRCDIR)/stm8s_awu.c
#ST_LIBSRC += $(ST_LIBSRCDIR)/stm8s_beep.c $(ST_LIBSRCDIR)/stm8s_clk.c
#ST_LIBSRC += $(ST_LIBSRCDIR)/stm8s_exti.c $(ST_LIBSRCDIR)/stm8s_flash.c
#ST_LIBSRC += $(ST_LIBSRCDIR)/stm8s_gpio.c $(ST_LIBSRCDIR)/stm8s_i2c.c
#ST_LIBSRC += $(ST_LIBSRCDIR)/stm8s_itc.c $(ST_LIBSRCDIR)/stm8s_iwdg.c
#ST_LIBSRC += $(ST_LIBSRCDIR)/stm8s_rst.c $(ST_LIBSRCDIR)/stm8s_spi.c
#ST_LIBSRC += $(ST_LIBSRCDIR)/stm8s_tim1.c $(ST_LIBSRCDIR)/stm8s_wwdg.c
SRC_DIR = src
SRC_ALL = $(shell find -L $(SRC_DIR) -name '*.c')
SRCS = $(filter-out $(SRC_DIR)/$(ST_TARGET).c,$(SRC_ALL))
ST_OBJS = $(ST_LIBSRC:.c=.rel)
ST_LIB_FILES := $(addprefix $(ST_BUILD_DIR)/,$(notdir $(ST_OBJS)))
LIBD_FILES := $(addprefix $(ST_DEBUG_DIR)/,$(notdir $(ST_OBJS)))
PR_ST_OBJS = $(SRCS:.c=.rel)
ST_SRC_FILES := $(addprefix $(ST_BUILD_DIR)/,$(notdir $(PR_ST_OBJS)))
SRCD_FILES := $(addprefix $(ST_DEBUG_DIR)/,$(notdir $(PR_ST_OBJS)))
ST_OBJS += $(PR_ST_OBJS)
STD_OBJS= $(ST_OBJS)
MCU = STM8S003
ST_COMPILER = __SDCC__
DEFINES = -D$(ST_COMPILER) -D$(MCU) -DUSE_STDPERIPH_DRIVER
ST_CFLAGS = -mstm8 $(DEFINES)
ST_LDFLAGS = $(addprefix -I ,$(INCLUDEDIR))
ST_DEBUG_FLAGS = --out-fmt-elf --all-callee-saves --debug --stack-auto --fverbose-asm --float-reent --no-peep
IHX = $(ST_BUILD_DIR)/$(ST_TARGET).ihx
ELF = $(ST_DEBUG_DIR)/$(ST_TARGET).elf
$(info $$ srcfiles is [${ST_OBJS}])
$(info $$ srcfiles is [${LIBD_FILES}])
ifdef st-debug
ST_OUT_DIR=$(ST_DEBUG_DIR)
else
ST_OUT_DIR=$(ST_BUILD_DIR)
endif
################### BUILD PROCESS ###################
.PHONY: all st-build st-clean st-flash st-debug st-wipe
#all: clean st-build
st: st-clean st-build st-flash
st-debug: $(STD_OBJS) $(ELF)# ST_CFLAGS+=$(ST_DEBUG_FLAGS)
st-debug: ST_CFLAGS+=$(ST_DEBUG_FLAGS)
st-debug: ST_OUT_DIR=$(ST_DEBUG_DIR)
$(STD_OBJS):
$(ELF): $(SRC_DIR)/$(ST_TARGET).c
@echo $(ST_OUT_DIR)
#ST_CFLAGS += $(ST_DEBUG_FLAGS)
$(ST_CC) $(ST_CFLAGS) $(ST_LDFLAGS) -o $(ST_OUT_DIR)/ $< $(SRCD_FILES) $(LIBD_FILES)
$(SIZE) $@
$(SIZE) $@ >> $(MEMORY_USAGE_DIR)/$(MEMORY_USAGE)
@echo Success!!!!\n\n
st-build: $(ST_OBJS) $(IHX)
$(ST_OBJS):
$(IHX): $(SRC_DIR)/$(ST_TARGET).c $(SRCS:.c)
$(ST_CC) $(ST_CFLAGS) $(ST_LDFLAGS) -o $(ST_OUT_DIR)/ $< $(ST_SRC_FILES) $(ST_LIB_FILES)
$(SIZE) $@
$(SIZE) $@ >> $(MEMORY_USAGE_DIR)/$(MEMORY_USAGE)
@echo Success!!!!\n\n
这将是没有标准外设库的代码:
#include <stdint.h>
#define CLK_DIVR (*(volatile uint8_t *)0x50C6)
#define TIM1_CR1 (*(volatile uint8_t *)0x5250)
#define TIM1_IER (*(volatile uint8_t *)0x5254)
#define TIM1_SR1 (*(volatile uint8_t *)0x5255)
#define TIM1_CNTRH (*(volatile uint8_t *)0x525E)
#define TIM1_CNTRL (*(volatile uint8_t *)0x525F)
#define TIM1_PSCRH (*(volatile uint8_t *)0x5260)
#define TIM1_PSCRL (*(volatile uint8_t *)0x5261)
#define PD_ODR (*(volatile uint8_t *)0x500f)
#define PD_DDR (*(volatile uint8_t *)0x5011)
#define PD_CR1 (*(volatile uint8_t *)0x5012)
void main(void)
{
CLK_DIVR = 0x00; // Set the frequency to 16 MHz
TIM1_PSCRH = 0x00; // Configure timer
TIM1_PSCRL = 0x80;
TIM1_CR1 = 0x01; //Enable timer
TIM1_IER = 0x01; //Enable interrupt - update event
PD_DDR = 1;
PD_CR1 = 1;
__asm__ ("rim");
while(1){
}
}
void TIM1_overflow_Handler() __interrupt(11)
{
TIM1_SR1 &= ~1; //reset interrupt
PD_ODR ^= 1; //toggle LED
}
这里我有两个版本的gdb的区别:
15c15
< 00008034: int 0x0080d7 ;0x80d7 <TIM1_overflow_Handler>
---
> 00008034: int 0x000000
44c44
< 00008098: ld A,(0x80fd,X) ;0x80fd <TIM1_overflow_Handler+38>
---
> 00008098: ld A,(0x8114,X) ;0x8114 <TIM1_overflow_Handler+38>
54c54
< 27 CLK_DIVR = 0x00; // Set the frequency to 16 MHz
---
> 8 main_internal();
56,163c56,136
< 000080b1: neg (0x50,SP) ;0x50
< 000080b3: ld A,0x3500 ;0x3500
< 29 TIM1_PSCRH = 0x00; // Configure timer
< 000080b4: mov 0x0052,#0x60 ;0x60
< 30 TIM1_PSCRL = 0x80;
< 000080b8: mov 0x8052,#0x61 ;0x61
< 32 TIM1_CR1 = 0x01; //Enable timer
< 000080bc: mov 0x0152,#0x50 ;0x50
< 33 TIM1_IER = 0x01; //Enable interrupt - update event
< 000080c0: mov 0x0152,#0x54 ;0x54
< 35 PD_DDR = 1;
< 000080c4: mov 0x0150,#0x11 ;0x11
< 36 PD_CR1 = 1;
< 000080c8: mov 0x0150,#0x12 ;0x12
< 37 __asm__ ("rim");
< 000080cc: rim
< 39 while(1){
< 000080cd: jp 0x80cd ;0x80cd <main+41>
< 41 }
< 000080d0: pop 0x0001 ;0x1
< 000080d3: pop 0x0002 ;0x2
< 000080d6: ret
< 43 void TIM1_overflow_Handler() __interrupt(11)
< TIM1_overflow_Handler:
< 000080d7: push 0x0002 ;0x2
< 000080da: push 0x0001 ;0x1
< 000080dd: ldw Y,SP
< 000080df: ldw 0x0001,Y ;0x1
< 45 TIM1_SR1 &= ~1; //reset interrupt
< 000080e3: ldw X,#0x5255 ;0x5255
< 000080e6: ld A,(X)
< 000080e7: and A,#0xfe ;0xfe
< 000080e9: ldw X,#0x5255 ;0x5255
< 000080ec: ld (X),A
< 46 PD_ODR ^= 1; //toggle LED
< 000080ed: ldw X,#0x500f ;0x500f
< 000080f0: ld A,(X)
< 000080f1: xor A,#0x01 ;0x1
< 000080f3: ldw X,#0x500f ;0x500f
< 000080f6: ld (X),A
< 47 }
< 000080f7: pop 0x0001 ;0x1
< 000080fa: pop 0x0002 ;0x2
< 000080fd: iret
< 000080fe: and A,#0xfe ;0xfe
< 00008100: ldw X,#0x5255 ;0x5255
< 00008103: ld (X),A
< 00008104: ldw X,#0x500f ;0x500f
< 00008107: ld A,(X)
< 00008108: xor A,#0x01 ;0x1
< 0000810a: ldw X,#0x500f ;0x500f
< 0000810d: ld (X),A
< 0000810e: pop 0x0001 ;0x1
< 00008111: pop 0x0002 ;0x2
< 00008114: iret
< 00008115: ld (X),A
< 00008116: ldw X,#0x5230 ;0x5230
< 00008119: ld A,(X)
< 0000811a: and A,#0x80 ;0x80
< 0000811c: cp A,#0x80 ;0x80
< 0000811e: jrne 0x8116 ;0x8116
< 00008120: ret
< 00008121: jra 0x8116 ;0x8116
< 00008123: ret
< 00008124: ldw X,#0x5235 ;0x5235
< 00008127: ld A,(X)
< 00008128: or A,#0x20 ;0x20
< 0000812a: ld (X),A
< 0000812b: ret
< 0000812c: ldw X,#0x5235 ;0x5235
< 0000812f: ld A,(X)
< 00008130: or A,#0x20 ;0x20
< 00008132: ld (X),A
< 00008133: ldw X,#0x5230 ;0x5230
< 00008136: ld A,(X)
< 00008137: and A,#0xd0 ;0xd0
< 00008139: ld (X),A
< 0000813a: ldw X,#0x5231 ;0x5231
< 0000813d: ld A,(X)
< 0000813e: ret
< 0000813f: sub SP,#0x08 ;0x8
< 00008141: mov 0x0050,#0xc6 ;0xc6
< 00008145: mov 0x0052,#0x60 ;0x60
< 00008149: mov 0x8052,#0x61 ;0x61
< 0000814d: mov 0x0152,#0x50 ;0x50
< 00008151: mov 0x0152,#0x54 ;0x54
< 00008155: mov 0x0150,#0x11 ;0x11
< 00008159: mov 0x0150,#0x12 ;0x12
< 0000815d: rim
< 0000815e: ldw X,#0x525e ;0x525e
< 00008161: ld A,(X)
< 00008162: ldw X,#0x5231 ;0x5231
< 00008165: ld (X),A
< 00008166: ldw X,#0x5230 ;0x5230
< 00008169: ld A,(X)
< 0000816a: and A,#0x80 ;0x80
< 0000816c: cp A,#0x80 ;0x80
< 0000816e: jrne 0x8166 ;0x8166
< 00008170: ldw X,#0x1388 ;0x1388
< 00008173: clr (0x02,SP) ;0x2
< 00008175: clr (0x01,SP) ;0x1
< 00008177: subw X,#0x0001 ;0x1
< 0000817a: ldw (0x07,SP),X ;0x7
< 0000817c: ld A,(0x02,SP) ;0x2
< 0000817e: sbc A,#0x00
< 00008180: ld (0x06,SP),A ;0x6
< 00008182: ld A,(0x01,SP) ;0x1
< 00008184: sbc A,#0x00
---
> 000080b1: iret
> ......... add A,0x5f ;0x5f
> 9 return 0;
> 000080b3: clrw X
> 10 }
> 000080b4: pop 0x0001 ;0x1
> 000080b7: pop 0x0002 ;0x2
> 000080ba: ret
> main_internal:
> 000080bb: push 0x0002 ;0x2
> 000080be: push 0x0001 ;0x1
> 000080c1: ldw Y,SP
> 000080c3: ldw 0x0001,Y ;0x1
> ......... ...
> 00ffffff: neg (0xa5,SP) ;0xa5
> 01000001: cpl (0xf9,SP) ;0xf9
> 01000003: neg (0xf7,SP) ;0xf7
> 01000005: xor A,0x6f ;0x6f
> 01000007: cpw X,#0xc9ac ;0xc9ac
> 0100000a: scf
> 0100000b: int 0x1ee2a7 ;0x1ee2a7
> 0100000f: sll 0x9b ;0x9b
> 01000011: clr (0x99,SP) ;0x99
> 01000013: jrne 0xffffef ;0xffffef
> 01000015:
> 01000016: addw SP,#0x11 ;0x11
> 01000018: or A,(0xaa,SP) ;0xaa
> 0100001a: sim
> 0100001b: mul X,A
> 0100001c: xor A,(0x3d,SP) ;0x3d
> 0100001e: sub A,0x63 ;0x63
> 01000020: adc A,0x53 ;0x53
> 01000022: ld (0xf8,SP),A ;0xf8
> 01000024: push 0xd95c ;0xd95c
> 01000027: pop A
> 01000028: sbc A,(0x53,SP) ;0x53
> 0100002a: cp A,(0x3e,SP) ;0x3e
> 0100002c: cpl 0x13 ;0x13
> 0100002e: sra (0xc0,X) ;0xc0
> 01000030: call (0xa2c9,X) ;0xa2c9
> 01000033: ld A,XH
> 01000034: tnzw X
> 01000035: subw X,#0x59cf ;0x59cf
> 01000038: ld (0x22,SP),A ;0x22
> 0100003a: decw X
> 0100003b: cpl (0xe9,X) ;0xe9
> 0100003d: and A,(0x7775,X) ;0x7775
> 01000040: sub A,(0x7e1c,X) ;0x7e1c
> 01000043: xor A,(X)
> 01000044: clrw X
> 01000045: swap 0xd5 ;0xd5
> 01000047: rlwa X,A
> 01000048: jreq 0x100006b ;0x100006b
> 0100004a: inc 0x22 ;0x22
> 0100004c:
> 0100004d: sra 0xdf ;0xdf
> 0100004f: cpw X,#0xb73f ;0xb73f
> 01000052: ld (0x0566,X),A ;0x566
> 01000055: sbc A,#0x4c ;0x4c
> 01000057: sll (X)
> 01000058: add A,0x40 ;0x40
> 0100005a: adc A,#0x05 ;0x5
> 0100005c: ld (0xc2,SP),A ;0xc2
> 0100005e: ld XL,A
> 0100005f: incw X
> 01000060: ldw (0xc8fe,X),Y ;0xc8fe
> 01000063: call 0x27e5 ;0x27e5
> 01000066: ldw X,(0xd0,X) ;0xd0
> 01000068: cpw X,0xc159 ;0xc159
> 0100006b: mov 0xc5,0xe8 ;0xe8
> 0100006e: cp A,(X)
> 0100006f: bcp A,(0xcb,SP) ;0xcb
> 01000071: cpw Y,(X)
> 01000072: xor A,(X)
> 01000073: pop CC
> 01000074: swap (0x1b,SP) ;0x1b
> 01000076: ldw X,#0x44cc ;0x44cc
> 01000079: div X,A
> 0100007a: rlc A
> 0100007b: sbc A,0xa8 ;0xa8
> 0100007d: inc (0x9b,X) ;0x9b
令人惊讶的是: 00008034: int 0x0080d7 ;0x80d7 在 main_internal.
的第二个版本中缺失如有任何帮助,我们将不胜感激
捂脸
我没有在 main_internal.h 文件中包含中断处理程序:
void TIM1_overflow_Handler() __interrupt(11);
在 SDCC Compiler User Guide 第 40 页:
If you have multiple source files in your project, interrupt service routines can be present in any of them, but a prototype of the isr MUST be present or included in the file that contains the function main.
所以请务必始终让您的 isr 对 main 函数可见。