《第3章80C51单片机C语言程序设计课件电子教案幻灯片.ppt》由会员分享,可在线阅读,更多相关《第3章80C51单片机C语言程序设计课件电子教案幻灯片.ppt(33页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、2022-5-301第第3 3章章 80C5180C51单片机单片机C C语言程序设计语言程序设计C51对标准对标准C的扩展的扩展3.1C51的的指针指针3.2C51的函数的函数3.3C51与汇编程序的接口与汇编程序的接口3.42022-5-3023.1 C51对标准对标准C的扩展的扩展 3.1.1 C513.1.1 C51的数据类型的数据类型 数据数据是计算机操作的对象,包含是计算机操作的对象,包含常量常量和和变量变量。 C51C51扩展了扩展了ANSI CANSI C,以适应单片机的结构和特点。,以适应单片机的结构和特点。 n 数据类型数据类型就是就是数据的格式数据的格式,它决定数据的,它
2、决定数据的值域值域范围范围、占用存储单元的个数占用存储单元的个数及能及能参与哪种运算参与哪种运算。 n 编写编写C51C51程序,先要确定数据类型、储存分区程序,先要确定数据类型、储存分区n 应尽可能采用无符号格式(应尽可能采用无符号格式(unsignedunsigned) n C51C51中,多字节数据采用中,多字节数据采用“大端对齐大端对齐”格式格式数据数据起始起始字节置于字节置于高地址端高地址端2022-5-303数据类型长度(位)取值范围字符型signed char8-128127unsigned char80255整 型signed int16-3276832767unsigned
3、int16065535长整型signed long32-2147488364821474883647unsigned long3204294967295浮点型float321.75494E-383.402823E+38位 型bit10,1sbit10,1访问SFRsfr80255sfr1616065535C51C51数据类型表数据类型表2022-5-304n bitbit定义定义位变量名字,编译器在位寻址区位变量名字,编译器在位寻址区自自动动分配分配该位变量;该位变量;n SbitSbit声明声明位变量的名字和地址,地址是确位变量的名字和地址,地址是确定的(定的(SFRSFR区确定位、位寻址区
4、变量的某确定区确定位、位寻址区变量的某确定位位)。几点说明:几点说明:unsignedunsigned char char bdatabdata ibaseibase; ;sbitsbit mybitfmybitf = ibase0; = ibase0;sbitsbit CY = 0 xD7; CY = 0 xD7;bit flag1 = 0;bit flag1 = 0;含义:含义:赋值赋值含义:含义:声明声明2022-5-3053.1.2 C513.1.2 C51数据的存储分区数据的存储分区存储器类型长度(位)对应单片机存储器bdata1片内RAM位寻址区,共128位。(亦能字节访问)dat
5、a8直接寻址,共128字节。idata8间接寻址,共256字节。pdata8片外 RAM分页间址,共256字节。(MOVX Ri)xdata16间接寻址,共64k字节。(MOVX DPTR)code16ROM间接寻址,共64k字节。(MOVC A,A+DPTR)n经常使用的变量应该置于片内经常使用的变量应该置于片内RAMRAM中,要用中,要用bdatabdata、datadata、idataidata来定义来定义n不常使用的变量或规模较大的变量应该置于片外不常使用的变量或规模较大的变量应该置于片外RAMRAM中,中,要用要用pdatapdata、xdataxdata来定义来定义bit bit
6、bdatabdata flags flags; /位变量位变量flagsflags定位在片内位寻址区定位在片内位寻址区 char data char data varvar; /字符变量字符变量varvar定位在片内定位在片内RAMRAM区区 float float idataidata x,yx,y; / /实型变量实型变量x x,y y定位在片内间址定位在片内间址RAMRAM区区 unsigned char unsigned char pdatapdata z z; /无符号字符变量无符号字符变量z z定位在片外分页间址定位在片外分页间址RAMRAM区区 2022-5-307编译模式默认存
7、储分区特 点SMALLdata小模式。 变量默认在片内RAM。空间小,速度块。COMPACTpdata紧凑模式。变量默认在片外RAM的页(256字节,页号由P2口决定)。LARGExdata大模式。 变量默认在片外RAM的64KB范围。空间大,速度慢。编译模式默认的变量存储分区编译模式默认的变量存储分区3.1.3 C513.1.3 C51的编译模式的编译模式未对变量存储分区定义时,未对变量存储分区定义时,C51C51编译器采用编译器采用默默认认存储分区。例如:存储分区。例如:char char varvar; /SMALL/SMALL模式时,模式时,varvar定位于定位于datadata存储
8、区存储区 /COMPACT/COMPACT模式时,模式时,varvar定位于定位于pdatapdata存储区存储区 /LARGE/LARGE模式时,模式时,varvar定位于定位于xdataxdata存储区存储区 2022-5-3093.1.4 3.1.4 用用_at_at_定义变量绝对地址定义变量绝对地址 用关键字用关键字“_at_”_at_”定义变量存放的首地址定义变量存放的首地址 idataidata intint y _at_ 0 x30 y _at_ 0 x30;/ / idataidata区域整型变量区域整型变量y y的首地址为的首地址为0 x30 0 x30 例如:例如:又如:又
9、如:xdataxdata char string20 _at_ 0 x3000 char string20 _at_ 0 x3000;/xdataxdata中字符型数组中字符型数组stringstring的首地址为的首地址为0 x30000 x3000 注意,注意,C51C51编程时不要轻易使用绝对地址定位变量。编程时不要轻易使用绝对地址定位变量。 2022-5-30103.2 C51的指针的指针n对于一个变量对于一个变量a a,利用,利用& &a a表示变量表示变量a a的地址。则语句的地址。则语句 p p = & = &a a; 表明表明把把a a的地址赋给了指针变量的地址赋给了指针变量p
10、 p,则,则“p p指向了指向了变量变量a a”。 n 可以用可以用* *P P表示变量表示变量a a指针变量的定义指针变量的定义 char char * *p; p; / 定义指针变量定义指针变量P P p = 30H ; p = 30H ; / / 指针变量赋值,指针变量赋值,30H30H为片内为片内RAMRAM地址地址 x = x = * *p; p; / / 30H30H单元的内容送给变量单元的内容送给变量x x* *P P指针变量指针变量数据变量数据变量3.2.1 3.2.1 已定义数据存储分区的指针已定义数据存储分区的指针定义时就定义时就指定了指定了所所指向数据指向数据的的存储分区
11、。存储分区。 n 该指针占该指针占1 1个字节个字节(idataidata * *,data data * *,pdatapdata * *)或)或2 2个字节个字节(code code * *,xdataxdata * *) 示例:示例:charchar datadata * *strstr; / / 指针指针strstr指向的指向的charchar型数据型数据存于存于data data 空间空间intint xdataxdata * *numnum; / / 指针指针numnum指向的指向的intint型数据型数据存于存于xdataxdata 空间空间 基于存储器的基于存储器的指针长度指针
12、长度比通用指针比通用指针短短,可以节省存储,可以节省存储器空间,器空间,运行速度快运行速度快,但它所指对象具有确定的存储器,但它所指对象具有确定的存储器空间,空间,兼容性不好兼容性不好。数据数据数据分区数据分区2022-5-3012定义时定义时未指定未指定所指向的所指向的数据数据的的存储分区存储分区 。也称。也称通用指针通用指针。3.2.2 3.2.2 未定义数据存储分区的指针未定义数据存储分区的指针-通用指针通用指针 n 通用指针占通用指针占3 3个个字节字节第一字节存放该指针的第一字节存放该指针的默认默认存储器存储器类型编码类型编码(见表见表)第二字节存放该指针的第二字节存放该指针的高高位
13、地址偏移量位地址偏移量第三字节存放该指针的第三字节存放该指针的低低位地址偏移量位地址偏移量 存储器类型编码存储器类型编码 存储器类型bdata/ data / idataxdatapdatacode编码0 x000 x010 xfe0 xff2022-5-3013通用指针定义示例:通用指针定义示例:charchar * *xdataxdata strptrstrptr; / / 指针本身存于指针本身存于xdataxdata 空间空间,它指向,它指向charchar型数据型数据intint * *data numberdata number; / / 指针本身存于指针本身存于data data
14、空间空间,它指向,它指向intint型数据型数据 由于指向对象的存储空间在编译时无法确定(由于指向对象的存储空间在编译时无法确定(运行时确运行时确定定),因此必须生成通用代码以保证对任意空间的对象进),因此必须生成通用代码以保证对任意空间的对象进行存取。所以行存取。所以通用指针通用指针生成的代码速度较慢生成的代码速度较慢。指针指针charchar型型数据数据指针分区指针分区2022-5-30143.2.3 3.2.3 利用指针进行绝对地址访问利用指针进行绝对地址访问 unsigned char data unsigned char data * *p p; p=0 x40 p=0 x40 ;
15、* *p=0 x55p=0 x55; /数据数据0 x550 x55送入内部送入内部RAMRAM的的0 x400 x40单元单元 例如:例如:v C51C51编译器提供了一组宏定义实现对编译器提供了一组宏定义实现对80C5180C51绝对地址的访问。绝对地址的访问。这组宏定义原型放在这组宏定义原型放在absacc.habsacc.h文件中,形如:文件中,形如: #define #define DBYTEDBYTE (unsigned char volatile data (unsigned char volatile data * *) 0) 0)从而使从而使DBYTEDBYTE用于以用于以字
16、节字节形式对形式对datadata区访问,可以写成:区访问,可以写成: * *(DBYTE)=0 x55H(DBYTE)=0 x55H;或或 DBYTE0=0 x55HDBYTE0=0 x55H; 与此类似:与此类似:C CBYTEBYTE用于以用于以字节字节形式对形式对codecode区区进行访问;进行访问;P PBYTEBYTE用于以用于以字节字节形式对形式对p pdatadata区区进行访问;进行访问;X XBYTEBYTE用于以用于以字节字节形式对形式对xdataxdata区区进行访问。进行访问。C CWORDWORD、D DWORDWORD、P PWORDWORD和和X XWORDW
17、ORD用于以用于以字字形式对形式对codecode区、区、datadata区、区、pdatapdata区区和和xdataxdata区区进行访问。进行访问。 3.2.4 C513.2.4 C51程序编写示例程序编写示例 【例例3-13-1】将将30H30H至至3FH3FH共共1616个个RAMRAM单元初始化为单元初始化为“55H”55H”。#include #include #include #include void void main(voidmain(void) ) unsigned char i;unsigned char i;for (i=0;i=15;i+)for (i=0;i=1
18、5;i+) DBYTE0 x30+i=0 x55;DBYTE0 x30+i=0 x55; while(1);while(1); 编译系统自动连接了编译系统自动连接了startup.a51startup.a51生成代码生成代码n一是将内部一是将内部RAMRAM的的00H00H7FH7FH清清0 0;n二是设置堆栈指针二是设置堆栈指针SPSP。 有全局变量赋值时有全局变量赋值时编译系统会自动连接编译系统会自动连接init.a51init.a51生成代码生成代码C:0 x0000 020011 LJMP C:0011C:0 x0000 020011 LJMP C:0011C:0 x0003 E4 C
19、LR AC:0 x0003 E4 CLR AC:0 x0004 FF MOV R7,AC:0 x0004 FF MOV R7,AC:0 x0005 7430 MOV A,#0 x30C:0 x0005 7430 MOV A,#0 x30C:0 x0007 2F ADD A,R7C:0 x0007 2F ADD A,R7C:0 x0008 F8 MOV R0,AC:0 x0008 F8 MOV R0,AC:0 x0009 7655 MOV R0,#0 x55C:0 x0009 7655 MOV R0,#0 x55C:0 x000B 0F INC R7C:0 x000B 0F INC R7C:0
20、x000C BF10F6 CJNE R7,#0 x10,C:0005C:0 x000C BF10F6 CJNE R7,#0 x10,C:0005C:0 x000F 80FE SJMP C:000FC:0 x000F 80FE SJMP C:000FC:C:0 x00110 x0011 787F MOV R0,#0 x7F 787F MOV R0,#0 x7FC:0 x0013 E4 CLR AC:0 x0013 E4 CLR AC:0 x0014 F6 MOV R0,AC:0 x0014 F6 MOV R0,AC:0 x0015 D8FD DJNZ R0,C:0014C:0 x0015 D8F
21、D DJNZ R0,C:0014C:0 x0017 758107 MOV SP,#0 x07C:0 x0017 758107 MOV SP,#0 x07C:0 x001A 020003 LJMP C:0003C:0 x001A 020003 LJMP C:0003反汇编如下:反汇编如下:编译系统自动连接了编译系统自动连接了startup.a51startup.a51生成代码生成代码n一是将内部一是将内部RAMRAM的的00H00H7FH7FH清清0 0;n二是设置堆栈指针二是设置堆栈指针SPSP。 另:另:全局变量赋值时全局变量赋值时编译系统会自动连接编译系统会自动连接init.a51init
22、.a51生成代码生成代码2022-5-30193.3 C51的函数的函数 3.3.1 C513.3.1 C51函数的定义函数的定义一般形式一般形式: :返回值类型返回值类型 函数名函数名(形式参数列表)(形式参数列表) 编译模式编译模式reentrantinterruptreentrantinterrupt nusingnusing n n 函数体函数体 n 编译模式为编译模式为SMALLSMALL、COPACTCOPACT或或LARGELARGEn reentrantreentrant用于定义可重入函数用于定义可重入函数n interrupt n interrupt n 用于定义中断函数用于
23、定义中断函数,n,n为中断号为中断号, ,可以为可以为0 03131n using n using n 确定工作寄存器组,取值为确定工作寄存器组,取值为0 03 3 【例例3-23-2】延时延时nMsnMs函数示例(晶振函数示例(晶振11.0592MHz11.0592MHz)。)。void void DelayMsDelayMs( unsigned ( unsigned intint n ) n ) /延时函数延时函数 unsigned char j;unsigned char j;while (n- -)while (n- -) for (j = 0; j 113; j+); for (j
24、= 0; j 113; j+); 调试:调试:RegistersRegisters窗口中的窗口中的secsec值。值。 3.3.2 C513.3.2 C51函数定义函数定义的选项的选项编译模式编译模式 n SMALL SMALL模式:变量默认在片内模式:变量默认在片内RAMRAM;n COMPACT COMPACT模式:变量默认在片外模式:变量默认在片外RAMRAM的页内;的页内;n LARGE LARGE模式:变量默认在片外模式:变量默认在片外RAMRAM的的64KB64KB范围。范围。reentrantreentrant定义为重入函数定义为重入函数 n ANSI C ANSI C中,函数默
25、认都是可重入的中,函数默认都是可重入的n C51C51函数函数默认默认是是不可重入不可重入的,的,使用可重入函数会消耗较使用可重入函数会消耗较多的存储器资源,多的存储器资源,应该尽量少用应该尽量少用。 interrupt n interrupt n 定义中断函数定义中断函数 常用的中断源对应的中断号常用的中断源对应的中断号using nusing n确定中断服务函数所使用的工作寄存器组确定中断服务函数所使用的工作寄存器组 中断源外中断0定时器0外中断1定时器1串行口定时器2中断号012345【例例3-33-3】中断函数定义示例中断函数定义示例#include #include sbitsbit
26、 P10 = P10; P10 = P10;void void IntSrv(void)interruptIntSrv(void)interrupt 0 0 if(INT0=0)if(INT0=0)/测开关状态测开关状态 P10=!P10;P10=!P10;while(INT0=0);while(INT0=0); 3.3.3 C513.3.3 C51的库函数的库函数常用的C51库函数参见附录B.2 【例例3-43-4】C51C51库函数调用示例。库函数调用示例。#include “#include “intrins.hintrins.h” ” /在在intrins.hintrins.h中有对函
27、数中有对函数_ _nopnop_( )_( )的定义的定义void void Delay(voidDelay(void) ) intint i=5000; i=5000; while(i-)_nopwhile(i-)_nop_( );_( ); 【例例3-53-5】C51C51标准输入输出函数调用示例。标准输入输出函数调用示例。#include #include #include #include void void InitSPort(voidInitSPort(void) ) SCON=0 x50; / SCON=0 x50; /串口方式串口方式1 1,允许接收,允许接收 TMOD=0 x
28、20; /T1 TMOD=0 x20; /T1方式方式2 2(自动重装)(自动重装) TH1= 0 xFD; / TH1= 0 xFD; /波特率波特率96009600 TR1 =1; / TR1 =1; /启动启动T1T1 TI =1; / TI =1; /发送中断置发送中断置1 1 void void main(voidmain(void) ) InitSPortInitSPort();(); printf(Helloprintf(Hello World n); World n); while(1); while(1); 标准标准I/OI/O的重定向!的重定向! 在调试状态:在调试状态:V
29、iewViewSerial WindowsSerial WindowsUART #1 UART #1 v3.4 C51与汇编程序的接口与汇编程序的接口 3.4.1 3.4.1 在在C51C51程序中嵌入汇编指令程序中嵌入汇编指令 【例例3-63-6】利用预编译指令。利用预编译指令。 #include reg51.h#include reg51.hvoid void Init(voidInit(void););void main()void main() while(1) while(1) Init(); Init(); void void Init(voidInit(void) ) # #pr
30、agmapragma asmasmMOV R7,#16MOV R7,#16MOV R1,#20HMOV R1,#20HMOV A,#55HMOV A,#55H LP:MOV R1,A LP:MOV R1,AINC R1INC R1 DJNZ R7,LP DJNZ R7,LP # #pragmapragma endasmendasmreturn;return; 要进行以下设置:要进行以下设置:2022-5-3027n将嵌有汇编语句的源文件加入工程文件,将将嵌有汇编语句的源文件加入工程文件,将鼠标指向该文件,选择右键菜单鼠标指向该文件,选择右键菜单 “ “option option for for
31、 insertasminsertasm. c”. c”。n将属性将属性propertiesproperties书签下的书签下的 “ “Generate Generate Assembler SRC File”Assembler SRC File”与与“Assemble SRC Assemble SRC File”File”选项置成选项置成“”“”。n再加入库文件(如再加入库文件(如C51S.LIBC51S.LIB),然后编译。),然后编译。 3.4.2 3.4.2 在在C51C51程序中调用汇编子程序程序中调用汇编子程序 【例例3-73-7】不含参数传递的子程序调用。不含参数传递的子程序调用。
32、先构造汇编语言源文件:先构造汇编语言源文件: d1ms:MOV R6,#249 ;d1ms:MOV R6,#249 ; DL:NOP DL:NOP ;1 ;1s s NOP NOP ;1 ;1s s DJNZ R6,DL ;2 DJNZ R6,DL ;2s,s,循环内约循环内约1ms1ms RET RET ENDEND ?PR?d1ms?EP4_7B?PR?d1ms?EP4_7B SEGMENT SEGMENT CODECODE PUBLIC PUBLIC d1msd1ms RSEG RSEG ?PR?d1ms?EP4_7B?PR?d1ms?EP4_7B注:注:d1msd1ms对应对应C51C
33、51的的d1msd1ms()()EP4_7BEP4_7B对应对应ep4_7b.asmep4_7b.asm编写编写C51C51语言程序如下,完成汇编子程序调用:语言程序如下,完成汇编子程序调用:#include #include sbitsbit P2_0=P20; P2_0=P20;externextern void d1ms(void); void d1ms(void);void main()void main() for(;)for(;) P2_0=0;P2_0=0;d1ms();d1ms(); / /* * 调用汇编子程序调用汇编子程序 * */ /P2_0=1;P2_0=1;d1ms(
34、);d1ms(); / /* * 调用汇编子程序调用汇编子程序 * */ / 主调函数要向被调函数传递所需的参数主调函数要向被调函数传递所需的参数传递给被调函数的数据称为实参传递给被调函数的数据称为实参实参向形参的传递是单向的实参向形参的传递是单向的参数传递可以参数传递可以采用寄存器采用寄存器、固定存储器位置固定存储器位置方式方式 参数传递参数传递寄存器参数传递寄存器参数传递传递的参数char、1字节指针int、2字节指针long、float通用指针参数1R7R6、R7R4R7R1、R2、R3参数2R5R4、R5R4R7R1、R2、R3参数3R3R2、R3R1、R2、R3SMALLSMALL模
35、式下,在内部模式下,在内部RAMRAM中完成中完成 COMPACTCOMPACT模式下,在外部模式下,在外部RAMRAM中完成中完成LARGERLARGER模式下,在外部模式下,在外部RAMRAM中完成中完成固定存储器位置参数传递固定存储器位置参数传递 80C51 80C51单片机不采用堆栈传递参数。单片机不采用堆栈传递参数。但但C51C51提供提供一种模拟堆栈,从而支持可重入函数的递归调用一种模拟堆栈,从而支持可重入函数的递归调用。 函数返回值使用的寄存器函数返回值使用的寄存器返回数据的类型寄存器说 明bitC进位标志位char、unsigned char、1字节指针R7int、unsigned int、2字节指针R6、R7高字节在R6,低字节在R7long、unsigned longR4、R5、R6、R7最高字节在R4,最低字节在R7floatR4、R5、R6、R732位IEEE格式通用指针R1、R2、R3存储类型在R1,高字节在R2,低字节在R3