前言
在初学Keil C51时,一定会引用过C51的头文件,例如:
#include<REG51.H>// 或者 #include <REG52.H>// 或者 #include <REGX51.H>// 或者 #include <REGX52.H>// 或者小写版本 <reg51.h> ...voidmain(){while(1){}}一般来说,会遇见4种头文件REG51.H和REGX51.H,REG52.H和REGX52.H
顺便一提:在Windows下文件名是不区分大小写的!
也就是说REG51.H和reg51.h相同,本文依据个人习惯,下文用大写
本文将解释这4个头文件的关系,并讲解一些头文件技巧
头文件区别
REG51.H和REGX51.H,REG52.H和REGX52.H
这四个头文件中,最基础的是
REG51.H,它是C51单片机的基础配置,内部定义了寄存器位置REGX51.H是REG51.H的升级版,内部除了基本的寄存器位置外,还有引脚定义,以及许多额外辅助配置宏
类似的,
REG52.H是C52单片机的基础配置,内部定义了寄存器位置REGX52.H是REG52.H的升级版,内部除了基本的寄存器位置外,还有引脚定义,以及许多额外辅助配置宏
看到这里,有些读者可能会有疑问,为什么开发C51单片机会出现C52头文件?
因为,虽然一般说C51单片机编程,但通常真正使用的芯片是STC公司生产的STC89C52RC单片机,C52单片机兼容C51,而且性能更强。
如今购买"C51"得到的一般都是C52单片机,只不过口头习惯继续叫"C51"
因为C52兼容C51,所以在开发C52时,用REG51.H/REGX51.H(C51的头文件)也是完全可以的,只是少了一些C52新增的功能
在实际开发中,通常都直接使用REGX52.H
头文件内容
我们以REG52.H和REGX52.H为例,看一下头文件内容(REG51.H和REGX51.H类似):
首先是REG52.H,本质上就是用sfr和sbit定义了各个基本寄存器的位置
例如P0组引脚,固定在0x80的位置,头文件已经帮我们写好了,就不需要我们自己手动记忆书写了
// REG52.Hsfr P0=0x80;sfr P1=0x90;sfr P2=0xA0;sfr P3=0xB0;sfr PSW=0xD0;...sbit CY=PSW^7;sbit AC=PSW^6;sbit F0=PSW^5;sbit RS1=PSW^4;sbit RS0=PSW^3;sbit OV=PSW^2;...而REGX52.H则是在REGX51.H的基础上多了通用引脚的定义与辅助宏
通用引脚就是已经帮忙写了P1_0,P2_0等定义
这样就不用手动一个一个定义引脚了,直接用REGX51.H或REGX52.H就可以直接用定义好的通用引脚了
而辅助宏则是便于记忆与配置单片机功能,详情见下文
// REGX52.H//以下这些是REG52.H就有的sfr P0=0x80;sfr P1=0x90;sfr P2=0xA0;...sbit CY=PSW^7;sbit AC=PSW^6;sbit F0=PSW^5;...//REGX52.H新增的通用引脚定义sbit P1_0=0x90;sbit P1_1=0x91;sbit P1_2=0x92;...//REGX52.H新增的辅助宏#defineT0_M0_0x01#defineT0_M1_0x02#defineT0_CT_0x04#defineT0_GATE_0x08#defineT1_M0_0x10#defineT1_M1_0x20...REGX 辅助宏
REGX52.H和REGX51.H中有3组辅助宏,可以方便我们配置单片机功能,分别是:
PCON辅助宏,用于辅助配置PCON寄存器,设置电源,功率
#defineIDL_0x01#defineSTOP_0x02#definePD_0x02/* Alternate definition */#defineGF0_0x04#defineGF1_0x08#defineSMOD_0x80TMOD辅助宏,用于辅助配置TMOD寄存器,设置定时器/计数器功能
#defineT0_M0_0x01#defineT0_M1_0x02#defineT0_CT_0x04#defineT0_GATE_0x08#defineT1_M0_0x10#defineT1_M1_0x20#defineT1_CT_0x40#defineT1_GATE_0x80#defineT1_MASK_0xF0#defineT0_MASK_0x0F中断标志辅助宏,便于记忆中断标志:
#defineIE0_VECTOR0/* 0x03 External Interrupt 0 */#defineTF0_VECTOR1/* 0x0B Timer 0 */#defineIE1_VECTOR2/* 0x13 External Interrupt 1 */#defineTF1_VECTOR3/* 0x1B Timer 1 */#defineSIO_VECTOR4/* 0x23 Serial port */#defineTF2_VECTOR5/* 0x2B Timer 2 */#defineEX2_VECTOR5/* 0x2B External Interrupt 2 */辅助宏使用示例
中断标志辅助宏
一般的检测外部按钮按下的INT1中断这么写:
voidINT1_button(void)interrupt2{LED=!LED;}需要手动记忆INT1中断对应2,而这时就可以用中断标志辅助宏:
voidINT1_button(void)interrupt IE1_VECTOR{LED=!LED;}这样就可以方便记忆一些,IEx对应INT中断,TFx对应定时器中断,或者单纯忘了中断对应的序号,到这里查看一下也是可以的
TMOD辅助宏
以下是设定Timer0,模式1,16位定时器:
TMOD&=0xF0;// 清除 Timer0 的控制位TMOD|=0x01;// Timer0,模式1,16位定时器而使用辅助宏后,可以增加可读性:
TMOD&=~T0_MASK_;// 清除 Timer0 的控制位TMOD|=T0_M0_;// Timer0,模式1,16位定时器