您的位置 首页 汽车

C51编程的一些概念

l绝对地址访问lC与汇编的接口lC51软件包中的通用文件l段名转换与程序优化第一节绝对地址访问C51提供了三种访问绝对地址的方法:1

l 肯定地址拜访

l C与汇编的接口

l C51软件包中的通用文件

l 段名转化与程序优化

第一节 肯定地址拜访
C51供给了三种拜访肯定地址的办法:

1. 肯定宏:
在程序中,用“#include”即可运用其间界说的宏来拜访肯定地址,包含:

CBYTE、XBYTE、PWORD、DBYTE、CWORD、XWORD、PBYTE、DWORD

详细运用可看一看absacc.h便知

例如:

rval=CBYTE[0x0002];指向程序存贮器的0002h地址

rval=XWORD [0x0002];指向外RAM的0004h地址

2. _at_要害字
直接在数据界说后加上_at_ const即可,可是留意:

(1)肯定变量不能被初使化;

(2)bit型函数及变量不能用_at_指定。

例如:

idata struct link list _at_ 0x40;指定list结构从40h开端。

xdata char text[25b] _at_0xE000;指定text数组从0E000H开端

提示:假如外部肯定变量是I/O端口等可自行改变数据,需求运用volatile要害字进行描绘,请参看absacc.h。

3. 衔接定位操控
此法是运用衔接操控指令code xdata pdata \data bdata对“段”地址进行,如要指定某详细变量地址,则很有局限性,不作详细评论。

第二节 Keil C51与汇编的接口
1. 模块内接口
办法是用#pragma句子详细结构是:

#pragma asm

汇编行

#pragma endasm

这种办法本质是经过asm与ndasm告知C51编译器中心行不必编译为汇编行,因而在编译操控指令中有SRC以操控将这些不必编译的行存入其间。

2. 模块间接口
C模块与汇编模块的接口较简略,分别用C51与A51对源文件进行编译,然后用L51将obj文件衔接即可,要害问题在于C函数与汇编函数之间的参数传递问题,C51中有两种参数传递办法。

(1) 经过寄存器传递函数参数

最多只能有3个参数经过寄存器传递,规则如下表:

参数数目
char
int
long,float
一般指针

1

2

3
R7

R5

R3
R6 & R7

R4 & R5

R2 & R3
R4~R7

R4~R7
R1~R3

R1~R3

R1~R3

(2) 经过固定存储区传递(fixed memory)

这种办法将bit型参数传给一个存储段中:

?function_name?BIT

将其它类型参数均传给下面的段:?function_name?BYTE,且依照预选次序寄存。

至于这个固定存储区本身在何处,则由存储形式默许。

(3) 函数的回来值

函数回来值一概放于寄存器中,有如下规则:

return type
Registev
阐明

bit
标志位
由详细标志位回来

char/unsigned char 1_byte指针
R7
单字节由R7回来

int/unsigned int 2_byte指针
R6 & R7
双字节由R6和R7回来,MSB在R6

long&unsigned long
R4~R7
MSB在R4, LSB在R7

float
R4~R7
32Bit IEEE格局

一般指针
R1~R3
存储类型在R3 高位R2 低R1

(4) SRC操控

该操控指令将C文件编译生成汇编文件(.SRC),该汇编文件可改名后,生成汇编.ASM文件,再用A51进行编译。

第三节 Keil C51软件包中的通用文件
在C51\LiB目录下有几个C源文件,这几个C源文件有非常重要的效果,对它们稍事修正,就能够用在自己的专用体系中。

1. 动态内存分配
init_mem.C:此文件是初始化动态内存区的程序源代码。它能够指定动态内存的方位及巨细,只需运用了init_mem( )才能够调回其它函数,比如malloc calloc,realloc等。

calloc.c:此文件是给数组分配内存的源代码,它能够指定单位数据类型及该单元数目。

malloc.c:此文件是malloc的源代码,分配一段固定巨细的内存。

realloc.c:此文件是realloc.c源代码,其功用是调整当时分配动态内存的巨细。

2. C51发动文件STARTUP.A51
发动文件STARTUP.A51中包含方针板发动代码,可在每个project中参加这个文件,只需复位,则该文件当即履行,其功用包含:

l 界说内部RAM巨细、外部RAM巨细、可重入仓库方位

l 铲除内部、外部或许以此页为单元的外部存储器

l 按存储形式初使化重入仓库及仓库指针

l 初始化8051硬件仓库指针

l 向main( )函数交权

开发人员可修正以下数据从而对体系初始化

常数名 含义

IDATALEN 待清内部RAM长度

XDATA START 指定待清外部RAM开始地址

XDATALEN 待清外部RAM长度

IBPSTACK 是否小形式重入仓库指针需初始化标志,1为需求。缺省为0

IBPSTACKTOP 指定小形式重入仓库顶部地址

XBPSTACK 是否大形式重入仓库指针需初始化标志,缺省为0

XBPSTACKTOP 指定大形式重入仓库顶部地址

