stc52单片机怎么在keil中找到(stc15单片机怎么用keil编程)
怎么用keil把程序烧进单片机 STC32G单片机的Keil C251引导过程简析
STC32G12K128是宏晶公司新推出的基于80251 CPU架构的32位单片机,使用Keil的C251进行代码编译和程序调试。由于80251CPU比8051CPU新增加了两个关键的SFR寄存器“DPXL”和“SPH”,前者将8051的“MOVX”指令的地址范围从16位扩展到了24位,后者将8051。的堆栈指令“PUSH”和“POP”的堆栈空间从8位扩展到了16位。
在标准的Intel 8xC251SA/SB/SQ/SP系列单片机中,它们的定义为
sfr DPXL = 0x84
sfr SPH = 0xBE
但对于STC32G12K128单片机,它们的定义为
sfr DPXL = 0x84
sfr SPH = 0x85
显然“SPH”的地址是不同的,在STC32G的技术手册中“DPXL”的复位值为“00”与Intel的“01”不同。一些从8051架构的8位单片机向32位单片机过渡的编程者在学习了解STC32G单片机的过程中产生了一些疑惑,主要集中在下两个问题上
之一个问题STC32G的“SPH”的SFR地址与标准的80251不同,是否影响程序的运行,是否影响DEBUG的结果?
第二个问题STC32G的“SPH”和“DPXL”的硬件加电时的“初值”是否影响程序的正常运行?
笔者认为产生这两个问题的根源在于不了解STC32G单片机的Keil C251引导过程,以为80251CPU硬件与Keil C251编译器软件是深度捆绑的,其实不是。本文将对C251的引导过程进行分析,给出这两个问题的答案。
(1)Keil C251编译器并不与80251的SFR寄存器地址进行捆绑。下图为一个最简单的C251程序和编译效果
在这个程序里,没有加入任何SFR定义的头文件,结果C251编译器将所有这些80251的SFR(包括8051的SP)都认定是未知的,产生严重编译错误。
结论Keil的C251编译器并没有绑定任何SFR寄存器地址(也包括标准的Intel的80251CPU的SFR地址),编程者只需要针对自己实际使用的单片机,包含对应该单片机的SFR地址定义的头文件,C251编译器就能产生正确的编译结果。
(2)C251引导过程对“DPXL”的设置。下图是C251从地址FF:0000加电复位的开始程序
从中可以看到引导程序一开始第188行就是设置“DPXL”.然后是对以“EDATALEN”为顶的EDATA区域进行清零,由于WR8循环一直递减到0,EDATA区域包括的IDATA区域被清零了。
再然后就是对XDATA区域清零。由于前面已经设置了“DPXL”了,所以第202行的“MOVX”指令能够正确地对XDATA区域进行赋值操作。
第188行的段值“?C?XDATASEG”是由C251的编译环境给出的。项目的目标属性选项页如下
如果下面的扩展存储器选项框中对RAM区域有设置话,就从中计算出XDATA区域的段值赋值给常数“?C?XDATASEG”,如果用户没有对RAM区域进行设置,就将常数“?C?XDATASEG”确定为缺省值“01”。
结论不管STC32G单片机复位时“DPXL”的值是多少,C251在引导程序的一开始就进行了正确的设置,保证了以后程序的正确运行。
(3)知识点Keil的C251编译器除了在这里设置“DPXL”的值外,以后不会再改变它的值,这样就保证了整个程序对XDATA区域定义的一致性。或者说除非用户故意(比如用DPXL=0这样的语句),C251对任何C语言程序的编译结果和库函数都不包含改变“DPXL”SFR值的内容。如果用户在自己的程序中改变了“DPXL”的值,应该及时保留和恢复它的值。
(4)C251引导过程对“SPX”的设置。下图是引导程序的部分
图中第235行程序“MOV DR60,#WORD0 (?STACK-1)”使用80251的对32位寄存器的低16位用立即数赋值的指令,直接对DR60的低16位SPX堆栈指针赋值。由于引导程序是一次性地直接给16位的堆栈指针赋值,不是分别对SPX的高低8位部分“SPH”和“SP”赋值,无论STC32G将“SPH”的SFR地址映射在什么地方,使用C251编译器,都能正确地设置堆栈,不会影响编译结果的正确性。
,除非用户指定,C251编译器产生的代码只会对整个“DR60”进行操作,不会也不能对16位的寄存器SPX进行操作,也更不会对8位的寄存器“SPH”和“SP”进行单独的操作。
PS:按照C251这个神操作,不“SPH”,甚至连“SP”映射在什么地方都无所谓了。
重要提示在进行DEBUG分析程序时,必须要看整个16位指针的SPX的值,不要分别只看SP和SPH两个8位的值。
(5)对于80251CPU,堆栈是向上增长的。SPX的初始值等于堆栈段“?STACK”区域的首地址。从前面程序的第171行到第174行可以看到堆栈段位于EDATA区域,长度缺省位100H字节。
根据C251的内存分配原则,堆栈段是在EDATA空间中一个分配的。如果用户没有自己定义EDATA变量,库函数也没有使用EDATA变量,那么堆栈段从地址“08H”开始(SPX=07H),绕开了R0~R7的DATA地址。
由于80251的寄存器有自己专用的“寄存器空间”,将堆栈位于08H开始的EDATA空间后,寄存器操作与堆栈操作就不会互相影响了。
(6)本文C251引导程序是Keil给出的针对“Intel 8xC251SA”CPU的“START251.A51”文件,它与C51引导程序更大的不同是没有对“PSW”和“PSW1”进行初始化设置。
这意味着C251编译器将C语言编译为机器码时,使用“纯80251指令”,即使对8位寄存器的操作,也只使用“R0~R15”的80251指令,不使用8051的依赖寄存器页映射的指令。
(7)值得特别指出的是在C251编译器产生的中断服务程序中,没有像C51那种使PSW=0的操作,也没有指定51寄存器页的“USING”宏指令。如果没有特别的需要,用户也不需要用“USING”宏指令设置寄存器页,保持RS0和RS1都等于系统复位值就行了。如果用户改变了,那用户就要自己维护整个程序的一致性。
stc15单片机怎么用keil编程 stc单片机型号怎么添加到keil里