资源预览内容
第1页 / 共33页
第2页 / 共33页
第3页 / 共33页
第4页 / 共33页
第5页 / 共33页
第6页 / 共33页
第7页 / 共33页
第8页 / 共33页
第9页 / 共33页
第10页 / 共33页
亲,该文档总共33页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
2024/8/121第第4 4章章 80C5180C51单片机单片机C C语言程序设计语言程序设计C51对标准对标准C的扩展的扩展4.1C51的的指针指针4.2C51的函数的函数4.3C51与汇编程序的接口与汇编程序的接口4.42024/8/1224.1 C51对标准对标准C的扩展的扩展 4.1.1 C514.1.1 C51的数据类型的数据类型 数据数据是计算机操作的对象,包含是计算机操作的对象,包含常量常量和和变量变量。 C51C51扩展了扩展了ANSI CANSI C,以适应单片机的结构和特点。,以适应单片机的结构和特点。 n 数据类型数据类型就是就是数据的格式数据的格式,它决定数据的,它决定数据的值域值域范围范围、占用存储单元的个数占用存储单元的个数及能及能参与哪种运算参与哪种运算。 n 编写编写C51C51程序,先要确定数据类型、储存分区程序,先要确定数据类型、储存分区n 应尽可能采用无符号格式(应尽可能采用无符号格式(unsignedunsigned) n C51C51中,多字节数据采用中,多字节数据采用“大端对齐大端对齐”格式格式数据数据起始起始字节置于字节置于高地址端高地址端2024/8/123数据类型数据类型长度长度(位位)取值范围取值范围字符型字符型signed char8-128127unsigned char80255整整 型型signed int16-3276832767unsigned int16065535长整型长整型signed long32-2147488364821474883647unsigned long3204294967295浮点型浮点型float321.75494E-383.402823E+38位位 型型bit10,1sbit10,1访问访问SFRsfr80255sfr1616065535C51C51数据类型表数据类型表2024/8/124nbitbit定定义义位位变变量量名名字字,编编译译器器在在位位寻寻址址区区自自动动分配分配该位变量;该位变量;nSbitSbit声声明明位位变变量量的的名名字字和和地地址址,地地址址是是确确定定的的(SFRSFR区区确确定定位位、位位寻寻址址区区变变量量的的某某确确定定位位)。几点说明:几点说明:unsignedunsigned char char bdatabdata ibaseibase; ;sbitsbit mybitfmybitf = ibase0; = ibase0;sbitsbit CY = 0xD7; CY = 0xD7;bit flag1 = 0;bit flag1 = 0;含义:含义:赋值赋值含义:含义:声明声明2024/8/1254.1.2 C514.1.2 C51数据的存储分区数据的存储分区存储器类型存储器类型长度(位)长度(位)对应单片机存储器对应单片机存储器bdata1片内片内RAM位寻址区,共位寻址区,共128位。(亦能字节访问)位。(亦能字节访问)data8直接寻址,共直接寻址,共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 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区区 2024/8/127编译模式编译模式默认默认存储分区存储分区特特 点点SMALLdata小模式。小模式。 变量默认在片内变量默认在片内RAM。空间小,速度块。空间小,速度块。COMPACTpdata紧凑模式。紧凑模式。变量默认在片外变量默认在片外RAM的页(的页(256字节,页号字节,页号由由P2口决定)。口决定)。LARGExdata大模式。大模式。 变量默认在片外变量默认在片外RAM的的64KB范围。空间大,范围。空间大,速度慢。速度慢。编译模式默认的变量存储分区编译模式默认的变量存储分区4.1.3 C514.1.3 C51的编译模式的编译模式未对变量存储分区定义时,未对变量存储分区定义时,C51C51编译器采用编译器采用默默认认存储分区。例如:存储分区。例如:char char varvar; /SMALL/SMALL模式时,模式时,varvar定位于定位于datadata存储区存储区 /COMPACT/COMPACT模式时,模式时,varvar定位于定位于pdatapdata存储区存储区 /LARGE/LARGE模式时,模式时,varvar定位于定位于xdataxdata存储区存储区 2024/8/1294.1.4 4.1.4 用用_at_at_定义变量绝对地址定义变量绝对地址 用关键字用关键字“_at_”_at_”定义变量存放的首地址定义变量存放的首地址 idataidata intint y _at_ 0x30 y _at_ 0x30;/ / idataidata区域整型变量区域整型变量y y的首地址为的首地址为0x30 0x30 例如:例如:又如:又如:xdataxdata char string20 _at_ 0x3000 char string20 _at_ 0x3000;/xdataxdata中字符型数组中字符型数组stringstring的首地址为的首地址为0x30000x3000 注意,注意,C51C51编程时不要轻易使用绝对地址定位变量。编程时不要轻易使用绝对地址定位变量。 2024/8/12104.2 C51的指针的指针n对于一个变量对于一个变量a a,利用,利用& &a a表示变量表示变量a a的地址。则语句的地址。则语句 p p = & = &a a; 表明表明把把a a的地址赋给了指针变量的地址赋给了指针变量p 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指针变量指针变量数据变量数据变量4.2.1 4.2.1 已定义数据存储分区的指针已定义数据存储分区的指针定义时就定义时就指定了指定了所所指向数据指向数据的的存储分区。存储分区。 n该指针占该指针占1 1个字节个字节(idataidata * *,data *data *,pdatapdata * *)或)或2 2个个字节字节(code *code *,xdataxdata * *) 示例:示例:charchar datadata * *strstr; / / 指针指针strstr指向的指向的charchar型数据型数据存于存于data data 空间空间intint xdataxdata *num *num; / / 指针指针numnum指向的指向的intint型数据型数据存于存于xdataxdata 空间空间 基于存储器的基于存储器的指针长度指针长度比通用指针比通用指针短短,可以节省存储,可以节省存储器空间,器空间,运行速度快运行速度快,但它所指对象具有确定的存储器,但它所指对象具有确定的存储器空间,空间,兼容性不好兼容性不好。数据数据数据分区数据分区2024/8/1212定义时定义时未指定未指定所指向的所指向的数据数据的的存储分区存储分区 。也称。也称通用指针通用指针。4.2.2 4.2.2 未定义数据存储分区的指针未定义数据存储分区的指针-通用指针通用指针 n通用指针占通用指针占3 3个个字节字节第一字节存放该指针的第一字节存放该指针的默认默认存储器存储器类型编码类型编码(见表见表)第二字节存放该指针的第二字节存放该指针的高高位地址偏移量位地址偏移量第三字节存放该指针的第三字节存放该指针的低低位地址偏移量位地址偏移量 存储器类型编码存储器类型编码 存储器类型存储器类型bdata/ data / idataxdatapdatacode编码编码0x000x010xfe0xff2024/8/1213通用指针定义示例:通用指针定义示例:charchar * *xdataxdata strptrstrptr; / / 指针本身存于指针本身存于xdataxdata 空间空间,它指向,它指向charchar型数据型数据intint *data number *data number; / / 指针本身存于指针本身存于data data 空间空间,它指向,它指向intint型数据型数据 由于指向对象的存储空间在编译时无法确定(由于指向对象的存储空间在编译时无法确定(运行时确运行时确定定),因此必须生成通用代码以保证对任意空间的对象进),因此必须生成通用代码以保证对任意空间的对象进行存取。所以行存取。所以通用指针通用指针生成的代码速度较慢生成的代码速度较慢。指针指针charchar型型数据数据指针分区指针分区2024/8/12144.2.3 4.2.3 利用指针进行绝对地址访问利用指针进行绝对地址访问 unsigned char data *punsigned char data *p; p=0x40 p=0x40 ; * *p=0x55p=0x55; /数据数据0x550x55送入内部送入内部RAMRAM的的0x400x40单元单元 例如:例如:v C51C51编译器提供了一组宏定义实现对编译器提供了一组宏定义实现对80C5180C51绝对地址的访问。绝对地址的访问。这组宏定义原型放在这组宏定义原型放在absacc.habsacc.h文件中,形如:文件中,形如: #define #define DBYTEDBYTE (unsigned char volatile data *) 0) (unsigned char volatile data *) 0)从而使从而使DBYTEDBYTE用于以用于以字节字节形式对形式对datadata区访问,可以写成:区访问,可以写成: * *(DBYTE)=0x55H(DBYTE)=0x55H;或或 DBYTE0=0x55HDBYTE0=0x55H; 与此类似:与此类似:C CBYTEBYTE用于以用于以字节字节形式对形式对codecode区区进行访问;进行访问;P PBYTEBYTE用于以用于以字节字节形式对形式对p pdatadata区区进行访问;进行访问;X XBYTEBYTE用于以用于以字节字节形式对形式对xdataxdata区区进行访问。进行访问。C CWORDWORD、D DWORDWORD、P PWORDWORD和和X XWORDWORD用于以用于以字字形式对形式对codecode区、区、datadata区、区、pdatapdata区区和和xdataxdata区区进行访问。进行访问。 4.2.4 C514.2.4 C51程序编写示例程序编写示例 【例例4-14-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=15;i+) DBYTE0x30+i=0x55;DBYTE0x30+i=0x55; while(1);while(1); 编译系统自动连接了编译系统自动连接了startup.a51startup.a51生成代码生成代码n一是将内部一是将内部RAMRAM的的00H00H7FH7FH清清0 0;n二是设置堆栈指针二是设置堆栈指针SPSP。 有全局变量赋值时有全局变量赋值时编译系统会自动连接编译系统会自动连接init.a51init.a51生成代码生成代码C:0x0000 020011 LJMP C:0011C:0x0000 020011 LJMP C:0011C:0x0003 E4 CLR AC:0x0003 E4 CLR AC:0x0004 FF MOV R7,AC:0x0004 FF MOV R7,AC:0x0005 7430 MOV A,#0x30C:0x0005 7430 MOV A,#0x30C:0x0007 2F ADD A,R7C:0x0007 2F ADD A,R7C:0x0008 F8 MOV R0,AC:0x0008 F8 MOV R0,AC:0x0009 7655 MOV R0,#0x55C:0x0009 7655 MOV R0,#0x55C:0x000B 0F INC R7C:0x000B 0F INC R7C:0x000C BF10F6 CJNE R7,#0x10,C:0005C:0x000C BF10F6 CJNE R7,#0x10,C:0005C:0x000F 80FE SJMP C:000FC:0x000F 80FE SJMP C:000FC:C:0x00110x0011 787F MOV R0,#0x7F 787F MOV R0,#0x7FC:0x0013 E4 CLR AC:0x0013 E4 CLR AC:0x0014 F6 MOV R0,AC:0x0014 F6 MOV R0,AC:0x0015 D8FD DJNZ R0,C:0014C:0x0015 D8FD DJNZ R0,C:0014C:0x0017 758107 MOV SP,#0x07C:0x0017 758107 MOV SP,#0x07C:0x001A 020003 LJMP C:0003C:0x001A 020003 LJMP C:0003反汇编如下:反汇编如下:编译系统自动连接了编译系统自动连接了startup.a51startup.a51生成代码生成代码n一是将内部一是将内部RAMRAM的的00H00H7FH7FH清清0 0;n二是设置堆栈指针二是设置堆栈指针SPSP。 另:另:全局变量赋值时全局变量赋值时编译系统会自动连接编译系统会自动连接init.a51init.a51生成代码生成代码2024/8/12194.3 C51的函数的函数 4.3.1 C514.3.1 C51函数的定义函数的定义一般形式一般形式: :返回值类型返回值类型 函数名函数名(形式参数列表)(形式参数列表) 编译模式编译模式reentrantinterruptreentrantinterrupt nusingnusing n n 函数体函数体 n编译模式为编译模式为SMALLSMALL、COPACTCOPACT或或LARGELARGEnreentrantreentrant用于定义可重入函数用于定义可重入函数ninterrupt n interrupt n 用于定义中断函数用于定义中断函数,n,n为中断号为中断号, ,可以为可以为0 03131nusing n using n 确定工作寄存器组,取值为确定工作寄存器组,取值为0 03 3 【例例4-24-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 = 0; j 113; j+); 调试:调试:RegistersRegisters窗口中的窗口中的secsec值。值。 4.3.2 C514.3.2 C51函数定义函数定义的选项的选项编译模式编译模式 n SMALL SMALL模式:变量默认在片内模式:变量默认在片内RAMRAM;n COMPACT COMPACT模式:变量默认在片外模式:变量默认在片外RAMRAM的页内;的页内;n LARGE LARGE模式:变量默认在片外模式:变量默认在片外RAMRAM的的64KB64KB范围。范围。reentrantreentrant定义为重入函数定义为重入函数 n ANSI C ANSI C中,函数默认都是可重入的中,函数默认都是可重入的n C51C51函数函数默认默认是是不可重入不可重入的,的,使用可重入函数会消耗较使用可重入函数会消耗较多的存储器资源,多的存储器资源,应该尽量少用应该尽量少用。 interrupt n interrupt n 定义中断函数定义中断函数 常用的中断源常用的中断源对应对应的中断号的中断号using nusing n确定中断服务函数所使用的工作寄存器组确定中断服务函数所使用的工作寄存器组 中断源中断源外中断外中断0定时器定时器0外中断外中断1定时器定时器1串行口串行口定时器定时器2中断号中断号012345【例例4-34-3】中断函数定义示例中断函数定义示例#include #include sbitsbit 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); 4.3.3 C514.3.3 C51的库函数的库函数常用的C51库函数参见附录B.2 【例例4-44-4】C51C51库函数调用示例。库函数调用示例。#include “#include “intrins.hintrins.h” ” /在在intrins.hintrins.h中有对函数中有对函数_ _nopnop_( )_( )的定义的定义void void Delay(voidDelay(void) ) intint i=5000; i=5000; while(i-)_nopwhile(i-)_nop_( );_( ); 【例例4-54-5】C51C51标准输入输出函数调用示例。标准输入输出函数调用示例。#include #include #include #include void void InitSPort(voidInitSPort(void) ) SCON=0x50; / SCON=0x50; /串口方式串口方式1 1,允许接收,允许接收 TMOD=0x20; /T1 TMOD=0x20; /T1方式方式2 2(自动重装)(自动重装) TH1= 0xFD; / TH1= 0xFD; /波特率波特率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的重定向!的重定向! 在调试状态:在调试状态:ViewViewSerial WindowsSerial WindowsUART #1 UART #1 4.4 C51与汇编程序的接口与汇编程序的接口 4.4.1 4.4.1 在在C51C51程序中嵌入汇编指令程序中嵌入汇编指令 【例例4-64-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) ) # #pragmapragma 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; 要进行以下设置:要进行以下设置:2024/8/1227n将嵌有汇编语句的源文件加入工程文件,将将嵌有汇编语句的源文件加入工程文件,将鼠标指向该文件,选择右键菜单鼠标指向该文件,选择右键菜单 “ “option option for for insertasminsertasm. c”. c”。n将属性将属性propertiesproperties书签下的书签下的 “ “Generate Generate Assembler SRC File”Assembler SRC File”与与“Assemble SRC Assemble SRC File”File”选项置成选项置成“”“”。n再加入库文件(如再加入库文件(如C51S.LIBC51S.LIB),然后编译。),然后编译。 4.4.2 4.4.2 在在C51C51程序中调用汇编子程序程序中调用汇编子程序 【例例4-74-7】不含参数传递的子程序调用。不含参数传递的子程序调用。先构造汇编语言源文件:先构造汇编语言源文件: 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对应对应C51C51的的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();d1ms(); /* /* 调用汇编子程序调用汇编子程序 * */ / 主调函数要向被调函数传递所需的参数主调函数要向被调函数传递所需的参数传递给被调函数的数据称为实参传递给被调函数的数据称为实参实参向形参的传递是单向的实参向形参的传递是单向的参数传递可以参数传递可以采用寄存器采用寄存器、固定存储器位置固定存储器位置方式方式 参数传递参数传递寄存器参数传递寄存器参数传递传递的参数传递的参数char、1字节指针字节指针int、2字节指针字节指针long、float通用指针通用指针参数参数1R7R6、R7R4R7R1、R2、R3参数参数2R5R4、R5R4R7R1、R2、R3参数参数3R3R2、R3R1、R2、R3SMALLSMALL模式下,在内部模式下,在内部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
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号