《MCS-51系列单片机原理及接口技术》8 C51语言程序设计.ppt_第1页
《MCS-51系列单片机原理及接口技术》8 C51语言程序设计.ppt_第2页
《MCS-51系列单片机原理及接口技术》8 C51语言程序设计.ppt_第3页
《MCS-51系列单片机原理及接口技术》8 C51语言程序设计.ppt_第4页
《MCS-51系列单片机原理及接口技术》8 C51语言程序设计.ppt_第5页
已阅读5页,还剩43页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

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芯片实现键盘和显示功能,数据口地址 0 xfffe,命令/状态口地址 0 xffff,include /*库函数 */ #include /*库函数*/ #define COM XBYTE0 xf

3、fff /*定义8279的命令地址 */ #define DAT XBYTE0 xfffe /*定义8279的数据地址 */ sbit clr_flag; unsigned char keyin(); /*用户函数名称类型声明*/ void display(unsigned char idata *d) void main(void) /*主函数*/,COM=0 xd1;/*对8279总清*/ doACC=COM; while(clr_flag=1); COM=00;/* 8279初始化命令 */ COM=0 x2a; void display(unsigned char idata *d)

4、/*显示函数函数体略 */ /* 按键函数略 *,返回,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) 枚举(enum) 指针类型 空类型,ke

5、il 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; /无符号数字节变量,定位在片外数据存储器,8.

6、2.3 特殊功能寄存器及C51定义,C51语言中为了访问51单片机的特殊功能寄存器(SFR),定义了关键字”sfr”等来描述SFR,sbit:定义可位寻址的特殊功能寄存器和可位寻址的某些特殊位,这种变量的定义有3种形式,分别如下,sfr_nameint_constant,该变量用一个已定义的sfr_name作为sbit的基地址,“”后面的表达式指定了位的位置,且必须是07之间的一个数字,例:sbit CY=PSW7,int_constantint_constant,这种方法以一个整常数作为基地址,该值必须在0 x800 xFF之间,并能被8整除,确定位置的方法同上,例:sbit CY=0 xD

7、07,int_constant,这种方法将位的绝对地址赋给变量,寄存器地址必须在0 x800 xFF之间,例:sbit CY=0 xD7,8.2.4 C51的运算符及其表达式,C51最基本的算术运算符有五种 :加法运算符,或正值符号; :减法运算符,或负值符号; * :乘法运算符; / :除法运算符; :模(求余)运算符,算术表达式、优先级和结合性 算术表达式就是用算术运算符和括号将运算对象连接起来的式子。例如: a+b; a+(b-c*d)%3; C51的算术运算符的优先级和标准C的算术运算符的优先级一致,即先乘除模,后加减,括号最优先。 算术运算符的结合性规定为自左至右方向,又称为“左结合

8、性,强制类型转换运算符() 在C51的运算表达式中当一个运算符的两侧的数据类型不同,则必须通过数据类型转换将数据转换成同种类型。转换的方式有两种:自动类型转换,强制类型转换,C51的关系运算符及优先级 C51共有6种关系运算符 : 大于 =: 大于或等于 =: 测试等于 !=: 测试不等于,关系运算符的优先级 、= 四种关系运算符的优先级相同,=、!= 两种关系运算符的优先级也相同;但前四种运算符优先级高于后两种。 关系运算符的优先级低于算术运算符的优先级。 关系运算符的优先级高于赋值运算符的优先级,C51的逻辑运算符 C51共有3种逻辑运算符: void seial_intr(void) i

9、nterrupt 4 if(_testbit_(TI) /是否是发送中断 P1=1;/ 翻转P1.0 _nop_();/等待一个指令周期 P1=0; else if (_testbit_(RI) /是否是接收中断 test=_cror_(SBUF, 1); / 将SBUF中的数据循环 右移一位,8.2.6 C51的函数,函数的定义 keil C51编译器扩展了标准C函数声明,这些扩展有: 指定一个函数为中断函数 选择函数所用的寄存器组 选择存储模式 指定重入 指定ALIEN PL/M51函数 在函数声明中可以包含这些扩展或属性,C51函数的标准格式如下: return_typefuncname

10、(args)small|compact|large reentrantinterrupt nusing n return_type:函数返回值的类型,如果不指定缺省是int。 funcname:函数名。 args:函数的参数列表。 small、compact或large:函数的存储模式。 reentrant:表示函数是递归或可重入的。 interrupt n:表示是一个中断函数。 using n:指定函数所用的寄存器组,函数的存储模式,函数的参数和局部变量保存在由存储模式指定的缺省存储空间中,C51编译器规定了一个函数可以在函数中用small、compact或large来指定存储模式,smal

11、l模式 所有局部变量和函数参数都保存在8051的可直接寻址的内部RAM中,compact模式 所有局部变量和函数参数都保存在外部数据存储器的一页中,large模式 所有局部变量和函数参数都保存在外部的数据存储器中,中断函数,C51编译器最多支持32个中断函数,用下表的中断号决定向量地址,interrupt函数属性指定函数为一个中断函数,中断函数的具体形式如下,void funcname(args) interrupt n using n,例如假设单片机的晶振为12MHz,用定时器0在P1.1口输出一个周期为2ms的方波,则中断服务程序为,void timer0(void) interrupt

12、1 using 2 TH0=0 xFF-(1000/256); TL0=0 xFF-(1000%256); P1_1=!P1_1;,中断函数的使用规则,中断函数没有函数参数。如果中断函数声明中带参数,编译器就产生错误信息,中断函数声明中不能包含返回值,必须声明为void。如果定义了一个返回值,编译器就产生一个错误,从一个中断程序中调用函数,必须和中断使用相同的寄存器组,指定一个函数的寄存器组,8051系列单片机的最低32个字节分成4组8寄存器组,作为寄存器R0到R7访问。当前所使用的寄存器组由PSW的两位决定,我们在处理中断或使用一个实时操作系统时寄存器组非常有用,为了在执行新的任务时,还保留

13、原有的寄存器组的内容,可进行寄存器组的切换。C51编译器提供了进行寄存器组切换的using函数属性来指定函数所用的寄存器组,注意: using属性不能用在用寄存器返回一个值的函数中,必须确保寄存器组切换在可控范围内,否则可能产生错误。 using属性在interrupt函数中最有用。通常对每个中断优先级指定一个不同的寄存器组,即可分配一个寄存器组对应所有非中断代码,另一个寄存器组为高级中断的寄存器组,第三个为低级中断的寄存器组,8.2.7 C51的绝对地址访问,C51提供了绝对宏、连接器定位控制和_at_关键字等3种访问绝对地址的方法,绝对宏,在C51的库函数中有一个absacc.h的库函数,

14、在这个库函数中声明了用来访问绝对地址的宏,如CBYTE、XBYTE、PWORD、DBYTE、CWORD、XWORD、PBYTE、DWORD等,具体的声明和使用方法请参考absacc.h。例如,ya_data=XBYTE0 xfff0; /指向外部数据存储器或外设端口地址0 xfff0 ya_dot=CWORD0 x0002; /指向程序存储器的0004地址,返回,_at_关键字,在C51程序中用_at_关键字,变量可以定位在绝对存储地址。用法如下: type memory_space variable_name _at_constant,memory_space:变量的存储空间。 type:变

15、量类型。 variable_name:变量名。 constant:定位变量的地址,例如: char xdata text256 _at_ 0 xE000; int xdata i1 _at_ 0 x9000,8.3 基本程序设计,C51的程序设计对于比较复杂的问题应该经过以下几个步骤,根据设计题目的要求确定数学模型和算法。 给出流程图。 根据流程图设计程序,常用的程序结构,顺序结构,分支结构,循环结构,函数调用,8. 顺序结构程序,顺序程序也称为简单程序,这样的程序在执行时是从第一条语句开始依次执行每一条指令,直至执行完毕,语句,例8-3:将一个片内数据存储器存储的单字节压缩BCD码,转换为相

16、应的ASCII码,存入到双字节的数据存储器中,分析:首先应将单字节压缩BCD码拆成两个半字节,然后将半字节的高4位或上3即可完成。参考程序如下,unsigned char data BCD_num;/ 单字节BCD码存放单元 unsigned char data ASC_num2; / 双字节ASC码存放单元 void BCD_ASC(void) ASC_num1=BCD_num/0 x10;/高位BCD码送高位ASC码单元 ASC_num0=BCD_num%0 x10; /低位BCD码送低位ASC码单元 ASC_num0|=0 x30;/完成低位转换成ASCII码 ASC_num1|=0 x

17、30;/完成高位转换成ASCII码,例8-4:将一个四位压缩BCD码BCD_num拆开成四位BCD码,并存放到FIRST(千位)、SECO(百位)、THIR(十位)、FOUR(个位)这四个字节单元中。这种问题经常在显示时用到,分析:首先将原数除以1000,得到千位数;再将余数除以100,得到百位数;然后再将余数除以10,得到十位数;最后得到的余数就是个位数。参考程序如下,unsigned int data BCD_num;/双字节BCD码存放单元 unsigned char data FIRST,SECO,THIR,FOUR; void BCD_decompose(void) unsigned

18、 int data temp; FIRST=(unsigned char)(BCD_num/1000); temp=BCD_num%1000;/得到除以1000的余数 SECO=(unsigned char)(temp/100); temp=temp%100;/得到除以100的余数 THIR=(unsigned char)(temp/10); FOUR=temp%10;/得到除以10的余数,8. 分支结构程序,分支结构程序就是条件判断分支程序,即根据不同的条件,执行不同的程序段。在C51中,可以采用if-else if嵌套语句,或switch语句,例8-5:设变量X存放在VAR单元,函数值将存

19、放在FUNC单元,试按照下式编写程序,char data VAR; char data FUNC; char fun(char dat) if(dat0)return(1); else if(dat0)return(-1); else return(0); /主程序 FUNC=fun(VAR);,分析:可以采用if-else if嵌套语句。参考程序如下,例8-6:P1口的低四位分别各接一个按键开关,且低电平有效,当仅有一个按键按下时,P3口的低四位采用采用编码输出,具体的对应关系见下表,否则P3口的低四位输出全1,分析:可以采用switch语句。参考程序如下,void key(void) P1

20、|=0 x0f;P1口置高,准备读入P1口的低四位状态 switch(P1/否则输出全1,8.3.3 循环结构程序,在程序设计中,常会遇到同样一组操作要重复许多次,在C51中,可以使用for语句来实现循环控制,例8-7:从BLOCK单元开始存放一组无符号数,数据块的长度存放在LEN单元,编写一个求和程序,并将和存入SUM单元,设和不超过16位二进制数,分析:可以采用for循环语句。参考程序如下,unsigned char data LEN, BLOCK; unsigned int data SUM; void SUM_program(unsigned char *BLOCK,unsigned

21、char LEN) unsigned char data i; for(i=0;iLEN;i+) SUM+=BLOCKi; /主程序 SUM_program(BLOCK,LEN);,8.3.4 函数调用,函数是独立于主函数(main函数)并能完成特定功能,能够被主函数或其它函数调用,又能返回主函数或其它被调用的函数。在C51中的函数调用就相当于51汇编中的LCALL或ACALL调用。另外,在C51中函数的原型既可以有入口参数,也可以有返回参数,因此可以使用带参数传递的函数实现参数的传递,见例8-1例程,将程序分解成了三个模块,即主程序模块、显示程序模块、检测按键和获取键值模块,显示模块通过入口

22、参数获取显示数值,而检测按键模块和获取键值模块则通过函数返回值的形式将信息传递给调用者,返回,8.3.4 函数调用,函数是独立于主函数(main函数)并能完成特定功能,能够被主函数或其它函数调用,又能返回主函数或其它被调用的函数。在C51中的函数调用就相当于51汇编中的LCALL或ACALL调用。另外,在C51中函数的原型既可以有入口参数,也可以有返回参数,因此可以使用带参数传递的函数实现参数的传递,见例8-1例程,将程序分解成了三个模块,即主程序模块、显示程序模块、检测按键和获取键值模块,显示模块通过入口参数获取显示数值,而检测按键模块和获取键值模块则通过函数返回值的形式将信息传递给调用者,

23、8.4 C51编程举例,本节内容将以一个简化的工程实例较为详细地介绍如何用C51实现该系统的软件开发,现有一个温度采集系统设计任务,温度采样路数为4路,测量温度范围为0100,精度为1;系统通过44键盘实现系统的功能和参数设定,由LED显示器进行显示;并要求用RS232方式实现数据的传输,8.4.1 键盘显示电路的软件设计,图8-1是8031、8279与键盘和显示器的接口电路。当有按键按下时,8279用申请外部中断0的方式通知8031,并通过四位LED七段数码管实现设定和当前采样信息的显示,图8-1 8279与8031的接口电路,由接口电路,可以得到8279的端口地址为: 命令/状态口: 0

24、xBFFF 数据口: 0 xBFFE 系统晶振为11.0592MHz,则ALE脚输出的频率为1.8432MHz,分频次数N=18。键盘显示系统的实现程序见例8-8,例8-8: #include /8031头文件 #include /绝对地址定义头文件 #define ORDER_8279 XBYTE0 xBFFF /8279的命令/状态口 #define DATA_8279 XBYTE0 xBFFE /8279的数据口 #define uint unsigned int #define uchar unsigned char /* 0F显示的段码表 */ uchar code table=0

