C51 就是 c 语言 for 51 单片机,这里边还是有很多不同的,在 c 语言里运算量
相信都知道那叫一个简单,直接 int, float 就哦了 ,当然这里也可以直接
int, float,但是他们还是有不同的,这里就介绍一下运算量中的不同! , 相同的我就直接跳过~(果断不说了,不同的对于以后 c 语言开发 51 单片机还是
相当有用的,慢慢的就会体会到了~~~~~ ,尤其是特殊功能寄存器变量、位 变量、还有绝对地址的访问!
C51 的运算量(只说重点~):
C51 中的运算量主要是常量和变量。
1、常量
常量是指在程序执行过程中不能改变的量。在 C51 中支持整型常量、浮点型常量、 字符型常量和字符串型常量。
1)整型常量
2)浮点型常量
3)字符型常量
4)字符串型常量
2、变量 变量就是在程序运行过程中可以改变的量呗。
一个变量有两部分组成:变量名和变量值。每个变量都有一个变量名,在存储器 中占用一定的存储单元,变量的数据类型不同,占用的存储单元数就不同。在存 储单元中存放的内容就是变量值。
1)数据类型说明符
在定义变量时必须通过数据类型说明符来指明变量的数据类型,指明变量在存储 器中占用的字节数。可以使基本数据类型说明符,也可以是组合数据类型说明符, 还可以是 typedef 或者#define 定义的类型别名(这里一定要注意 typedef 一般用
来定义别名!尽量不要用#define 啊~~我就不解释了 ,太专业了~~不过用宏 定义就一定要用#define)
例如:
typedef unsigned char uchar; //这个是有;的
typedef unsigned int uint;
或者:
#define uchar unsigned char //这个就没有; 而且它们两个定义相反
#define uint unsigned int
2)变量名 变量名有两种:普通变量和指针变量。他们的区别是指针变量名前面带“*”号。
3)存储种类
存储种类是指变量在程序执行过程中的作用范围。C51 变量的存储种类有 4 种, 分别是:自动(auto)、外部(extern)、静态(static)和存储器(register)。
a、auto
当定义它的函数体或者复合语句执行时,C51 才为该变量分配内存空间,结束时 占用的内存空间释放。自动变量一般分配在内存的堆栈空间中。定义变量时,如 果缺省存储种类,则默认为此。
b、extern
被定以后分配固定的内存空间,在程序整个执行时间内都有效,知道程序结束时 才释放。
c、static
使用 static 定义的变量成为外部变量,可分为内部静态变量和外部静态变量。在 函数体内部定义的静态变量为内部静态变量,它在对应的函数体内有效,一直存 在,但在函数体外不可见。这样不仅使变量在定义它的函数体外可以被保护,还 可以实现当离开函数体时值不被改变。外部静态变量是在函数体外定义的静态变 量,它在程序中一直存在,但在定义的范围之外是不可见的。如在多文件或者多
模块处理中(这点很重要,以后会用到很多,尤其是多模块,写大程序必须具备 的),外部静态变量只在文件内部或者模块内部有效。
d、register
它定义的变量存放在 CPU 内部的寄存器中,处理速度快,但是数目有限。
4)存储器类型 存储器类型用来指明变量所处的单片机的存储区域情况。类型如下: data:直接寻址的片内 RAM 低 128B,访问速度快
bdata:片内 RAM 的可位寻址区(20H~2FH),允许字节和位混合访问
idata:间接寻址访问的片内 RAM,允许访问全部片内 RAM
pdata:用 Ri 简洁访问的片外 RAM 低 256B
xdata:用 DPTR 间接访问的片外 RAM,允许访问全部 64KB 片外 RAM
code:程序存储器 ROM64KB
注意:定义变量时可以省略“存储类型”,省略时 C51 编译器将按存储模式默认存 储器类型。具体的存储情况啊~~一会你就知道了,继续往下看~~哈
例如:
char data var1; //在片内 RAM 低 128B 定义用直接寻址方式访问的自足型变量
var1
unsigned char bdata var2; //在片内 RAM 位寻址区(20H~2FH)单元定义可字 节处理和位处理的无符号字符型变量 var2
5)特殊功能寄存器变量
在 51 单片机中有很多特殊功能寄存器(不过这些有些东西还是不需要我们来关 心的~~~因为在调用#include"reg52.h"的时候里面都给你整好了 ),通过这些
特殊功能寄存器可以控制 51 单片机的定时器、计数器、串口、I/0 及其他功能部 件(这里很重要的~~~~~~),没一个特殊功能寄存器再片内 RAM 中都对应一个 字节单元或者两个字节单元。
在 C51 中,允许用户对这些特殊功能寄存器进行访问,但是访问时需要通过 sfr 或者 sfr16 类型说明符进行定义,定义是需要指明他们所对应的片内 RAM 单元的 地址。(你过关不用担心,直接调用#include"reg52.h"就哦了~)
例如:
sfr PSW=0xd0; sfr SCON=0x98; sfr16 DPTR=0x82;
6)位变量
在 C51 中,允许用户通过位类型符定义位变量。 位类型符有两个:bit 和 sbit。可以定义两种位变量。 a、bit 型位变量
在格式中可以加上各种修饰,但是要注意存储器类型只能是 bdata、data、idata, 只能是片内 RAM 的可位寻址区,严格来说只能是 bdata。
例如:
bit bdata a1;
b、sbit 型位变量
sbit 位类型符用于定义在可位寻址字节或者特殊功能寄存器中的位,定义时需要 指明其位地址,可以使位直接地址,可以是可位寻址变量带位号,也可以是特殊 功能寄存器名带位号。
例如(这些东西都在#include"reg52.h"中):
sbit OV=0xd2;
sbit CY=0xd7;
unsigned char bdata flag;
sbit flag_0=flag^0; //字节地址与位号之间、特殊功能寄存器与位号之间一般用
“^”作间隔
sfr P1=x090;
sbit P1_1=P1^1;
3、存储模式(个人感觉真的用不到这些东东了,因为你丫的要是嫌小可以换个 大的,而且还相当的便宜~~~~ ,我以前试过扩展一个 RAM 和 ROM,擦
不成啊~~)
C51 编译器支持 3 种存储模式:SMALL 模式、COMPACT 模式和 LARGE 模式。不 同的存储模式对变量默认的存储器类型不一样。
1)SMALL 模式
SMALL 模式成为小编译模式,在 SMALL 模式下,编译时函数参数以及变量被默 认在片内 RAM 中,存储类型为 data。
2)COMPACT 模式
COMPACT 模式称为紧凑编译模式,在 COMPACT 模式下,编译时函数参数和变量 被默认在片外 RAM 的低 256B 空间,存储类型为 pdata。
3)LARGE 模式
LARGE 模式称为大编译模式,在 LARGE 模式下,编译时函数参数和变量被默认在 片外 RAM 的 64KB 空间了,存储器类型为 xdata。
例如:
#pragma small //变量的存储模式为 SMALL
char k1; //存储类型为 data
int xdata m1; //存储类型 xdata
#pragma compact //变量的存储模式为 COMPACT
char k2;
int xdata m2;
int func1(int x1,int y1) large //函数的存储模式为 LARGE
{
return(x1+y1);
}
int func2(int x2,int y2) //编译的存储模式隐含为 SMALL,没有指明模式,隐含
SMALL
{
return(x2-y2);
}
4、绝对地址的访问(这里才是重点中的重点啊~~~)
在 C51 中,可以通过变量的形势访问 51 单片机的存储器,也可以通过绝对地址 来访问存储器。三种方法:
1)使用 C51 运行库中预定义宏(就是调用#include"absacc.h")
C51 编译器提供了一组宏定义来对 51 单片机的 code、data、pdata 和 xdata 空间 进行绝对寻址!
规定只能以无符号数方式访问,定义了 8 个宏定义,其函数原型如下:
#define CBYTE((unsigned char volatile*)0x50000L) //CBYTE 以字节形势对 code 区 寻址
#define DBYTE((unsigned char volatile*)0x40000L) //data 区
#define PBYTE((unsigned char volatile*)0x30000L) //pdata 区
#define XBYTE((unsigned char volatile*)0x20000L) //xdata 区
#define CWORD(unsigned int volatile*)0x50000L) //以字形式对 code 区寻址
#define DWORD(unsigned int volatile*)0x40000L)
#define PWORD(unsigned int volatile*)0x30000L)
#define XWORD(unsigned int volstile*)0x20000L)
例如:
#include"absacc.h"
#include"reg52.h"
typedef unsigned char uchar; typedef unsigned int uint; void main()
{
uchar var1;
uint var2;
var1=XBYTE[0x0005]; //XBYTE[0x0005]访问片外 RAM 的 0005 字节单元
var2=XWORD[0x0002]; //XWORD[0x0002]访问片外 RAM 的 0002 字单元
.
.
. while(1);
}
2)通过指针访问
采用指针的访问的方法,可以在 C51 程序中对任意指定的存储器单元进行访问。
typedef unsigned char uchar; typedef unsigned int uint; void func()
{
uchar data var1;
uchar pdata *dp1; //定义一个指向 pdata 区的指针 dp1
uint xdata *dp2; //定义一个指向 xdata 区的指针 dp2,为 uint 型
uchar data *dp3; //定义一个指向 data 区的指针 dp3,为 char 型
dp1=0x30; //dp1 指针赋值,指向 pdata 区的 30H 单元
dp2=0x1000; //dp2 指针赋值(uint 型),指向 xdata 区的 1000H 单元
*dp1=0xff; //将数据 0xff 送到片外 RAM30H 单元
*dp2=0x1234; //将数据 0x1234(由于是 uint 型,你懂得~~~),送到片 外 RAM1000H 单元
dp3=&var1; //dp3 指针指向 data 区的 var1 变量
*dp3=0x20; //给变量 var1 赋值 0x20
}
3)使用 C51 扩展关键字 _at_ (这个用的最多了~~~ ) 总算完了,我真的要累死了~~~~擦擦擦擦啊
一般格式:
[存储类型] 数据类型说明 变量名 _at_ 地址常量;
其中,存储类型为 data、bdata、idata、pdata、xdata 等 C51 能识别的数据类型, 如果省略,则会按照存储模式规定的默认存储类型确定变量的存储区域( 这
里又用到上边的了);数据类型为 C51 支持的数据类型;地址常数用于指定变量 的绝对地址,必须位于有效的存储器空间之内;使用_at_定义的变量必须为全局 变量。
例如:
typedef unsigned char uchar;
typedef unsigned int uint;
data uchar x1 _at_ 0x40; //在 data 区中定义字节变量 x1,地址为 0x40H,这里 是 uchar
xdata uint x2 _at_ 0x2000; //在 xdata 区中定义字变量 x2,它的地址为 0x2000H, 这里是 uint
我感觉我真的不想再写了,累死了~~~擦
不过完工了,爽啊~~解脱
完整的pdf格式文档51黑下载地址:
C51—运算量(重点:特殊功能寄存器变量、位变量.pdf
(118.07 KB, 下载次数: 19)
|