这里针对传统 STC32 / STC8 系列,无用户系统区的单片机(但是可以操作全部FLASH空间)
提供一种BOOT和APP之间共享中断的方案,无需重定向中断向量表
且支持多个APP同时使用中断
ota程序升级.zip
(101.24 KB, 下载次数: 8)
BOOT程序:
#include <AI8H.H>
int cnt = 0;
int ota_cnt = 0;
void Timer0_Init(void);
unsigned int xdata ISR_Offset _at_ 0x400; //偏移地址,定义在1k的xdata处
#define LDR_SIZE 0x1800
void All_Isr(void)
{
cnt++;
}
void Timer0_Isr(void) interrupt 1
{
((void (code *)())(ISR_Offset))();
}
void main(void)
{
P_SW2 |= 0x80;
ISR_Offset = (unsigned int)All_Isr;//给定中断地址
P4M0 = 0x00; P4M1 = 0x00;
P6M0 = 0x00; P6M1 = 0x00;
Timer0_Init();
EA = 1;
while(1)
{
if(cnt>=200)
{
cnt = 0;
P40 = ~P40;
P60 = ~P60;
ota_cnt++;
if(ota_cnt>10)
{
ota_cnt = 0;
EA = 0;//跳转之前记得给中断关了,不然乱蹦跶
((void (code *)())(LDR_SIZE))();
}
}
}
}
void Timer0_Init(void) //1毫秒@24.000MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x40; //设置定时初始值
TH0 = 0xA2; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0中断
} 复制代码 app程序:
#include <AI8H.H>
int cnt = 0;
void Timer0_Init(void);
unsigned int xdata ISR_Offset _at_ 0x400; //偏移地址,定义在1k的xdata处
void All_Isr(void)
{
cnt++;
}
void main(void)
{
P_SW2 |= 0x80;
ISR_Offset = (unsigned int)All_Isr;//给定中断地址
P4M0 = 0x00; P4M1 = 0x00;
P6M0 = 0x00; P6M1 = 0x00;
Timer0_Init();
EA = 1;
while(1)
{
if(cnt>=50)
{
cnt = 0;
P40 = ~P40;
P60 = ~P60;
}
}
}
void Timer0_Init(void) //1毫秒@24.000MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x40; //设置定时初始值
TH0 = 0xA2; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0中断
} 复制代码 程序主要使用xdata不断电情况下不变的特性,通过一个变量来存储不同的中断函数地址
然后在app内,不使用interrupt定义,而是使用普通函数写完成中断程序后,将此函数的地址赋值给这个共同约定好的变量,使其可以在BOOT的中断函数中被调用一次,以此达到可以不用重定向中断向量,多个APP可用中断函数的作用
APP程序的HEX文件处理方法可以参考: 如何把自己的用户区ISP固件和自己的用户区AP固件进行合并供工厂量产使用 - ISP下载/做自己的ISP 国芯人工智能技术交流网站 - AI32位8051交流社区