8位单片机体系的直接软件构架(C51系列)
1.启动文件的编制
$ NOMOD51 ;Ax51宏汇编器控制命令:禁止预定义的8051
;自定义上电后需要初始化的储存区域
;间接寻址区IDATA起始地址固定为0
IDATALEN EQU 8OH ;指定需要初始化的IDATA区长度(以字节为单位)
XDATASTART EQU OH ;需要初始化的外部直接寻址区XDATA的起始地址
XDATALEN EQU OH ;指定需要初始化的XDATA区长度(以字节为单位)
PDATASTART EQU OH ;指定需要初始化的页寻址区PDATA起始地址
PDATALEN EQU OH ;指定需要初始化的PDATA区长度(以字节为单位)
;重入堆栈初始化,下面的EQU语句定义并初始化重入函数的堆栈指针
;SMALL模式下重入函数的堆栈空间
IBPSTACK EQU O ;SMALL模式下使用重入则设为1
EBPSTACKTOP EQU OFFH+1 ;设置堆栈顶为最高位置+1
;LARGE模式下重入函数的堆栈空间
XBPSTACK EQU O ;LARGE模式下使用重入则设为1
XBPSTACKTOP EQU OFFFFH+1 ;设置堆栈顶为最高位置+1
;COMPACT模式下重入函数的堆栈空间
PBPSTACK EQU O ;COMPACT模式下使用重入则设为1
PBPSTACKTOP EQU OFFFFH+1 ;设置堆栈顶为最高位置+1
;使用COMTACT模式是为64KB的XDATA RAM定义页
PPAGEENABLE EQU O ;使用PDATA也则设为1
PPAGE EQU O ;定义页号
PPAGE_SFR DATAOAOH ;SFR的最高地址字节
;标准SFR符号
ACC DATA OEOH
B DATA OFOH
SP DATA 81H
DPL DATA 82H
DPH DATA 83H
;******************************************************************************
NAME ? C_STARTUP
C_C51STARTUP SEGMENT CODE
STACK SEGMENT IDATA
RSEG ? STACK
DS 1
EXTRN CODE ( ? C_STAR ;外部代码(这个标号将代表用户程序的起始地址)
PUBLIC ? STARTUP ;给外部使用的符号
CSEG AT O ;在code段0地址处放以下代码(绝对地址定位)
?C_STARTUP:
LJMP STARTUP1
RSEG ? C_C51STARTUP
STARTUP1:
IF IDATALEN <> ;若长度大于1,则初始化IDATA
MOV RO,# IDATALEN-1
CLR A
IDATALOOP:
MOV @RO,A
DJNZ RO,IDATALOOP
ENDIF
IF XDATALEN <> 0 ;若长度大于1,则初始化XDATA
MOV DPTR,# XDATASTART
MOV R7; # LOW (XDATALEN)
IF (LOW(XDATALEN)) <> 0 ;预置初始化的外循环次数为R6
MOV R6;# (HIGH (XDATALEN ) )+1
ELSE MOV R6;# HIGH (XDATALEN )
ENDIF
CLR A
XDATALOOP:
MOVX @DPTA,A
INC DPTR
DJNZ R7,XDATALOOP
DJNZ R6,XDATALOOP
ENDIF
IF PPAGEENABLE <> 0
MOV PPAGE_SFR, # PPAGE
ENDIF
IF PDATALEN <> 0 ;若长度大于1,则初始化PDATA
MOV R0, # LOW (PDATASTART)
MOV R7, # LOW (PDATALEN)
CLR A
PDATALOOP:
MOVX @R0,A
INC R0
DJNZ R7,PDATALOOP
ENDIF
IF IBPSTACK <> 0 ;SMALL模式下使用重入函数是要设置的堆栈
EXTRN DATA ( ? C_IBP)
MOV ? C_IBP ,# LOW IBPSTACKTOP
ENDIF
IF XBPSTACK <> 0 ;COMPACT模式下使用重入函数是要设置的堆栈
EXTRN DATA ( ? C_XBP)
MOV ? C_XBP,# HIGH XBPSTACKTOP
MOV ? C_XBP + 1,# HIGH XBPSTACKTOP
ENDIF
IF PBPSTACK <> 0 ;LARGE 模式下使用重入函数是要设置的堆栈
EXTRN DATA ( ? C_PBP)
MOV ? C_PBP, # LOW PBPSTACKTOP
ENDIF
MOV SP,# ? STACK – 1
;如果使用了Mode 4 程序分组技术 ( BANKING )请启用下面的程序代码
; CALL ? B_SWITCHO ;程序从第一个块 (bank0)开始执行
LJMP ? C_START ;从这里跳到C程序入口
END
2.主程序的文件构架:
# include “main.h”
void Project_Init(void) /该函数初始化微控制器
{
USART_vInit(); //初始化异步串行接口器件
T01__vInit(); //初始化定时器T0和T1
INT__vInit(); //初始化外部触发中断ET0、ET1
IP = 0x15; //设置中断优先级:T2、T1、T0为低,串口、ET1、ET1为高
//用户可以加入的代码
EA = 1; //开放全局中断
}
//用户可以加入的自定义函数
void main ( void) //主程序函数,由Keil PK51内定函数C_START调用
{
//用户可以加入的自定义变量
Project_Init(); //初始化项目核心微控制器
//用户可以加入的全局初始变量赋值
while(1) //无限循环体,完成后台事务处理
{
//用户可以加入的代码
}
}
3.中断处理文件的构架
中断处理文件interrupt.c 的框架格式如下:
#include”interrupt.h
//外部中断0服务处理程序
void INT_viIsrEx0(void)interrupt EXOINT
{
//用户可以加入的代码
}
//定时器T1服务处理程序
void T1_viIsrT1(void) interrupt T1 INT
{
//用户可以加入的代码
}
// 串行收发中断服务处理程序
void USART_ viIsr (void)interrupt USARTINT
{
USART_Interrupt(); //在串行接口设备驱动程序中的串行收发中断处理函数
//用户可以加入的代码
}