微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 51单片机基础剖析(基于C语言)

51单片机基础剖析(基于C语言)

时间:11-20 来源:互联网 点击:

过灵活运用不同的数据类型,所有的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 //init_mempool()、malloc()、free()函数所在的头文件

……

void main (void)

{

char *ptr1;

init_mempool (0x1000,0x500); //内存池初始化,0x1000为起始地址,0x500为内存大小

ptr1=malloc(30); /*动态为指针变量分配长度为30字节的存储空间*/

……

//此

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top