51单片机基础剖析(基于C语言)
过灵活运用不同的数据类型,所有的8051地址空间都是可以进行访问。例如:
DWORD[0x0004]=0x12F8;// 即内部数据存储器中(0x08)=0x12; (0x09)=0xF8
注:用以上八个函数,可以完成对单片机内部任意ROM和RAM进行访问,非常方便。还有一种方法,那就是用指钟,后面会对C51的指针有详细的介绍。
4.寄存器变量(register)
为了提高程序的执行效率,C语言允许将一些频率最高的那些变量,定义为能够直接使用硬件寄存器的所谓的寄存器变量。定义一个变量时,在变量类型名前冠以“register” 即将该变量定义成为了寄存器变量。寄存器变量可以认为是一自动变量的一种。有效作用范围也自动变量相同。由于计算机寄存器中寄存器是有限的。不能将所有变量都定义成为寄存器变量,通常在程序中定义寄存器变量时,只是给编译器一个建议,该变量是否真正成为寄存器变量,要由编译器根据实际情况来确定。另一方面,C51编译器能够识别程序中使用频率最高的变量,在可能的情况下,即使程序中并未将该变量定义为寄存器变量,编译器也会自动将其作为寄存器变量处理。被定义的变量是否真正能成为寄存器变量,最终是由编译器决定的。
5.内存访问的实现
(1)指钟
指钟本身是一个变量,其中存放的内容是变量的地址,也即特定的数据。8051的地址是16位的,所以指针变量本身占用两个存储单元。指针的说明与变量的说明类似,仅在指针名前加上“*”即可。
如: int *int_point; //声明一个整型指针
char *char_point; //声明一个字符型指针
利用指针可以间接存取变量。实现这一点要用到两个特殊运算符
& 取变量地址
* 取指针指向单元的数据
示例一:
int a=15,b;
int *int_point; //定义一个指向整型变量的指针
int_point=&a; //int_point指向 a
*int_point=5; //给int_point指向的变量a 赋值5 等同于a=5;
示例二:
char i,table[6],*char_point;
char_point=table;
for(i=0;i<6;i++)
{
char_point=i;
char_point++;
}
注:指针可以进行运算,它可以与整数进行加减运算(移动指针)。但要注意,移动指针后,其地址的增减量是随指针类型而异的,如,浮点指针进行自增后,其内部将在原有的基础上加4,而字符指针当进生自增的时候,其内容将加1。原因是浮点数,占4个内存单元,而字符占一个字节。
宏晶科技最新一代STC12C5A360S2系列,每一个单片机出厂时都有全球唯一身份证号码(ID号),用户可以在单片机上电后读取内部RAM单元F1H~F7H的数值,来获取此单片机的唯一身份证号码。使用MOV @Ri指令来读取。下面介绍C51获取方法:
char id[7]={0};
char i;
char idata *point;
for(i=0;i<7;i++)
{
id[i]=*point;
point++;
}
(此处只是对指针做一个小的介绍,达到访问内部任何空间的方式,后述有对指针使用的详细介绍)
(2)对SFR,RAM ,ROM的直接存取
C51提供了一组可以直接对其操作的扩展函数
若源程序中,用#include包含头文件,io51.h 后,就可以在扩展函数中使用特殊功能寄存器的地址名,以增强程序的可读性:
注 此方法对SFR,RAM,ROM的直接存取不建议使用.因为,淡io51.h这个头文件在KEIL中无法打开,可用指针,或是采用absacc.h头文件,
(3) PWM与PCA
STC12系列有两路PWM/PCA
PWM:(Pulse Width Modulation)脉宽调制,是一种使用程序来控制波形占空比,周期,相位波形的技术。
PCA:(Programmable Counter Array)可编程计数阵列,它比通常的定时/计数器的定时能力强,需要CPU的干预少。其优势一是软件简单,二是精度大有提高。
*6.动态内存分配的实现
在单片机的实际开发中,很多情况下我么需要开辟一块内存,但是具体开辟多大,也就是内存的字节数我们还无法确定,比如可能要等到上位机的指令发送下来才能确定,这个时候我们就得动态分配内存。注意,单片机内部存储资源是极其有限的,不允许开发人员开辟出一块很大的存储区来备用。在VC 6.0环境下很容易用malloc()来得到一块RAM,但是由于单片机内部没有操作系统(如何在51上跑uC/OS-II我以后会写出来),所以在51上实现动态内存分配就是个难点也是一个重点问题。下面给出代码,详细分析大家可以参考求是科技编的《8051系列单片机C程序设计完全手册》这本书。
#include
#include
……
void main (void)
{
char *ptr1;
init_mempool (0x1000,0x500); //内存池初始化,0x1000为起始地址,0x500为内存大小
ptr1=malloc(30); /*动态为指针变量分配长度为30字节的存储空间*/
……
//此
51单片机C语 相关文章:
- Proteus运行Keil编写的51单片机C语言步骤(11-30)
- 《世上只有妈妈好》51单片机C语言程序(11-26)
- 51单片机C语言编程中对单片机绝对地址访问的两种方法(11-26)
- 硬件仿真器会不会被淘汰(11-26)
- 51单片机C语言头文件及其使用(11-26)
- 51单片机的C语言延时的一些总结(11-25)