关于C语言的简介
C语言程序采用函数结构,每个C语言程序都由一个或多个函数组成,在这些函数中至少应包含一个主函数main(),与若干个其他功能的函数,不管main()函数放于何处,程序总是从main()开始执行,执行到main()函数结束则结束,在main()函数中调用其他函数,其他函数也可以互相调用,main()函数只能调用其他的功能函数,而不能被其他的函数所调用,功能函数可以是C语言编译器提供的库函数,也可以是由用户定义的自定义函数,在编制C程序时,程序开始部分一般是预处理命令,函数说明和变量定义
在C语言编程中,对数据类型与变量的定义,必须要与单片机的存储结构相关联,否则编译器不能正确的映射定位。
用C语言编写单片机应用程序与标准的C语言程序也有相应的区别:C语言编写单片机应用程序时,需要根据单片机存储结构与内部资源定义相关的数据类型和变量,而标准的C语言程序不需要考虑这些问题
C51包含的数据类型,变量存储模式输入输出处理,函数等方面与标准的C语言有一定的区别,其他的语法规则,程序设计与程序设计方法等与标准的C语言程序设计相同
C51与C的区别
C51的语法规定,程序结构与程序设计方法都与标准的C语言程序设计相同,但C51程序与标准的C程序在以下几个方面不一样:
(1) C51中定义的库函数和标准C语言定义的库函数不同,标准的C语言定义的库函数是按照通用微型计算机来定义的,而C51中的库函数是按51单片机的相应情况来定义的;
(2)C51中的数据类型与标准的C的数据类型也有一定的区别,在C51中还增加了几种针对51单片机的特有的数据类型;
(3)C51变量的存储模式与标准C中的变量的存储模式不一样,在C51中变量的存储模式是与51单片机的存储器紧密相关;
(4)C51与标准C的输入输出处理不一样,C51中的输入输出是通过51串行口来完成的,输入输出指令执行前必须对串行口进行初始化;
(5)C51与标准C在函数使用方面也有一定的区别,C51有专门的中断函数
C51的数据类型分为基本数据类型和组合数据类型,
*指针型:指针型本身就是一个变量,在这个变量中存放的指向另一个数据的地址,这个指针变量要占用一定的内存单元,对于不同的处理器长度不一样,在C51中长度一般为1~3字节
特殊功能寄存器型:
这是C51的扩充数据类型,用于访问51单片机中的特殊功能寄存器数据,分为sfr和sfr16两种类型,其中sfr为字节型特殊功能寄存器类型,占一个内存单元,利用它可以访问51内部所有的特殊功能寄存器;sfr16为双字节型特殊功能寄存器类型,占两个字节单元,利用它可以访问51内部的所有两个字节的特殊功能寄存器,在C51中对特殊功能寄存器访问必须先用sfr或sfr16进行声明
位类型:
这也是C51扩充的数据类型,用于访问51单片机中的可寻址的位单元,在C51中支持两种位类型:bit型和sbit型,它们在内存中都只占一个二进制位,其中:用bit定义的位变量在C51编译器中编译时,在不同的位置位地址可以变化,而用sbit定义的位变量必须与51单片机的一个可以寻址位单元或可位寻址的字节单元中的其中某一位联系在一起,在C51编译时,其对应的位地址是不可变化的
C51运算量
常量
整型常量:十进制整数,十六进制整数(以0x开头)
长整数:在C51中当一个整数的值达到长整数的范围,则该数按长整数型存放,在存储器中占四个字节
浮点型常量:也就是实型常数,有十进制表示形式和指数表示形式,十进制表示形式又被称为定点表示形式,由数字和小数点组成,
字符型常量:字符型常量是用单引号引起的字符,如‘s’,‘b’,‘1’
字符串常量:是由双引号 “ ” 括起的字符组成,如“D”,“1234”, 一个字符常量在计算机内只用一个字节存放,而一个字符串常量在内存中存放时不仅仅双括号内的字符一个占一个字节,而且系统会自动在后面加一个转义字符“”\0”作为字符串结束符,因而这两个是不一样的,如‘A’和“A” 是不一样的
变量
在程序运行过程中值可以改变的量,一个变量可以由两部分组成:变量名和变量值,在C51中,变量在使用前必须对变量进行定义,指出变量的数据类型和存储模式,以便编译系统分配相应的存储单元,定义的格式如下:【存储种类】 数据类型说明符 【存储器类型】变量名1【=初值】,变量名2【初值】
数据类型说明符
在定义变量时,必须通过数据类型说明符指明变量的数据类型,指明变量在存储器中占用的字节数,可以是基本数据类型说明符,也可以是组合数据类型说明符,还可以是用typedef 定义的类型别名
在C51中,为了增加程序的可读性,允许用户为系统固有的数据类型说明符
用 typedef 起别名,格式如下:
typedef c51 固有的数据类型说明符 别名;
typedef unsigned int uint;
typedef unsigned char uchar;
存储种类
C51变量的存储种类有四种:自动(auto),外部(extern),静态(static)和寄存器(register)
auto:使用auto定义的变量称为自动变量,其作用范围在定义它的函数体或复合语句内部,当定义它的函数体或复合语句执行时,C51 才为该变量分配内存空间,结束时占用的内存空间释放。自动变量一般分配在内存的堆栈空间中。定义变量时,如果省略存储种类,则该变量默认为自动(auto)变量。
extern:使用extern 定义的变量称为外部变量,在一个函数体内,要使用一个已在该函数体外或别的程序中定义的外部变量时,该变量在该函数体内要用extern 说明,外部变量被定义后分配固定的内存空间,在程序整个执行时间内都有效,直到程序结束才释放
static:使用static定义的变量称为静态变量,分为内部静态变量和外部静态变量,在函数体内部定义的静态变量为内部静态变量,它在对应的函数体内有效,一直存在,但在函数体外不可见,这样不仅使变量在定义它的函数体外被保护,还可以实现当离开函数时值不被改变。外部静态变量上在函数外部定义的静态变量。它在程序中一直存在,但在定义的范围之外是不可见的。如在多文件或多模块处理中,外部静态变量只在文件内部或模块内部有效。
register:使用 register 定义的变量称为寄存器变量。它定义的变量存放在 CPU 内部的寄存器中,处理速度快,但数目少。C51 编译器编译时能自动识别程序中使用频率最高的变量,并自动将其作为寄存器变量,用户可以无需专门声明。
存储器类型
存储器类型是用于指明变量所处的单片机的存储器区域情况,C51编译器能识别的存储器的类型有以下几种
位变量
在C51中,允许用户通过位类型符定义为位变量,位类型符有两个:bit和sbit,可以定义两种位变量
bit 位类型用于定义一般的可位处理位变量,格式:bit 位变量名
在格式中可以加上各种修饰,但注意存储器类型只能是 bdata、data、idata。
只能是片内 RAM 的可位寻址区,严格来说只能是 bdata。
sbit 位类型符用于定义在可寻址字节或特殊功能寄存器中的位,定义时必须指明其位地址,可以是位直接地址,可以是可位寻址变量带位号,也可以是特殊功能寄存器名带位号
格式如下:sbit 位变量名=位地址
关于code 关键字
为51特有,有一种数据,我们要在程序中使用,但是却不会改变它的值,定义这种数据时可以加一个code 关键字进行修饰,这个数据就会存储到我们的程序空间flash中,这样可以大大节省单片机的RAM使用量,因为单片机的RAM空间比较小,而程序空间大的多,如我们现在要使用的数码管真值表,我们只会使用它们的值,而不需要改变它们,就可以用code 关键字把它放入flash 中
Keil C51 语言中的关键字,代表了RAM的不同区域的划分
data:片内RAM 从0x00~0x7f
idata:片内RAM 从0x~0xFF
pdata: 片外RAM 从0x00~0xFF
xdata: 片外RAM 从0x0000~0xFFFF
在keil 默认设置下,data 是可以省略的,即什么都不加的时候变量就是定义到data 区域中的
data 区域RAM的访问在汇编语言中用得是直接寻址,执行速度是最快的,如果定义成idata,不仅仅可以访问 Data 区域,还可以访问0x80H-0XFF的范围,但加了idata 关键字后,访问的时候51 单片机用的是通用寄存器间接寻址,速度较data 会慢一些
对于外部 RAM 来说,使用 pdata 定义的变量存到了外部 RAM 的 0x00~0xFF 的地址范围内,这块地址的访问和 idata 类似,都是用通用寄存器间接寻址,而如果你定义成 xdata,
可以访问的范围更广泛,从以访问的范围更广泛,从 0 到 64K 的地址都可以访问到,但是它需要使用 2 个字节寄存器DPTRH 和 DPTRL 来进行间接寻址,速度是最慢的。
函数
函数定义的一般格式如下:
函数类型 函数名(形式参数表) 【reetrant】【interrupt m】
函数类型:说明了函数返回值的类型
函数名:用户为自定义的函数取的名字以便调用函数时使用
形式参数表:用于列录在主调函数与被调用函数之间进行数据传递的形式参数
reentrant :修饰符
用于把函数定义为可重入函数,所谓可重入函数就是允许被递归调用的函数,函数的递归调用是指当一个函数正被调用而尚未返回时,又直接或间接调用函数本身,只有重入函数才允许递归调用
注意点:
1,用reentrant修饰的重入函数被调用时,实参表内不允许使用bit 类型的参数,函数体内也不允许存在任何关于位变量的操作,更不能返回bit 类型的值
2,编译时,系统为重入函数在内部或外部存储区建立一个模拟堆栈区,称为重入栈,重入函数的局部变量及参数被放在重入栈中,使重入函数可以实现递归调用
3,在参数传递上,实际参数可以传递给间接调用的重入函数,无重入属性的间接调用函数不能包含调用参数,但可以使用定义的全局变量来进行参数传递
interrupt m 修饰符
是C51中非常重要的一个修饰符,中断函数必须通过它进行修饰,在·C51程序设计中,当函数定义时用了interrupt m 修饰符,系统编译时把对应函数转化为中断函数,自动加上程序头段和尾段,并按51系统中断的处理方式自动把它安排在程序存储器中相应的位置,在该修饰符中,m的取值为0~31,对应的中断情况如下:
0-外部中断0
1-定时、计数器T0
2-外部中断1
3-定时、计数器T1
4-串行口中断
5-定时、计数器T2
后续还有数组,指针等的内容,暂时未介绍到,也是自己在逐步的学习