在sdcc中,中断处理函数使用关键字__interrupt标识,后面跟上中断号,8051中断号列表如下:
Interrupt # Description Vector Address 0 External 0 0x0003 1 Timer 0 0x000b 2 External 1 0x0013 3 Timer 1 0x001b 4 Serial 0x0023 5 Timer 2 (8052) 0x002b
虽然看上去很简单,但是在使用过程中还出现了一个小问题,由于我将程序分成了两个部分,main.c和timer.c,而在timer.c中的定时器中断处理函数timer0_isr始终是不能被执行,检查程序呢也未发现什么原因,通过查看sdcc中的源代码和上网查找timer部分代码,也未发现timer0初始化有任何问题,顿时就郁闷了。但是也发现两个一个不同之处,就是在main函数之前对中断处理函数做了一个声明,于是我就在我的程序中加上了这个声明,程序终于调用了中断处理函数,特此记录一下。完整的程序如下:
/* timer.c */
#include <at89x52.h>
#define OSC_FREQ 12000000UL
#define TIMER_MODE0 0x00
#define TIMER_MODE1 0x01
#define TIMER_MODE2 0x02
#define TIMER_MODE3 0x03
volatile unsigned int count = 0;
void timer0_isr(void) __interrupt 1
{
count++;
TH0 = (65536-1000*(OSC_FREQ/12000000)) >> 8;
TL0 = (65536-1000*(OSC_FREQ/12000000)) & 0x00FF;
}
void timer0_init(void)
{
TMOD &= 0xF0;
TMOD |= TIMER_MODE1; /* Timer 0 work on 16-bit timer mode */
TH0 = (65536-1000*(OSC_FREQ/12000000)) >> 8;
TL0 = (65536-1000*(OSC_FREQ/12000000)) & 0x00FF;
ET0 = 1; /* Enable timer 0 interrupt */
EA = 1;
TR0 = 1; /* Turn on timer 0 */
}
void delayms(unsigned int n)
{
while (count <= n);
count = 0;
}
/* timer.h */
#ifndef __TIMER_H
#define __TIMER_H
extern void timer0_init(void);
extern void delayms(unsigned int n);
#endif /* __TIMER_H */
/* main.c */
#include <at89x52.h>
#include "timer.h"
#define led1 P2_0
void timer0_isr(void) __interrupt 1;
void main(void)
{
timer0_init();
while (1) {
led1 = 0;
delayms(1000);
led1 = 1;
delayms(1000);
}
}
注:经验证,在Keil中未出现该问题。