8051单片机的C语言编程

2019-04-15 17:58发布

      8051的C语言编程和传统的C语言编程是类似的。当然其中有些数据类型是不一样的,我们知道8051支持强大的位寻址能力,因此8051的C语言编程增加了一些新的数据类型,为了不使的8051的能力被浪费。下面给出新增的数据类型。       bit   ——用于定义1个位变量,用于8051的位寻址空间(仅仅限于内部RAM的20H——2FH的字节空间(00H——7FH的位地址空间)).(不得不说8051的地址重叠搞得人很烦)                      例如:bit  flag  = 0;    定义flag为一个位变量,并且初始化为0.
       sbit  ——用于定义一个位变量,用于8051的特殊功能寄存器(内部RAM的80H——FFH的字节空间)
                      例如:sbit CY  =  0xD7;
                                sbit  P0_0 = 0x80^0;
        上面的bit和sbit是两种不同的数据类型,bit是用于给某一位地址赋值,而sbit是用于给某一个特殊功能寄存器的某一位的位地址起名字。
       sfr  ——用于定义一个特殊功能寄存器变量。                       例如:sfr  PSW  = 0xD0;                       当有了上面的定以后,可以这样来使用PSW的每一位,例如:PSW^0;表示PSW的第0位,即奇偶校验位P。
       sfr16  ——用于定义16位的特殊功能寄存器变量。
                        例如:sfr16  DPTR  = 0x82;        通过上面引入的数据类型,使得8051的C语言编程变得和普通的C语言编程基本一致。也充分利用了8051的特点。        现在,我们的集成开发环境都很人性化,把8051的特殊功能寄存器,可位寻址特殊功能寄存器的控制位都定义在一个名为reg51.h的头文件里面。下面我们给出该头文件的内容。 /*-------------------------------------------------------------------------- REG51.H Header file for generic 80C51 and 80C31 microcontroller. Copyright (c) 1988-2002 Keil Elektronik GmbH and Keil Software, Inc. All rights reserved. --------------------------------------------------------------------------*/ #ifndef __REG51_H__ #define __REG51_H__ /* BYTE Register */ sfr P0 = 0x80; sfr P1 = 0x90; sfr P2 = 0xA0; sfr P3 = 0xB0; sfr PSW = 0xD0; sfr ACC = 0xE0; sfr B = 0xF0; sfr SP = 0x81; sfr DPL = 0x82; sfr DPH = 0x83; sfr PCON = 0x87; sfr TCON = 0x88; sfr TMOD = 0x89; sfr TL0 = 0x8A; sfr TL1 = 0x8B; sfr TH0 = 0x8C; sfr TH1 = 0x8D; sfr IE = 0xA8; sfr IP = 0xB8; sfr SCON = 0x98; sfr SBUF = 0x99; /* BIT Register */ /* PSW */ sbit CY = 0xD7; sbit AC = 0xD6; sbit F0 = 0xD5; sbit RS1 = 0xD4; sbit RS0 = 0xD3; sbit OV = 0xD2; sbit P = 0xD0; /* TCON */ sbit TF1 = 0x8F; sbit TR1 = 0x8E; sbit TF0 = 0x8D; sbit TR0 = 0x8C; sbit IE1 = 0x8B; sbit IT1 = 0x8A; sbit IE0 = 0x89; sbit IT0 = 0x88; /* IE */ sbit EA = 0xAF; sbit ES = 0xAC; sbit ET1 = 0xAB; sbit EX1 = 0xAA; sbit ET0 = 0xA9; sbit EX0 = 0xA8; /* IP */ sbit PS = 0xBC; sbit PT1 = 0xBB; sbit PX1 = 0xBA; sbit PT0 = 0xB9; sbit PX0 = 0xB8; /* P3 */ sbit RD = 0xB7; sbit WR = 0xB6; sbit T1 = 0xB5; sbit T0 = 0xB4; sbit INT1 = 0xB3; sbit INT0 = 0xB2; sbit TXD = 0xB1; sbit RXD = 0xB0; /* SCON */ sbit SM0 = 0x9F; sbit SM1 = 0x9E; sbit SM2 = 0x9D; sbit REN = 0x9C; sbit TB8 = 0x9B; sbit RB8 = 0x9A; sbit TI = 0x99; sbit RI = 0x98; #endif 8051单片机有多重存储方式,内部RAM,内部ROM,外部RAM,外部ROM。有时候我们希望知道该变量在哪儿。
        上面这张表给出了变量,函数等被放在8051的那个存储区。
例如:char  code  str[] = "hello  world!";定义一个数组,被放在ROM中。        当然了,上面的定义方式会导致在访问的时候速度是不一样的,比如data就比xdata要快。如果数据是放在外部RAM的,可以考虑使用xdata或者是pdata。        如果忘记声明存储在哪儿,8051会默认是small的存储模式。该模式将所有数据放在内部RAM中。详细请看下表

在程序中可以通过#program来选择设置哪一种模式。否则默认是small。
 最后,还是要谈到关于指针的问题,8051的C语言编程实际上还是很像汇编语言的,需要我们对内存区域进行直接操作。指针在C语言里本来就很灵活,在这里我们还是要看看指针的存储类型。例如: int  *xdata  numptr = #    指针指向int类型的数据,但它本身是在外部RAM中存储着。           int  data  *xdata  numptr  =  #   指针指向存储在内部RAM中的int类型数据,指针本身在外部RAM中。还有一点很重要,C语言的数据类型在8051中占据的大小。




以上的结果表明:char类型在8051中占据了1个字节int类型在8051中占据了2个字节float类型在8051中占据了4个字节double类型在8051中占据了4字节指针是最有意思的一个。从上面的结果来看,如果没有指定指针所指向的数据存储在哪块儿,则指针在8051中占据3字节。其中第一个字节存储了它所对应的数据的存储类型如果指明了在内部RAM,则占据一个字节,在外部RAM则是占用2个字节。未定义数据存储类型的指针变量第1字节中的数据和数据存储类型的对应关系