《C51单片机的C语言程序设计.ppt》由会员分享,可在线阅读,更多相关《C51单片机的C语言程序设计.ppt(44页珍藏版)》请在三一办公上搜索。
1、2023/11/7,1,第10章 80C51的C语言程序设计,单片机C语言概述,10.1,C51的数据类型与运算,10.2,C51流程控制语句,10.3,C51的指针类型,10.4,C51的函数,10.5,C51编程实例,10.6,2023/11/7,2,10.1 单片机C语言概述,10.1.1 C51程序开发过程,编译器能自动完成变量的存储单元的分配 对常用功能模块和算法编制相应的函数,方便移植,采用C51的优点,C语言具有良好的可读性、可移植性和基本的硬件操作能力。,C51程序开发过程,编写源程序 建立工程,加入源程序 编译生产目标程序 仿真调试、写存储器,2023/11/7,3,2023
2、/11/7,4,10.1.2 C51程序结构,#include#include void delayms(unsigned);void main(void)unsigned char i;P1=0 x01;do for(i=0;i=7;i+)delayms(5000);P1=P11;if(P1=0 x0)P1=0 x01;while(1);,void delayms(unsigned x)unsigned char j;while(x-)for(j=0;j123;j+);,2023/11/7,5,10.2.1 C51的数据类型,10.2 C51的数据类型与运算,数据类型决定其取值范围、占用存储
3、器的大小及可参与哪种运算。,2023/11/7,6,尽可能采用无符号格式bit用于定义位变量的名字,编译器会对其分配地址(RAM的20H 2FH 区域)sbit用于定义位变量的名字和地址,地址是确定的且不用编译器分配(SFR及RAM的20H2FH 区域)C51编译器在编译时会自动进行类型转换,几点说明:,2023/11/7,7,10.2.2 C51数据的存储类型,C51的存储器类型,2023/11/7,8,经常使用的变量应该置于片内RAM中,要用bdata、data、idata来定义。不经常使用的变量或规模较大的变量应该置于片外RAM中,要用pdata、xdata来定义。默认存储器类型由编译控
4、制命令的存储模式指令限制。,2023/11/7,9,10.2.3 80C51硬件结构的C51定义,特殊功能寄存器的声明,sfr 特殊功能寄存器名=地址常数;,格式:,例如:sfr SCON=0 x98;sfr P0=0 x80;,2023/11/7,10,特殊功能寄存器中特定位的声明,sbit 位变量名=特殊功能寄存器名位的位置(07)例如:sfr PSW=0 xD0;sbit OV=PSW2;,sbit 位变量名=字节地址位的位置(07)例如:sbit OV=0 xD02;sbit CY=0 xD07;,sbit 位变量名=位地址 例如:sbit OV=0 xD2;sbit CY=0 xD7
5、;,2023/11/7,11,内部RAM中可位寻址对象的定义,先定义变量的数据类型和存储类型 例如:int bdata ibase;char bdata array4;,再利用sbit进行声明 例如:sbit mybit0=ibase0;sbit mybit15=ibase15;sbit ary07=array07;sbit ary37=array37;,访问示例:ibase=-1;array2=a;array2=0,2023/11/7,12,算术运算符和算术表达式,10.2.4 C51的运算符和表达式,基本算术运算符 例如:+加法运算符;-减法(取负)运算符;*乘法运算符;/除法运算符;%取
6、余数运算符。,示例:25.0/20.0=1.25 25/20=125%20=5,取负运算优先级最高。,2023/11/7,13,自增、自减运算符(仅能用于变量)例如:+自增运算符;-自减运算符;,类型转换运算符 自动转换,顺序:bitcharintlongfloat 强制类型转换,如:(double)a,2023/11/7,14,关系运算符和关系表达式,关系运算符 大于;=大于等于;=等于;!=不等于。,关系表达式关系表达式的值为逻辑值:真(1)和假(0),2023/11/7,15,逻辑运算符和逻辑表达式,逻辑运算符&逻辑与|逻辑或!逻辑非,逻辑表达式逻辑表达式的值为逻辑值:真(1)和假(0)
7、,例:5|0结果为1,2&0结果为0。,2023/11/7,16,位运算符,&按位与|按位或 按位异或 按位取反 右移,例:P1=P11表示对P1口的所有位左移1位,2023/11/7,17,赋值和复合赋值运算符,复合赋值运算符+=加法赋值;-=减法赋值;*=乘法赋值;/=除法赋值;%=取模赋值;,符号“=”称为赋值运算符,=右移位赋值;&=逻辑与赋值;|=逻辑或赋值;=逻辑异或赋值;=逻辑非赋值;,例:a*=5相当于a=a*5;b&=0 x80相当于b=b&0 x80。,2023/11/7,18,10.3 C51流程控制语句,10.3.1 C51选择语句,条件语句,if(条件表达式)语句 例
8、如:if(p1!=0)c=20;,if(条件表达式)语句1 else 语句2 例如:if(p1!=0)c=20;else c=0;,2023/11/7,19,if(条件表达式1)语句1 else if(条件表达式2)语句2 else if(条件表达式3)语句3 else if(条件表达式n)语句n else 语句n+1,2023/11/7,20,开关语句,switch(表达式)case 常量表达式1:语句1;break;case 常量表达式2:语句2;break;case 常量表达式n:语句n;break;default:语句n+1;,2023/11/7,21,10.3.2 C51循环语句,w
9、hile语句,一般形式为:while(条件表达式)语句;,如果条件表达式的结果一开始就为假,则后面的语句一次也不能执行。,Do-while语句,一般形式为:do语句 while(条件表达式);,任何条件下,循环体语句至少会被执行一次。,2023/11/7,22,for语句,一般形式为:for(初值表达式;条件表达式;更新表达式)语句,if语句与goto语句结合,当型循环 形式为:loop:if(表达式)语句 goto loop;,2023/11/7,23,直到型循环 形式为:loop:语句 if(表达式)goto loop;,continue是一种循环中断语句,它并不跳出循环体;break语句
10、只能跳出它所处的那一层循环;goto语句可以用于跳出多重循环(从内层到外层)。,注意:,2023/11/7,24,10.4 C51的指针类型,有一个变量a,利用&a表示变量a的地址。则语句 p=&a;把a的地址赋给了指针变量p,则“p指向了变量a”。,*P表示变量a的内容,指针变量的定义 char data*p/*定义指针变量*/p=30H/*为指针变量赋值,30H为片内RAM地址*/x=*p/*30H单元的内容送给变量x*/,2023/11/7,25,定义时未指定它所指向的对象的存储器类型,10.4.1 一般指针,一般指针占3个字节第一字节存放该指针的默认存储器类型编码(见表)第二字节存放该
11、指针的高位地址偏移量第三字节存放该指针的低位地址偏移量,存储器类型编码,2023/11/7,26,一般指针定义示例:,char*xdata strptr;/*指针本身存于xdata 空间,它指向char型数据*/int*data number;/*指针本身存于data 空间,它指向int型数据*/,由于指向对象的存储空间在编译时无法确定(运行时确定),因此必须生成一般代码以保证对任意空间的对象进行存取。所以一般指针所产生的代码速度较慢。,2023/11/7,27,10.4.2 基于存储器的指针,定义时就指定它所指向的对象的存储器类型,指针占1个字节(idata*,data*,pdata*)或2
12、个字节(code*,xdata*),基于存储器指针定义示例:,char data*str;/*指针指向的char型数据存于data 空间*/int xdata*num;/*指针指向的int型数据存于xdata 空间*/,基于存储器的指针长度比一般指针短,可以节省存储器空间,运行速度快,但它所指对象具有确定的存储器空间,兼容性不好。,2023/11/7,28,10.5 C51的函数,10.5.1 C51函数的定义,一般形式:,返回值类型 函数名(形式参数列表)编译模式reentrantinterrupt nusing n 函数体,编译模式为SMALL、COPACT或LARGEreentrant用
13、于定义可重入函数interrupt n 用于定义中断函数,n为中断号,可以为031using n 确定工作寄存器组,取值为03,2023/11/7,29,10.5.2 C51函数的调用与参数传递,主调函数要向被调函数传递所需的参数传递给被调函数的数据称为实际参数,即实参实参向形参的传递是单向的参数传递可以采用寄存器、固定存储器位置方式,参数传递,寄存器参数传递,2023/11/7,30,SMALL模式下,在内部RAM中完成 COMPACT模式下,在外部RAM中完成LARGER模式下,在外部RAM中完成,固定存储器位置参数传递,80C51单片机不采用堆栈传递参数。但C51提供一种模拟堆栈,从而支
14、持可重入函数的递归调用。,10.5.3 C51的库函数,常用的C51库函数参见附录B.2,2023/11/7,31,10.6 C51编程实例,10.6.1 80C51内部资源的编程,中断服务函数示例,中断函数的定义形式void 函数名(void)interrupt n using m 函数体,2023/11/7,32,【例10-1】单片机应用系统中,外中断0引脚接一个开关,并行口线P1.0接一个发光二级管。要求:开关闭合一次,发光二极管的状态改变一次。试编写程序,#include“reg51.h”#include“intrins.h”sbit P10=P10;void delay(void)i
15、nt a=5000;while(a-)_nop_();,void int_srv(void)interrupt 0 delay();if(INT0=0)P10=!P10;while(INT0=0);,void main()P10=0;EA=1;EX0=1;while(1);,2023/11/7,33,定时计数器编程示例,【例10-2】利用定时/计数器T0的方式1,产生10ms的定时,并使P1.0引脚上输出周期为20ms的方波,采用中断方式,设系统时钟频率为12 MHz。,1、计算计数初值X:Nt/Tcy 1010-3/110-610000计数器初值应为-10000。即应将-(10000/256
16、)送入TH0中,-(10000%256)送入TL0中。,2、求T0的方式控制字TMOD:M1M0=01,GATE=0,C/T=0,可取方式控制字为01H。,3、程序清单(见下页),2023/11/7,34,#include“reg51.h”sbit P10=P10;void timer0(void)interrupt 1 P10=!P10;TH0=-(10000/256);TL0=-(10000%256);,void main(void)TMOD=0 x01;P10=0;TH0=-(10000/256);TL0=-(10000%256);EA=1;ET0=1;TR0=1;while(1);,2
17、023/11/7,35,10.6.2 80C51扩展资源的编程,通用并行口编程示例,【例10-3】用81C55作为微型打印机与单片机间的接口电路。,2023/11/7,36,#include“reg51.h”#include“absacc.h”/*含有对XBYTE等绝对地址访问宏的定义*/#define uchar unsigned char#define COMD8155 XBYTE0 x7f00#define PA8155 XBYTE0 x7f01#define PB8155 XBYTE0 x7f02#define PC8155 XBYTE0 x7f03sbit BUSY=P33;,202
18、3/11/7,37,uchar code tab17=0 xb8,0 xdf,0 xbd,0 xcc,0 x20,0 xb3,0 xf6,0 xb0,0 xe6,0 xc9,0 xe7,0 x20,0 x32,0 x30,0 x30,0 x38,0 x0a;/*高教 出版社 2008*/uchar t1=17;,void ptr(uchar d)/*打印字符函数*/PA8155=d;PC8155=0 x00;/*产生选通脉冲*/PC8155=0 x01;while(BUSY);,2023/11/7,38,void main(void)COMD8155=0 x0f;/*送命令字*/prt(0 x
19、1c);/*送中文打印方式命令字高字节*/prt(0 x26);/*送中文打印方式命令字低字节*/EA=1;EX1=1;while(1);,2023/11/7,39,void int1(void)interrupt 2 using 1 uchar i;EA=0;for(i=0;i t1;i+)prt(tabi);EA=1;,2023/11/7,40,A/D转换接口编程示例,【例10-4】ADC0809与单片机的接口电路如图。,2023/11/7,41,#include“reg51.h”#include“absacc.h”#define uchar unsigned char#define IN0 XBYTE0 x7ff8sbit ad_busy=P33;,2023/11/7,42,void ad0809(uchar idata*x)uchar i;uchar xdata*ad_adr;ad_adr=&IN0;for(i=0;i 8;i+)*ad_adr=0;/*启动转换*/i=i;/*延时等待*/i=i;while(ad_busy!=0);xi=*ad_adr;/*存转换结果*/ad_adr+;/*下一通道*/,2023/11/7,43,void main(void)static uchar idata ad10;ad0809(ad);,Thank You!,