C51编程的一些概念

发布者:巳午未最新更新时间:2016-03-25 来源: eefocus关键字:c51  编程 手机看文章 扫描二维码
随时随地手机看文章
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)。

关键字:c51  编程 引用地址:C51编程的一些概念

上一篇:C8051F320 I/O使用总结
下一篇:delphi与51单片机串行通信

推荐阅读最新更新时间:2024-03-16 14:48

基于LonWorks的在系统编程技术
摘要:LonWorks技术的应用使得在系统编程的内涵得以更充分的体现。本文在概要介绍ISP以及LonWorks技术的基础上,详细说明采用基于Neuron芯片的控制节点实现对CPLD进行在系统编程的具体方法。 关键词:Neuron 控制节点 在系统编程(ISP) CPLD 引言 在系统编程ISP(In System Programming)是指在用户设计的目标系统或印刷电路板上为重新配置逻辑,或实现新的功能而对器件进行编程或反复编程。随着EDA工具的普及和ISP器件的日益成熟,ISP技术也得到了越来越广泛的应用。ISP技术的应用使得硬件设计软件化,其显著优势体现在:简化生产流程;利用同一硬件结构实现多种系统功能,使之成多功能硬
[传感技术]
AVR单片机无法进入编程模式
做项目用到了AVR单片机ATmega16,学习的过程中编辑编译环境是ICCAVR,采用并口下载器和PonyProg2000软件下载程序。项目做的差不多的时候,考虑到如果要去现场调试程序并且还用并口下载器,那就要带个台式电脑或者买个EXPRESSCARD了,这样就很不方便,那就考虑笔记本电脑吧。后来就买了个深圳市研学电子有限公司的AVR二合一工具。照着光盘资料安装了USB驱动和AVR Studio软件后,将AVR二合一工具和计算机USB口以及目标板相连后,打开AVR Studio软件,单击工具栏上的 按钮,出现如下对话框: 单击Connect按钮,出现如下对话框: 然后单击Flash组中的Program按钮,出现如下对话
[单片机]
AVR单片机无法进入<font color='red'>编程</font>模式
TI面向MCU应用的零漂移可编程增益放大器
日前,德州仪器 (TI) 宣布推出具有单端输入、单电源工作、轨至轨 I/O 以及多通道多路复用器 (MUX) 的 PGA11x 产品系列零漂移可编程增益放大器 (PGA) 。 PGA112 、 PGA113 、 PGA116 以及 PGA117 可针对微处理器应用提供高度集成的高灵活可编程增益放大解决方案,满足便携式数据采集、远程抄表、自动增益控制、可编程逻辑控制器以及手持测试设备等需求。 PGA112 与 PGA116 可提供 1 、 2 、 4 、 8 、 16 、 64 以及 128 等二进制增益,而 PGA1
[模拟电子]
TI面向MCU应用的零漂移可<font color='red'>编程</font>增益放大器
具 I2C/PMBus 数字控制和可编程环路补偿的双通道 DC/DC 控制器
加利福尼亚州米尔皮塔斯 (MILPITAS, CA) 2015 年 8 月 12 日 凌力尔特公司 (Linear Technology Corporation) 推出 60V 输入、双输出同步降压型 DC/DC 控制器 LTC3886,该器件具可编程环路补偿和基于 I2C 的 PMBus 接口。这个控制器采用恒定频率、电流模式架构,可编程输出电压高达 13.8V。LTC3886 非常适合需要很大输入电压范围的严酷环境,这种大输入电压范围常见于工厂自动化、工业、医疗、通信和航空电子应用。 LTC3886 可配置为双输出或单输出,可叠置至多达 6 相,以支持高达 120A 的负载电流。针对 2、3、4 或 6 相的交
[电源管理]
按歪歪扭扭电路图做有模有样单片机89C51编程
上次要用 单片机 89C51时,K1200编程器有点问题,不知道编程器还是单片机出问题,于是自己又做了个简易的 89C51 编程器,主要是不想花什么钱,就地取材。电路图参考了网上的一些资料。 正好有2个单片机小板,加上一个STC单片机。 只是引脚太多,飞线太多了,焊得累S了。然后 单片机 和VC编程也累得不行。嗑嗑碰碰,终于成功。烧写单片机 89C51 可真是麻烦。 电路图,手画的,能简便就简便: 完工后的图,焊得我晕: P0口上的上拉电阻一定要接,不然读 单片机 数据正确,但烧写时比较奇怪,前几个数量随机的字节会正确,后面就都是0xFF了,怎么调整程序都没有用,浪费了很多时间。通讯时上拉电阻挺重要的。 后来K1200
[电源管理]
按歪歪扭扭电路图做有模有样单片机89C51<font color='red'>编程</font>器
89C51单片机定时/计数器、P1口编程举例
在89C51单片机的P1.0端口上接有一个发光二极管,P1.0输出低电平时发光二极管点亮,输出高电平时熄灭。P1.7接有一个开关,开关闭合时,P1.7为低电平,断开时为高电平。请设计一个控制程序,当开关闭合时,发光二极管每秒钟闪烁一次,当开关断开时,发光二极管每秒钟闪烁两次。已知系统使用12MHz的晶体。 LED BIT P1.0 ;发光二极管控制信号输出端口 KEY BIT P1.7 ;开关状态检测端口 CLOK EQU 20H ;时钟单元(单位:1/16秒) SEC BIT CLOK.3 ;秒闪烁控制位 DSEC BIT CLOK.2 ;半秒闪烁控制位 ORG 0000H LJMP MAIN ;至主程序 ORG
[单片机]
STC89C52RC单片机额外篇 | 06 - 认识高内聚、低耦合的模块化编程
模块化编程是管理程序的一种方法,代码量少的情况下其实感觉不到模块化编程的好处,但是随着代码量越来越大,为了方便管理与调试定位问题,模块化管理是必须的。模块化是尽可能地实现函数内部高内聚,函数之间低耦合!下面我给大家看看如何实现在单片机编程中实现模块化! 为了给读者达到更好的理解效果,本博文引用博主大学之时的一篇实验报告作为例子。 没错,就是这篇博文:《单片机综合实验 - 06 | 数字温度计设计》。 这个数字温度计主要包含了以下几个模块: DS18B20数字温度传感器 LED数码管 蜂鸣器 1 原始程序 //*****************************头文件声明********************
[单片机]
通过日期算星期的C51源程序
#include reg52.h #define uint unsigned int #define uchar unsigned char uchar code monthday ={31,28,31,30,31,30,31,31,30,31,30,31}; uchar month_n_day(uint y,uchar m) //算出某年某月有多少天 { if(m==2) return(((y%4 == 0) && (y%100 != 0) || (y%400 == 0))? 29: 28); else return(monthday ); } //**************
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved