《MCS-51系列单片机原理及接口技术 第2版 教学课件 ppt 作者 邹振春 第八章C51语言程序设计》由会员分享,可在线阅读,更多相关《MCS-51系列单片机原理及接口技术 第2版 教学课件 ppt 作者 邹振春 第八章C51语言程序设计(48页珍藏版)》请在金锄头文库上搜索。
1、第八章 C51语言程序设计,8.1 C51语言程序设计,8.2 C51语言语法简介,8.3 基本程序设计,8.4 C51编程举例,8.1 C51语言简介,C51语言的优点:,1)对单片机的指令系统不要求了解,仅要求对单片机的存储器结构有初步了解。,2)寄存器分配、不同寄存器的寻址及数据类型等细节可由编译器管理。,3)程序有规范的结构,可分为不同的函数,可使程序结构化。,4)指定操作的变量选择组合,改善了程序的可读性。,5)关键字及运算函数可用近似人的思维过程方式使用。,6)编程及程序调试时间显著缩短,从而提高效率。,7)提供的库包含许多标准子程序,具有较强的数据处理能力。,8)已编好的程序可容
2、易地植入新程序,具有较强的模块化编程技术。,C51中函数分为两大类,一类是库函数,一类是用户定义函数。库函数是C51在库文件中已经定义的函数,其函数说明在相关的头文件中。这类函数,用户在编程时只要用include预处理指令将头文件包含在用户文件中,直接调用即可。外部函数是用户自己定义、自己调用的一类函数。,C51程序的一般格式如下: 类型 函数名(参数表) 参数说明; 数据定义部分; 执行语句部分; ,例8-1:用8279芯片实现键盘和显示功能,数据口地址 0xfffe,命令/状态口地址 0xffff 。,#include /*库函数 */ #include /*库函数*/ #define C
3、OM XBYTE0xffff /*定义8279的命令地址 */ #define DAT XBYTE0xfffe /*定义8279的数据地址 */ sbit clr_flag; unsigned char keyin(); /*用户函数名称类型声明*/ void display(unsigned char idata *d) void main(void) /*主函数*/ ,COM=0xd1; /*对8279总清*/ doACC=COM; while(clr_flag=1); COM=00; /* 8279初始化命令 */ COM=0x2a; void display(unsigned char
4、 idata *d) /*显示函数函数体略 */ /* 按键函数略 */,返回,8.2 C51语言语法简介,8.2.1数据与数据类型,C51语言按照ANSI C的标准来定义,它的数据也基本遵从标准C的数据结构,C51的数据结构是以数据类型的形式出现的。,为了支持8051结构,提供了几种标准C的扩展,这些扩展符有: bit、str、sbit、str16等。,C51的C语言的数据类型如下: 位型(bit) 字符型(char) 基本类型 整形(int) 长整形(long) 浮点型(float) 数组类型(array) 数据类型 结构体类型(struct) 构造类型 共用体(union) 枚举(enu
5、m) 指针类型 空类型,keil C51编译器支持的数据类型、长度和数域,8.2.2 C51数据的存储类型与8051存储器结构定义,8051单片机系统,C51存储类型定义,C51数据类型定义举例,char data day; /字节型变量,定位在直接寻址片内数据存储器,bit bdata flag; /位型变量,定位在可位寻址片内数据存储器,float idata x,y,z; /浮点型变量,定位在间接寻址片内数据存储器,unsigned char xdata vector10; /无符号数字节变量,定位在片外数据存储器,unsigned int pdata result; /无符号数字节变量
6、,定位在片外数据存储器,8.2.3 特殊功能寄存器及C51定义,C51语言中为了访问51单片机的特殊功能寄存器(SFR),定义了关键字”sfr”等来描述SFR。,sbit:定义可位寻址的特殊功能寄存器和可位寻址的某些特殊位。,这种变量的定义有3种形式,分别如下:,sfr_nameint_constant,该变量用一个已定义的sfr_name作为sbit的基地址,“”后面的表达式指定了位的位置,且必须是07之间的一个数字。,例:sbit CY=PSW7;,int_constantint_constant,这种方法以一个整常数作为基地址,该值必须在0x800xFF之间,并能被8整除,确定位置的方法
7、同上。,例:sbit CY=0xD07;,int_constant,这种方法将位的绝对地址赋给变量,寄存器地址必须在0x800xFF之间。,例:sbit CY=0xD7;,8.2.4 C51的运算符及其表达式, C51最基本的算术运算符有五种 :加法运算符,或正值符号; :减法运算符,或负值符号; * :乘法运算符; / :除法运算符; :模(求余)运算符。,算术表达式、优先级和结合性 算术表达式就是用算术运算符和括号将运算对象连接起来的式子。例如: a+b; a+(b-c*d)%3; C51的算术运算符的优先级和标准C的算术运算符的优先级一致,即先乘除模,后加减,括号最优先。 算术运算符的结
8、合性规定为自左至右方向,又称为“左结合性”,,强制类型转换运算符() 在C51的运算表达式中当一个运算符的两侧的数据类型不同,则必须通过数据类型转换将数据转换成同种类型。转换的方式有两种:自动类型转换,强制类型转换。, C51的关系运算符及优先级 C51共有6种关系运算符 : 大于 =: 大于或等于 =: 测试等于 !=: 测试不等于,关系运算符的优先级 、= 四种关系运算符的优先级相同,=、!= 两种关系运算符的优先级也相同;但前四种运算符优先级高于后两种。 关系运算符的优先级低于算术运算符的优先级。 关系运算符的优先级高于赋值运算符的优先级。, C51的逻辑运算符 C51共有3种逻辑运算符
9、: &:逻辑与; |:逻辑或; !:逻辑非。, C51的位操作运算符 C51提供了如下的位操作运算符: &: 按位与; |:按位或; :按位异或; :按位取反; :位右移,8.2.5 C51的专用函数,对于一些简单的操作,编译器提供了一些专用函数供用户使用,许多专用函数直接对应着汇编指令,而另外一些比较复杂并兼容ANSI。,空操作指令 _nop_()是和汇编指令集中的NOP指令相对应的专用指令,在执行时执行一个指令周期的空操作。,变量循环位移指令 和汇编指令集中单字节循环位移指令RL A、RR A 相对应的专用指令是_crol_(变量,循环次数) 、_cror_(变量,循环次数)。对于int类
10、型的专用指令为_irol_、_iror_,对于long类型调令为_lrol_、_lror_。,判位转移指令 在C51中也提供了像汇编中JBC指令那样的专用指令_testbit_。如果参数位置位将返回1,否则将返回0。这条专用指令在检查标志位时十分有用,而且使C51的代码更具有可读性。,#include #include char test; void seial_intr(void) interrupt 4 if(_testbit_(TI) /是否是发送中断 P1=1;/ 翻转P1.0 _nop_();/等待一个指令周期 P1=0; else if (_testbit_(RI) /是否是接收中
11、断 test=_cror_(SBUF, 1); / 将SBUF中的数据循环 右移一位 ,8.2.6 C51的函数,函数的定义 keil C51编译器扩展了标准C函数声明,这些扩展有: 指定一个函数为中断函数 选择函数所用的寄存器组 选择存储模式 指定重入 指定ALIEN PL/M51函数 在函数声明中可以包含这些扩展或属性,C51函数的标准格式如下: return_typefuncname(args)small|compact|large reentrantinterrupt nusing n return_type:函数返回值的类型,如果不指定缺省是int。 funcname:函数名。 ar
12、gs:函数的参数列表。 small、compact或large:函数的存储模式。 reentrant:表示函数是递归或可重入的。 interrupt n:表示是一个中断函数。 using n:指定函数所用的寄存器组。,函数的存储模式,函数的参数和局部变量保存在由存储模式指定的缺省存储空间中,C51编译器规定了一个函数可以在函数中用small、compact或large来指定存储模式,small模式 所有局部变量和函数参数都保存在8051的可直接寻址的内部RAM中。,compact模式 所有局部变量和函数参数都保存在外部数据存储器的一页中,large模式 所有局部变量和函数参数都保存在外部的数据
13、存储器中,中断函数,C51编译器最多支持32个中断函数,用下表的中断号决定向量地址。,interrupt函数属性指定函数为一个中断函数,中断函数的具体形式如下:,void funcname(args) interrupt n using n,例如假设单片机的晶振为12MHz,用定时器0在P1.1口输出一个周期为2ms的方波,则中断服务程序为 :,void timer0(void) interrupt 1 using 2 TH0=0xFF-(1000/256); TL0=0xFF-(1000%256); P1_1=!P1_1; ,中断函数的使用规则:,中断函数没有函数参数。如果中断函数声明中带参
14、数,编译器就产生错误信息。,中断函数声明中不能包含返回值,必须声明为void。如果定义了一个返回值,编译器就产生一个错误。,从一个中断程序中调用函数,必须和中断使用相同的寄存器组,指定一个函数的寄存器组,8051系列单片机的最低32个字节分成4组8寄存器组,作为寄存器R0到R7访问。当前所使用的寄存器组由PSW的两位决定。,我们在处理中断或使用一个实时操作系统时寄存器组非常有用,为了在执行新的任务时,还保留原有的寄存器组的内容,可进行寄存器组的切换。C51编译器提供了进行寄存器组切换的using函数属性来指定函数所用的寄存器组。,注意: using属性不能用在用寄存器返回一个值的函数中,必须确
15、保寄存器组切换在可控范围内,否则可能产生错误。 using属性在interrupt函数中最有用。通常对每个中断优先级指定一个不同的寄存器组,即可分配一个寄存器组对应所有非中断代码,另一个寄存器组为高级中断的寄存器组,第三个为低级中断的寄存器组。,8.2.7 C51的绝对地址访问,C51提供了绝对宏、连接器定位控制和_at_关键字等3种访问绝对地址的方法。,绝对宏,在C51的库函数中有一个absacc.h的库函数,在这个库函数中声明了用来访问绝对地址的宏,如CBYTE、XBYTE、PWORD、DBYTE、CWORD、XWORD、PBYTE、DWORD等,具体的声明和使用方法请参考absacc.h
16、。例如:,ya_data=XBYTE0xfff0; /指向外部数据存储器或外设端口地址0xfff0 ya_dot=CWORD0x0002; /指向程序存储器的0004地址,返回,_at_关键字,在C51程序中用_at_关键字,变量可以定位在绝对存储地址。用法如下: type memory_space variable_name _at_constant;,memory_space:变量的存储空间。 type:变量类型。 variable_name:变量名。 constant:定位变量的地址。,例如: char xdata text256 _at_ 0xE000; int xdata i1 _at_ 0x9000;,8.3