PBPSTACK 是否Compact重入仓库指针,需初始化标志,缺省为0

PBPSTACKTOP 指定Compact形式重入仓库顶部地址

PPAGEENABLE P2初始化答应开关

PPAGE 指定P2值

PDATASTART 待清外部RAM页首址

PDATALEN 待清外部RAM页长度

提示:假如要初始化P2作为紧凑形式高端地址,有必要:PPAGEENAGLE=1,PPAGE为P2值,例如指定某页1000H-10FFH,则PPAGE=10H,并且衔接时有必要如下:

L51 PDATA(1080H),其间1080H是1000H-10FFH中的任一个值。

以下是STARTUP.A51代码片断,赤色是常常或许需求修正的当地:

;——————————————————————————

; This file is part of the C51 Compiler package

; Copyright KEIL ELEKTRONIK GmbH 1990

;——————————————————————————

; STARTUP.A51: This code is executed after processor reset.

;

; To translate this file use A51 with the following invocation:

;

; A51 STARTUP.A51

;

; To link the modified STARTUP.OBJ file to your application use the following

; L51 invocation:

;

; L51 , STARTUP.OBJ

;

;——————————————————————————

;

; User-defined Power-On Initialization of Memory

;

; With the following EQU statements the initialization of memory

; at processor reset can be defined:

;

; ; the absolute start-address of IDATA memory is always 0

IDATALEN EQU 80H ; the length of IDATA memory in bytes.

;

XDATASTART EQU 0H ; the absolute start-address of XDATA memory

XDATALEN EQU 0H ; the length of XDATA memory in bytes.

;

PDATASTART EQU 0H ; the absolute start-address of PDATA memory

PDATALEN EQU 0H ; the length of PDATA memory in bytes.

;

; Notes: The IDATA space overlaps physically the DATA and BIT areas of the

; 8051 CPU. At minimum the memory space occupied from the C51

; run-time routines must be set to zero.

;——————————————————————————

;

; Reentrant Stack Initilization

;

; The following EQU statements define the stack pointer for reentrant

; functions and initialized it:

;

; Stack Space for reentrant functions in the SMALL model.

IBPSTACK EQU 0 ; set to 1 if small reentrant is used.

IBPSTACKTOP EQU 0FFH+1 ; set top of stack to highest location+1.

;

; Stack Space for reentrant functions in the LARGE model.

XBPSTACK EQU 0 ; set to 1 if large reentrant is used.

XBPSTACKTOP EQU 0FFFFH+1; set top of stack to highest location+1.

;

; Stack Space for reentrant functions in the COMPACT model.

PBPSTACK EQU 0 ; set to 1 if compact reentrant is used.

PBPSTACKTOP EQU 0FFFFH+1; set top of stack to highest location+1.

;

;——————————————————————————

;

; Page Definition for Using the Compact Model with 64 KByte xdata RAM

;

; The following EQU statements define the xdata page used for pdata

; variables. The EQU PPAGE must conform with the PPAGE control used

; in the linker invocation.

;

PPAGEENABLE EQU 0 ; set to 1 if pdata object are used.

PPAGE EQU 0 ; define PPAGE number.

;

;——————————————————————————

3. 规范输入输出文件
putchar.c

putchar.c是一个初级字符输出子程,开发人员可修正后应用到自己的硬件体系上,例如向CLD或LEN输出字符。

缺省:putchar.c是向串口输出一个字符XON|XOFF是流控标志,换行符“\*n”主动转化为回车/换行“\r\n”。

getkey.c

getkey函数是一个初级字符输入子程,该程序可用到自己硬件体系,如矩阵键盘输入中,缺省时经过串口输入字符。 4. 其它文件
还包含对Watch-Dog有共同功用的INIT.A51函数以及对8×C751适用的函数,可参看源代码。

第四节 段名协议与程序优化
1. 段名协议(Segment Naming Conventions)
C51编译器生成的方针文件寄存于许多段中,这些段是代码空间或数据空间的一些单元,一个段能够是可重定位的,也能够是肯定段,每一个可重定位的段都有一个类型和姓名,C51段名有以下规则:

每个段名包含前缀与模块名两部分,前缀表明存储类型,模块名则是被编译的模块的姓名,例如:

?CO?main1 :表明main1模块中的代码段中的常数部分

?PR?function1?module 表module模块中函数function1的可履行段,详细规则参看手册。

2. 程序优化
C51编译器是一个具有优化功用的编译器,它共供给六级优化功用。保证生成方针代码的最高功率(代码最少,运转速度最快)。详细六级优化的内容可参看协助。

在C51中供给以下编译操控指令操控代码优化:

OPTIMIZE(SJXE):尽量选用子程序,使程序代码削减。

NOAREGS:不运用肯定寄存器拜访,程序代码与寄存器段独立。

NOREGPARMS:参数传递总是在部分数据段完成,程序代码与低版本C51兼容。

OPTIMIZE(SIZE)AK OPTIMIZE(speed)供给6级优化功用,缺省为: OPTIMIZE(6,SPEED)。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/qiche/261770.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部