25、x3f,0 x06,0 x5b,0 x4f,0 x66,0 x6d,0 x7d, 0 x07, 0 x7f,0 x6f,0 x77,0 x7c,0 x39,0 x5e,0 x79,0 x71; uchar key_data(void); /按键取值函数 void display(uchar idata *dat,* 主函数 */ void main(void) ORDER_8279=0 x00; /键盘、显示方式设置 ORDER_8279=0 x32; /时钟分频系数为18 IE=0 x91;/使能串口中断和INT0中断 /* 显示函数,入口为显示缓冲区首址 */ void display(u

26、char idata *disp_buff) uchar i; for(i=0;i8;i+) ORDER_8279=0 x80+i; DATA_8279=table*disp_buff; disp_buff+; /显示缓冲区地址加一,* 键盘中断函数 */ void service_int1(void) interrupt 0 using 1 ORDER_8279=0 x40;/允许读FIFO RAM keynum= DATA_8279;/读8279状态 keynum=keynum,8.4.2数据采集系统的软件设计,图8-2 ADC0809与8031的接口电路,按照图8-2的接法,ADC0809的模拟通道03的地址空间分别为:0 x78000 x78FF,0 x790079FF, 0 x7A000 x7AFF,0 x7B000 x7BFF。下面给出ADC0809一次完成4路数据采集的采样程序,程序见例8-9,例8-9: #include /8031头文件 #include /绝对地址定义头文件 #define IN_0 XBYTE0 x7800/ADC08

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论