好文档就是一把金锄头!
欢迎来到金锄头文库![会员中心]
电子文档交易市场
安卓APP | ios版本
电子文档交易市场
安卓APP | ios版本

80C51语言程序设计基础ppt课件.ppt

77页
  • 卖家[上传人]:M****1
  • 文档编号:592327042
  • 上传时间:2024-09-20
  • 文档格式:PPT
  • 文档大小:523KB
  • / 77 举报 版权申诉 马上下载
  • 文本预览
  • 下载提示
  • 常见问题
    • 第3章 单片机C51语言设计基础3.1 C513.1 C51的数据的数据3.2 C513.2 C51对单片机主要资源的控制对单片机主要资源的控制3.3 C513.3 C51的基本运算与流程控制的基本运算与流程控制3.4 C513.4 C51的数组与指针的数组与指针3.5 C513.5 C51函数函数3.6 C513.6 C51的预处理命令的预处理命令 3.1 C51的数据3.1.1 3.1.1 数据类型数据类型 3.1.2 3.1.2 常量与变量常量与变量3.1.3 3.1.3 数据存储类型数据存储类型3.1.4 3.1.4 局部变量与全局变量局部变量与全局变量 3.1.1 数据类型 3.1.2 常量与变量1 1.常量.常量 C51C51语语言言中中的的常常量量是是不不接接受受程程序序修修改改的的固固定定值值,,常量可以是任意数据类型常量可以是任意数据类型 C51C51中中的的常常量量有有整整型型常常量量、、实实型型常常量量、、字字符符型型常常量、字符串常量符号常量等量、字符串常量符号常量等 ((2 2〕实型常量〕实型常量 在整型常量后加一个字母在整型常量后加一个字母“L“L〞或〞或“l”“l”,表示该数位长,表示该数位长整型。

      例如整型例如23L23L、、0Xfd4l0Xfd4l等 如果需要的是负值,则必须将负号如果需要的是负值,则必须将负号“-”“-”放置于常量表放置于常量表达式的最前面,例如达式的最前面,例如-0x56-0x56、、-9-9等实型常量又称浮点常量,是一个十进制表示的符号实型常量又称浮点常量,是一个十进制表示的符号实数实型常量的值包括整数部分、尾数部分和指实数实型常量的值包括整数部分、尾数部分和指数部分实型常量的形式如下:数部分实型常量的形式如下:[digits][.digits][E[+/-]digits][digits][.digits][E[+/-]digits]一些实型常量的示例如下:一些实型常量的示例如下:15.7515.75、、1.575E11.575E1、、1575E-31575E-3、、-0.0025-0.0025、、-2.5e-3-2.5e-3、、25E-425E-4 (3〕字符型常量 字符型常量是指用一对单引号括起来的一个字符如字符型常量是指用一对单引号括起来的一个字符如'a''a'、、'9''9'、、' '!!' '等字符常量中的单引号只起定界作用并不表示字符本身。

      等字符常量中的单引号只起定界作用并不表示字符本身 在在C51C51语言中,字符是按其对应的语言中,字符是按其对应的ASCIIASCII码值来存储的,码值来存储的,1 1个字符占个字符占1 1个个字节字节 字符串常量是指用一对双引号括起来的一串字符,双引号只起定界作用,字符串常量是指用一对双引号括起来的一串字符,双引号只起定界作用,如如"China""China"、、"123456""123456"等 (5〕符号常量 C51 C51语言中允许将程序中的常量定义为一个标识符,称为符号常量语言中允许将程序中的常量定义为一个标识符,称为符号常量 符号常量一般使用大写英文字母表示,以区别于一般用小写字母表符号常量一般使用大写英文字母表示,以区别于一般用小写字母表示的变量示的变量 符号常量在使用前必须先定义,定义的形式是:符号常量在使用前必须先定义,定义的形式是: #define #define 标识符标识符 常量常量 #define PI 3.1415926 #define PI 3.1415926 2.变量变量的定义:变量的定义: 数据类型数据类型 变量名变量名; ; int i,j,k; int i,j,k; unsigned char si; unsigned char si; unsigned int ui; unsigned int ui; double balance,profit,loss; double balance,profit,loss; C51 C51中常用的:中常用的:bitbit、、charchar、、intint(1〕整型变量〔INT) 16位数据有符号:有符号:signed intsigned int -32 768 -32 768~~32 767 32 767 无符号:无符号:unsigned int unsigned int 0 0~~65 535 65 535 0x1234 0x1234存储形式存储形式 ((3 3〕实型变量〕实型变量((2 2〕长整型变量〔〕长整型变量〔long intlong int)) 长整型变量长度是长整型变量长度是3232位,占用位,占用4 4个字节〔个字节〔bytebyte),其),其他方面和整型变量〔他方面和整型变量〔intint〕类似。

      〕类似分为单精度〔分为单精度〔floatfloat〕型和双精度〔〕型和双精度〔doubledouble〕型其定义形式为:其定义形式为: float x,y; // float x,y; //指定指定x,yx,y为单精度实数为单精度实数 double z; // double z; //指定指定z z为双精度实数为双精度实数 在一般系统中,一个在一般系统中,一个floatfloat型数据在内存中占型数据在内存中占4 4个字节个字节〔〔3232位),一个位),一个doubledouble型数据占型数据占8 8个字节〔个字节〔6464位)单精位)单精度实数提供度实数提供7 7位有效数字,双精度实数提供位有效数字,双精度实数提供1515~~1616位有效位有效数字 (4〕字符变量CHAR字符变量用来存放字符常量注意只能存放字符变量用来存放字符常量注意只能存放1 1个字符字符变量的定义形式如下:字符变量的定义形式如下:char char 变量名变量名; ;例如:例如: char c1,c2; char c1,c2;它表示它表示c1c1和和c2c2为字符变量,各存放为字符变量,各存放1 1个字符。

      可以用下面的语句对个字符可以用下面的语句对c1c1、、c2c2赋赋值:值:c1='a';c2='b';c1='a';c2='b';字符变量的长度是字符变量的长度是1 1字节〔字节〔bytebyte〕即〕即8 8位这很适合于位这很适合于80518051单片机,因为单片机,因为80518051单片机每次可以处理单片机每次可以处理8 8位数据变量的类型是位,位变量的值可以是变量的类型是位,位变量的值可以是1 1〔〔truetrue〕或〕或0 0〔〔falsefalse)与与80518051硬件特性操作有关的位变量必须定位在硬件特性操作有关的位变量必须定位在80518051单片机片内存储区单片机片内存储区〔〔RAMRAM〕的可位寻址空间中〕的可位寻址空间中 3.有符号/无符号问题说明((1 1〕尽量使用无符号变量〕尽量使用无符号变量((2 2〕在编程时,为了书写方便,经常使用简化的缩写形式来定义〕在编程时,为了书写方便,经常使用简化的缩写形式来定义变量的数据类型:变量的数据类型: #define uchar unsigned char #define uchar unsigned char #define uint unsigned int #define uint unsigned int 3.1.3 数据存储类型 数据时存放在数据时存放在5151单片机的存储器中的,因此要规定数据单片机的存储器中的,因此要规定数据的存储类型。

      的存储类型P53 P53 表表3-43-4 常用:常用:datadata、、xdataxdata、、codecode 另外:另外:bdatabdata ((1 1〕〕DATADATA区区datadata区的寻址是最快的,所以应该把经常使区的寻址是最快的,所以应该把经常使用的变量放在用的变量放在datadata区,但是区,但是datadata区的空间是区的空间是有限的,有限的,datadata区除了包含程序变量外,还包区除了包含程序变量外,还包含了堆栈和寄存器组含了堆栈和寄存器组datadata区声明中的存储类型标式符为区声明中的存储类型标式符为datadata,通,通常指片内常指片内RAMRAM的低的低128128字节的内部数据存储的字节的内部数据存储的变量,可直接寻址变量,可直接寻址声明举例如下:声明举例如下: unsigned char data unsigned char data system_status=0;system_status=0; unsigned int data unit_id[2]; unsigned int data unit_id[2]; char data inp_string[16]; char data inp_string[16]; bdatabdata实际是实际是datadata中的位寻址区,在这个区中声中的位寻址区,在这个区中声明变量就可以进行位寻址。

      位变量的声明对状明变量就可以进行位寻址位变量的声明对状态寄存器来说是十分有用的,因为它可能仅仅态寄存器来说是十分有用的,因为它可能仅仅需要某一位,而不是整个字节需要某一位,而不是整个字节bdatabdata区声明中的存储类型标识符为区声明中的存储类型标识符为bdatabdata,指,指内部可位寻址的内部可位寻址的1616字节存储区〔字节存储区〔20H20H到到2FH2FH),),数据类型是可位寻址变量的数据类型数据类型是可位寻址变量的数据类型 (2) BDATA区区 以下是在BDATA区中声明的位变量和使用位变量的例子: unsigned char bdata status_byte; unsigned int bdata status_word; unsigned long bdata status_dword; sbit stat_flag=status_byte^4; if(status_word^15) {…} stat_flag=1; (3〕IDATA区idataidata区也可以存放使用比较频繁的变量,使用寄存器作为指针进行寻址。

      区也可以存放使用比较频繁的变量,使用寄存器作为指针进行寻址idataidata区声明中的存储类型标识符为区声明中的存储类型标识符为idataidata,指内部的,指内部的256256字节的存储区,字节的存储区,但是只能间接寻址,速度比直接寻址慢但是只能间接寻址,速度比直接寻址慢声明举例如下:声明举例如下:unsigned char idata system_status=0;unsigned char idata system_status=0;unsigned int idata unit_id[2];unsigned int idata unit_id[2];char idata inp_string[16];char idata inp_string[16];float idata out_value;float idata out_value;pdatapdata区和区和xdataxdata区属于外部数据存储区,外部数据区是可读可写的存区属于外部数据存储区,外部数据区是可读可写的存储区,最多可以有储区,最多可以有64KB64KB在这两个区,变量的声明与在其他区的语法是一样的,但在这两个区,变量的声明与在其他区的语法是一样的,但pdatapdata区只区只有有256256字节而字节而xdataxdata区可达区可达65 53665 536字节。

      字节 声明举例如下:unsigned char xdata system_status=0;unsigned int pdata unit_id[2] ;char xdata inp_string[16] ;float pdata out_value;外部地址段中除了包含存储器地址外,还包含外部地址段中除了包含存储器地址外,还包含I/O器件的地址对外部器件寻址可以通过指针器件的地址对外部器件寻址可以通过指针或或C51提供的宏,使用宏对外部器件提供的宏,使用宏对外部器件I/O口进行口进行寻址更具可读性寻址更具可读性 ((5 5〕程序存储区〕程序存储区CODECODE 程序存储区的数据是不可改变的,跳转向量和程序存储区的数据是不可改变的,跳转向量和状态表对状态表对codecode段访问和对段访问和对xdataxdata区访问的时间是一区访问的时间是一样的编译的时候要对程序存储区中的对象进行初样的编译的时候要对程序存储区中的对象进行初始化,否则就会产生错误程序存储区始化,否则就会产生错误程序存储区codecode声明的声明的标识符为标识符为codecode,在,在C51C51语言编译器中可以用语言编译器中可以用codecode存存储区类型标识符来访问程序存储区。

      下面是程序存储区类型标识符来访问程序存储区下面是程序存储区声明的例子:储区声明的例子:unsigned char code a[ ]=unsigned char code a[ ]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x0{0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x10,0x11,0x12,0x13,0x14,0x15};8,0x09,0x10,0x11,0x12,0x13,0x14,0x15}; 变量存储类型定义举例:char data var1;bit bdata flags;float idata x,y,z;unsigned int pdata dimension;unsigned char xdata vector[10][4][4]; 3.1.4 3.1.4 局部变量与全局变量局部变量与全局变量 从变量的作用范围来区分,变量可以被分为全局变量和局部变量;从变量的作用范围来区分,变量可以被分为全局变量和局部变量; 某些变量在程序运行过程中是始终存在的某些变量在程序运行过程中是始终存在的---全局变量。

      全局变量 某些变量只是在进入某个函数时才开始存在某些变量只是在进入某个函数时才开始存在---局部变量局部变量 1.局部变量局部变量是在某个函数中存在的变量,也可以称为内部变量,它只在该局部变量是在某个函数中存在的变量,也可以称为内部变量,它只在该函数内部有效函数内部有效局部变量可以分为动态局部变量和静态局部变量,使用关键词局部变量可以分为动态局部变量和静态局部变量,使用关键词autoauto定义定义动态局部变量〔动态局部变量〔autoauto可以省略),使用关键词可以省略),使用关键词staticstatic定义静态局部变量,定义静态局部变量,例如:例如:auto int a;auto int a;static unsigned char j;static unsigned char j;动态局部变量在程序执行完毕后其存储空间被释放,而静态局部变量在动态局部变量在程序执行完毕后其存储空间被释放,而静态局部变量在程序执行完成后其存储空间并不释放,而且其值保持不变程序执行完成后其存储空间并不释放,而且其值保持不变如果该函数再次被调用,则该函数初始化后其初始值为上次的数值。

      如果该函数再次被调用,则该函数初始化后其初始值为上次的数值动态局部变量和静态局部变量的区别如下:动态局部变量和静态局部变量的区别如下:  动态局部变量在函数被调用时分配存储空间和动态局部变量在函数被调用时分配存储空间和初始化,每次函数调用时都需要初始化;静态初始化,每次函数调用时都需要初始化;静态局部变量在编译程序时分配存储空间和初始化,局部变量在编译程序时分配存储空间和初始化,仅初始化一次仅初始化一次 动态局部变量存放在动态存储区,在每次退出动态局部变量存放在动态存储区,在每次退出所属函数时释放;静态局部变量存放在静态存所属函数时释放;静态局部变量存放在静态存储区,每次调用后函数不释放,保持函数执行储区,每次调用后函数不释放,保持函数执行完毕之后的数值到下一次调用完毕之后的数值到下一次调用 如果在建立时动态局部变量不初始为一个不确如果在建立时动态局部变量不初始为一个不确定的数,静态局部变量不初始化,则它们的值定的数,静态局部变量不初始化,则它们的值为为0 0或者是空字符或者是空字符 2 2.全局变量.全局变量 全局变量是在整个源文件中都存在的变量,又称为外部变量。

      全全局变量是在整个源文件中都存在的变量,又称为外部变量全局变量的有效区间是从定义点开始到源文件结束,其中的所有函数都局变量的有效区间是从定义点开始到源文件结束,其中的所有函数都可以直接访问该变量,如果定义点之前的函数需要访问该变量,则需可以直接访问该变量,如果定义点之前的函数需要访问该变量,则需要使用要使用externextern关键词对该变量进行声明,如果全局变量声明文件之外关键词对该变量进行声明,如果全局变量声明文件之外的源文件需要访问该变量,也需要使用的源文件需要访问该变量,也需要使用externextern关键词进行声明关键词进行声明全局变量有以下特点: 全局变量是整个文件都可以访问的变量,可以用于在函数之间共享全局变量是整个文件都可以访问的变量,可以用于在函数之间共享大量的数据,存在周期长,在程序编译时就存在,如果两个函数需要大量的数据,存在周期长,在程序编译时就存在,如果两个函数需要在不互相调用时共享数据,则可以使用全局变量进行参数传递;在不互相调用时共享数据,则可以使用全局变量进行参数传递; C51C51语言程序的函数只支持一个函数返回值,如果一个函数需要返回语言程序的函数只支持一个函数返回值,如果一个函数需要返回多个值,除了使用指针外,还要使用全局变量;多个值,除了使用指针外,还要使用全局变量; 使用全局变量进行参数传递可以减少从实际参数向形式参数传递时使用全局变量进行参数传递可以减少从实际参数向形式参数传递时所必需的堆栈操作;所必需的堆栈操作; 在一个文件中,如果某个函数的局部变量和全局变量同名,则在这在一个文件中,如果某个函数的局部变量和全局变量同名,则在这个局部变量的作用范围内局部变量不起作用,全局变量起作用;个局部变量的作用范围内局部变量不起作用,全局变量起作用; 全局变量一直存在,占用了大量的内存单元,并且加大了程序的耦全局变量一直存在,占用了大量的内存单元,并且加大了程序的耦合性,不利于程序的移植或复用。

      合性,不利于程序的移植或复用  静态局部变量的作用范围仅仅是在定义的函数内,不静态局部变量的作用范围仅仅是在定义的函数内,不能被其他的函数访问,全局变量的作用范围是整个程序,能被其他的函数访问,全局变量的作用范围是整个程序,静态全局变量的作用范围是该变量定义的文件;静态全局变量的作用范围是该变量定义的文件; 静态局部变量是在函数内部定义,全局变量是在所有静态局部变量是在函数内部定义,全局变量是在所有函数外定义;函数外定义; 静态局部变量仅仅在第静态局部变量仅仅在第1 1次调用时被初始化,再次调用次调用时被初始化,再次调用时使用上次调用结束时的数值,全局变量在程序运行时时使用上次调用结束时的数值,全局变量在程序运行时建立,值为最近一条访问该全局变量的语句执行的结果建立,值为最近一条访问该全局变量的语句执行的结果 另外,另外,mainmain函数虽然是函数虽然是.c.c文件的主文件,但也是一文件的主文件,但也是一个函数,在其内部定义的变量也属于局部变量全局变个函数,在其内部定义的变量也属于局部变量全局变量一般在量一般在.c.c文件的开始部分定义或在文件的开始部分定义或在.h.h文件中定义,由文件中定义,由.c.c文件引用。

      文件引用C51C51语言程序多使用全局变量传递参数,语言程序多使用全局变量传递参数,因为这样可以降低程序处理的难度,加快程序执行的速因为这样可以降低程序处理的难度,加快程序执行的速度,提高程序的时效性度,提高程序的时效性 3.2 C513.2 C51对单片机资源的控制对单片机资源的控制3.2.1 3.2.1 特殊功能寄存器的特殊功能寄存器的C51C51语言定义语言定义3.2.2 3.2.2 绝对地址的访问绝对地址的访问3.2.3 3.2.3 位变量的位变量的C51C51语言定义语言定义 3.2.1 3.2.1 特殊功能寄存器的特殊功能寄存器的C51C51定义定义2121个特殊功能寄存器两种方式:个特殊功能寄存器两种方式:1 1.使用关键字.使用关键字sfrsfr定义定义 sfr sfr 特功器名字特功器名字= =特功器地址特功器地址; ; sfr SCON=0x98; sfr SCON=0x98; /* /*串口控制寄存器地址串口控制寄存器地址98H*/98H*/ sfr TMOD=0X89; sfr TMOD=0X89; /* /*定时器定时器/ /计数器方式控制寄存器地址计数器方式控制寄存器地址9H*/9H*/2 2.通过头文件访问.通过头文件访问SFRSFR#include #include ////使用的单片机为使用的单片机为IntelIntel公司的公司的MCS-51MCS-51void main(void)void main(void){ {TL0=0xb0; TL0=0xb0; TH0=0x3c;TH0=0x3c;TR0=1; TR0=1; ////启动定时器启动定时器0 0...}...} 3.SFR中位定义—3种方式((1 1〕第〕第1 1种方法种方法sbit sbit 位名位名= =特殊功能寄存器名特殊功能寄存器名^ ^位置位置; ;((2 2〕第〕第2 2种方法种方法sbit sbit 位名位名= =字节地址字节地址^ ^位置位置; ;((3 3〕第〕第3 3种方法种方法sbit sbit 位名位名= =位地址位地址; ;例:例:unsigned char bdata flag;sbit flag0=flag^0;sfr P1=0x90;sbit P1_0=P1^0;sbit P1_1=P1^1;sbit P1_6=P1^6;sbit P1_7=P1^7;P60 P60 例例3-3 sbit3-3 sbit型变量的定义型变量的定义P60 P60 例例3-4 3-4 片内片内I/OI/O口及其位的定义口及其位的定义 3.2.2 绝对地址的访问包括:片内包括:片内RAMRAM、片外、片外RAMRAM及及I/OI/O口。

      可以有两种方式:口可以有两种方式:用用#include#include可使用其中声明的宏来访问绝对地址,可使用其中声明的宏来访问绝对地址, DBYTE DBYTE以字节形式对以字节形式对datadata区寻址;区寻址; DWORD DWORD以字形式对以字形式对datadata区寻址;区寻址; XBYTE XBYTE以字节形式对以字节形式对xdataxdata区寻址;区寻址; XWORD XWORD以字形式对以字形式对xdataxdata区寻址;区寻址;另外:另外:  CBYTE CBYTE以字节形式对以字节形式对codecode区寻址;区寻址;  CWORD CWORD以字形式对以字形式对codecode区寻址;区寻址;  PBYTE PBYTE以字节形式对以字节形式对pdatapdata区寻址;区寻址;  PWORD PWORD以字形式对以字形式对pdatapdata区寻址 例例3-5( P61 )3-5( P61 )#include #include #define PA XBYTE[0xffec]#define PA XBYTE[0xffec]////将将PAPA定义为外部定义为外部I/OI/O口,地址为口,地址为0xffec0xffec#define NRAM DBYTE[0x40]#define NRAM DBYTE[0x40]/*/*将将NRAMNRAM定义为片内定义为片内RAMRAM,地址为,地址为40H40H,长度为,长度为8 8位位*/*/ void main( ) void main( ){ {PA=0x3A;PA=0x3A;NRAM=0x01;NRAM=0x01; } }#include#include#define PORTA XBYTE[0xFFC0]#define PORTA XBYTE[0xFFC0]/*/*将将PORTPORT定义为外部定义为外部I/OI/O口,地址为口,地址为0xFFC00xFFC0,长度为,长度为8 8位位*/*/#define NRAM DBYTE[0x40]#define NRAM DBYTE[0x40]/*/*将将NRAMNRAM定义为片内定义为片内RAMRAM,地址为,地址为40H40H,长度为,长度为8 8位位*/*/ 例例3-63-6〔〔P62)P62)data unsigned char x1 _at_ 0x40;data unsigned char x1 _at_ 0x40;/*/*在在datadata区定义字节变量区定义字节变量x1,x1,它的地址为它的地址为40H*/40H*/xdata unsigned int x2 _at_ 0x2000;xdata unsigned int x2 _at_ 0x2000; /* /*在在xdataxdata区定义字变量区定义字变量x2,x2,它的地址为它的地址为2000H*/2000H*/void main(void)void main(void){ {x1=0xff;x1=0xff;x2=0x1234H;x2=0x1234H;......while(1); }while(1); }可以使用关键字可以使用关键字_at__at_对指定的存储器空间的绝对地址进行访问。

      对指定的存储器空间的绝对地址进行访问一般格式如下:一般格式如下: 【存储类型】【存储类型】 数据类型符数据类型符 变量名变量名 _at_ _at_ 地址常数地址常数; ; 3.2.3 3.2.3 位变量的位变量的C51C51语言定义语言定义1 1.位变量的.位变量的C51C51语言定义语言定义 采用关键字采用关键字bitbit进行定义例如:进行定义例如: bit direction_bit; bit direction_bit;/* /* 将将direction_bitdirection_bit定义为位变量定义为位变量 */ */ bit lock_pointer; bit lock_pointer;/* /* 将将lock_pointerlock_pointer定义为位变量定义为位变量 */ */ bit display_invers; bit display_invers;/* /* 将将display_inversdisplay_invers定义为位变量定义为位变量 */ */ 2 2.可位寻址对象.可位寻址对象 可位寻址对象指可以字节或位寻址的对象。

      该对象应位于可位寻址对象指可以字节或位寻址的对象该对象应位于80518051片内可位寻址片内可位寻址RAMRAM区中,区中,C51C51语言编译器允许数据类型为语言编译器允许数据类型为idataidata的对象放入的对象放入80518051片内可位寻址片内可位寻址RAMRAM区 位变量的存储类型只能是位变量的存储类型只能是bdatabdata 在程序设计时,对于可位寻址的对象,即可以字节寻址也可以位寻址的变量,在程序设计时,对于可位寻址的对象,即可以字节寻址也可以位寻址的变量,但其存储类型只能是但其存储类型只能是bdatabdata 使用时应先说明字节变量的数据类型和存储类型,然后可使用使用时应先说明字节变量的数据类型和存储类型,然后可使用bitbit定义可独立寻定义可独立寻址访问的对象位例如:址访问的对象位例如:bdata int ibase; /* ibase定义为定义为bdata整型变量整型变量 */bdata char bary[4]; /* bary定义为定义为bdata字符型数组字符型数组 */sbit mybit0=ibase^0; /* mybit0定义为定义为ibase的第的第0位位*/sbit mybit15=ibase^15; /* mybit15定义位定义位ibase的第的第15位位*/sbit Ary07=bary[0]^7; /* Ary07定义为定义为bary[0]的第的第7位位*/sbit Ary37=bary[3]^7; /*Ary37定义为定义为bary[3]的第的第7位位*/Ary37=0; /* bary[3]的第的第7位赋值为位赋值为0 */bary[3]='a'; /* 字节寻址:字节寻址:bary[3]赋值为赋值为'a' */ sbit定义要求基址对象的存储类型为定义要求基址对象的存储类型为bdata,只有这样其特殊位定义〔,只有这样其特殊位定义〔sbit〕是合〕是合法的。

      法的 位置(位置('^'操作符〕后的最大值依赖于指定的基类型,对于操作符〕后的最大值依赖于指定的基类型,对于char/uchar而言而言是是0~~7,对于,对于int/uint而言是而言是0~~15,对于,对于long/ulong而言是而言是0~~31 3.3 C513.3 C51的基本运算与流程控制的基本运算与流程控制3.3.1 3.3.1 基本运算基本运算3.3.2 3.3.2 选择〔分支〕控制语句选择〔分支〕控制语句3.3.3 3.3.3 循环结构流程控制语句循环结构流程控制语句3.3.4 break3.3.4 break语句、语句、continuecontinue语句、语句、gotogoto语句语句 3.3.1 基本运算〔运算符)运算符是表示特定的算术或逻辑运算的符号,也称操作符运算符是表示特定的算术或逻辑运算的符号,也称操作符把需要进行运算的各个量通过运算符连接起来,便构成表达式把需要进行运算的各个量通过运算符连接起来,便构成表达式算术运算符、关系运算符、算术运算符、关系运算符、逻辑运算符、位运算符、逻辑运算符、位运算符、赋值运算符、特殊运算符赋值运算符、特殊运算符算术运算的操作符:算术运算的操作符:+ + (加法运算符)、(加法运算符)、- - (减法运算符)(减法运算符)* * (乘法运算符)、(乘法运算符)、/ / (除法运算符)(除法运算符)%% (模运算或取余运算符)(模运算或取余运算符)++++为自增运算符为自增运算符- -- -为自减运算符。

      为自减运算符 注意:注意:/ /:结果的整数部分;:结果的整数部分;% %:结果的余数部分;:结果的余数部分;- -::除进行减法外,还可以进行取负操作除进行减法外,还可以进行取负操作表示:自增表示操作数加操作数加1 1X++ X++ 等同于等同于X=X+1X=X+1X ++X 表示先加表示先加1 1,再取,再取值;值;X++X++表示先取值,再加表示先取值,再加1 1例例3-83-8:自增和自减运算符的程序:自增和自减运算符的程序#include #include void main( )void main( ){ int x, y, z1, z2; x=10; y=21;{ int x, y, z1, z2; x=10; y=21; z1=(x++)+(x++); z1=(x++)+(x++); printf(“x=%d, z1=%d\n”, x, z1); printf(“x=%d, z1=%d\n”, x, z1); z2=(++y)+(++y); z2=(++y)+(++y); printf(“y=%d, z2=%d\n”, y, z2); printf(“y=%d, z2=%d\n”, y, z2); } } 二、关系运算—成立或不成立主要用于比较操作数的大小关系。

      主要用于比较操作数的大小关系包括:包括:< < (小于)、(小于)、<= <= (小于等于)、(小于等于)、> > (大于)、(大于)、>= >= (大于等(大于等于)、于)、= = = = (等于)、!(等于)、!= = (不等于)(不等于)看关系是否成立结果:看关系是否成立结果:0 0或或1 1例3-9 关系运算符运算的程序示例#include void main( ){ int a, b, c, d; a=-2.3>0; b=71==32; c=7!=0; d=-12<=0; printf(“a=%d, b=%d, c=%d,d=%d\n”, a, b, c, d);} 三、逻辑运算—结果是真或假进行逻辑运算的操作符包括:进行逻辑运算的操作符包括:&& && (逻辑与)、(逻辑与)、|| || (逻辑或)、!(逻辑非)(逻辑或)、!(逻辑非)看结果是否为真结果:看结果是否为真结果:0 0或或1 1例3-10 逻辑运算的程序示例#include void main( ){ int a, b, c, d, e ; a=!0 ; b=15&&22 ; c=35&&0 ; d=17.3||0 ; e=17.3||2.6 ;printf(“a=%d, b=%d,c=%d, d=%d, e=%d\n”, a, b, c, d, e);} 四、位运算四、位运算将两个操作数按二进制数展开,然后对应位进行逻辑运算。

      包括:将两个操作数按二进制数展开,然后对应位进行逻辑运算包括:& &(按位与)、(按位与)、| |(按位或)、^(按位异或)、(按位或)、^(按位异或)、~(按位取反)、~(按位取反)、<<<<(位左移)、(位左移)、>>>>(位右移)(位右移)位运算的操作对象只能是整型和字符型数据这些位运算和汇编语言位运算的操作对象只能是整型和字符型数据这些位运算和汇编语言中的位操作指令十分类似中的位操作指令十分类似位操作指令是单片机的重要特点,所以位运算在位操作指令是单片机的重要特点,所以位运算在C51C51语言控制类程序设语言控制类程序设计中的应用比较普遍计中的应用比较普遍例例3-11 3-11 位运算程序示例将位运算程序示例将A A值循环右移值循环右移2 2位位main( )main( ){ {unsigned char a=0xc3,b,c;unsigned char a=0xc3,b,c;int n=2;int n=2;b=a<<(8-n);b=a<<(8-n);c=a>>n;c=a>>n;a=c|b;a=c|b;} } 例3-12 位运算程序示例#include void main( ){ int a, b,c; a=23; b=217; c=a&b; printf(“a&b=%d\n”, c); c=a|b; printf(“a|b=%d\n”, c); c=a^b ; printf(“a^b=%d\n”, c); c=~a ; printf(“~a =%d\n”, c); c=a<<3 ; printf(“a<<3=%d\n”, c); c= b>>2 ; printf(“b>>2=%d\n”, c);} 五、赋值运算五、赋值运算变量名变量名= =表达式表达式; ;例如:例如:a=(b=4)+(c=6);a=(b=4)+(c=6);该表达式的值为该表达式的值为1010,变量,变量a a的值为的值为1010。

      复合赋值运算符:复合赋值运算符: 赋值符号前加上其他运算符构成复合运算符赋值符号前加上其他运算符构成复合运算符C51C51语言提供以语言提供以下下1010种复合运算符:种复合运算符:+=+=,,-=-=,,*=*=,/,/= =,%,%= =,,﹠=﹠=,︱,︱= =,,^=^=,,<<=<<=,,>>=>>=例如:例如:a+=b;a+=b; // //等价于等价于a=(a+b)a=(a+b)x*=a+b; //x*=a+b; //等价于等价于x=(x*(a+b))x=(x*(a+b))a&=b;a&=b; // //等价于等价于a=(a&b)a=(a&b)a<<=4;a<<=4; // //等价于等价于a=(a<<4)a=(a<<4) 算术运算符、逻辑运算符、关系运算符、赋值运算符的优先级 3.3.2 选择〔分支〕控制语句 通过选择结构,可以使计算机具有决策能力,从而使计算机能够按通过选择结构,可以使计算机具有决策能力,从而使计算机能够按照我们的意志在某个特定条件下完成相应的操作,可以照我们的意志在某个特定条件下完成相应的操作,可以““随机应变随机应变””。

      包括:包括:ifif语句、语句、switchswitch语句语句一、IF语句 if if语句用来判定所给定的条件是否满足,根据判定语句用来判定所给定的条件是否满足,根据判定结果决定执行给出的两种操作之一结果决定执行给出的两种操作之一 if if语句的基本结构如下:语句的基本结构如下: if( if(表达式表达式) ) { { 语句语句; }; } 括号中的表达式成立时,程序执行大括号内的语句,括号中的表达式成立时,程序执行大括号内的语句,否则程序跳过大括号中的语句部分而直接执行下面其他否则程序跳过大括号中的语句部分而直接执行下面其他语句C51C51语言提供语言提供3 3种形式的种形式的ifif语句:语句: 形式一: IF(表达式){语句;}if(x>y){ max=x; min=y; } 形式二: IF(表达式){语句1;} ELSE {语句2;}if(x>y) { max=x;}else { min=y;} 形式三:if(if(表达式表达式1){1){语句语句1;}1;}else if(else if(表达式表达式2){2){语句语句2;}2;}else if(else if(表达式表达式3){3){语句语句3;}3;}......else if(else if(表达式表达式m){m){语句语句m;}m;}else {else {语句语句n;}n;}if(x>1000) { y=1; }if(x>1000) { y=1; }else if(x>500) { y=2;}else if(x>500) { y=2;}else if(x>300) { y=3;}else if(x>300) { y=3;}else if(x>100) { y=4;}else if(x>100) { y=4;}else{ y=5;}else{ y=5;} 例3-13 分支编程示例#includemain ( ){ int x,y; scanf("%d",&x); if(x<0) y=-1; else {if (x==0) y=0;else y=1; } printf("x=%%d,y=%%d\n",x,y);} 例3-14:#includevoid main( ){ int a,b; a=200; b=321; if(a==b) {a++;b++; } printf("a=%d,b=%d\n",a,b);} 例3-15:#includevoid main( ){ int a,b; a=12;b=21; if(a==b) { a++;b++; } { a--;b--;} printf("a=%d,b=%d\n",a,b);} 例3-16:#includevoid main( ){ int score; char grade; score=45; if(score>=90) grade='A'; else if(score>=80) grade='B'; else if(score>=70) grade='C'; else if(score>=60) grade='D'; else grade='E'; printf("score=%d,grade=%c\n",score,grade);} 二、SWITCH语句switchswitch语句是多分支选择语句一般形式如下:语句是多分支选择语句一般形式如下:switch(switch(表达式表达式) ){ {case case 常量表达式常量表达式1:{1:{语句语句1;} break;1;} break;case case 常量表达式常量表达式2:{2:{语句语句2;} break;2;} break;......case case 常量表达式常量表达式n:{n:{语句语句n;} break;n;} break;default:{default:{语句语句n+1;}n+1;}} } 例3-17 3.3.3 3.3.3 循环结构流程控制语句循环结构流程控制语句四种形式:四种形式: if goto if goto while while do--while do--while for for 一、基于IF和GOTO构成的循环 1 1、采用、采用ifif和和gotogoto可以构成可以构成““当型〞循环当型〞循环loop: if(loop: if(表达式表达式) ) { {语句语句; ;goto loop;goto loop; } }2 2、采用、采用ifif和和gotogoto也可以构成也可以构成““直到型〞循环程序直到型〞循环程序 loop: {loop: {语句语句; ;if(if(表达式表达式) goto loop;) goto loop; } }3 3、、gotogoto语句为无条件转向语句语句为无条件转向语句 goto goto 语句标号语句标号; ; 二、WHILE while(表达式表达式) { 语句语句; } 例:#includevoid main( ){ int i, s; i=100; s=0; while(i>0) { s=s+i; i=i-1; } printf(“1+2+…+100=%d\n”,s);}注意:注意:先判断,后执行;先判断,后执行;如果循环体内只有一个语句,可以不用如果循环体内只有一个语句,可以不用{ }While循环体循环体{ }后无分号;后无分号; 三、DO-WHILEdo{ 语句语句; } while (表达式)(表达式); 例:#includevoid main( ){ int i, s; i=100;s=0; do { s=s+i; i=i-1; } while(i>0); printf(“1+2+…+100=%d\n”,s);}注意:注意:先执行先执行, 后判断;后判断;如果循环体内只有一个语句,可以不用如果循环体内只有一个语句,可以不用{ }循环体循环体{ }后无分号;后无分号;while(表达式〕后的分号不能省;表达式〕后的分号不能省; 四、FORfor(for(表达式表达式1;1;表达式表达式2;2;表达式表达式3)3){ {语句语句; }; }for(y=0for(y=0;;y<=99y<=99;;y=y+3)y=y+3){ {delay(33);delay(33); px= px=~~px;px;} } 例:#includevoid main( ){ int i, s; s=0; for(i=0;i<=100;i++) { s=s+i; } printf(“1+2+…+100=%d\n”,s);}注意:注意:3个表达式都是可选项,可以任意省略,但个表达式都是可选项,可以任意省略,但“;;”不能省。

      不能省省省1是不对循环变量赋初值;是不对循环变量赋初值;省省2是不判断循环条件的真假;是不判断循环条件的真假;省省3是不对循环变量操作是不对循环变量操作for( ; ;)表示无限循环表示无限循环 无限循环的实现: ((1 1〕〕for(; ;)for(; ;){ { 代码段;代码段;} }((2 2〕〕while(1)while(1) { { 代码段;代码段; } }((3 3〕〕do{ do{ 代码段;代码段; } } while while〔〔1 1);); 3.3.4 BREAK3.3.4 BREAK语句、语句、CONTINUECONTINUE语句、语句、GOTOGOTO语语句句在循环语句执行过程中,在循环语句执行过程中, 如果需要在满足循环判定条件的情况下跳出代码段,可以使用如果需要在满足循环判定条件的情况下跳出代码段,可以使用breakbreak或或continuecontinue语句;语句; 如果要从任意地方跳转到代码的某个地方,可以使用如果要从任意地方跳转到代码的某个地方,可以使用gotogoto语句1、BREAKbreakbreak语句用于从循环代码中退出,然后执行循环语句之后的语句,语句用于从循环代码中退出,然后执行循环语句之后的语句,不再进入循环不再进入循环 。

      形式:形式: break break;;注意:一个注意:一个breakbreak只能跳出一层循环只能跳出一层循环 例:#includevoid main( ){ int i, s; i=0; s=0; while(1) { s=s+iI; i++; if(i>100) break; } printf(“1+2+…+100=%d\n”,s);} 2、CONTINUE continue continue语句用于退出当前循环,不再执行本轮循环,程序代码语句用于退出当前循环,不再执行本轮循环,程序代码从下一轮循环开始执行,直到判断条件不满足为止从下一轮循环开始执行,直到判断条件不满足为止与与breakbreak的区别是该语句不是退出整个循环形式:的区别是该语句不是退出整个循环形式: continue; continue;例:例:#includevoid main( ){ char ch[ ]={‘a’,’ B’,’c’,’D’,’e’,’F’}; int i=-1; while(i<5) { if ( ch[i]>=‘a’&& ch[i]<=‘z’) continue; printf(“ch[%d]=%c\n”, i, char[i] ); }} 3、GOTO goto goto是一个无条件转移语句。

      当执行是一个无条件转移语句当执行gotogoto语句时,将程序指针跳转到语句时,将程序指针跳转到gotogoto给出给出的下一条代码,基本格式如下:的下一条代码,基本格式如下: goto goto 标号标号; ;例:例:void main(void)void main(void){ {unsigned char counter;unsigned char counter;int sum ; sum=0;int sum ; sum=0;sumadd: sum=sum+counter;sumadd: sum=sum+counter; counter++; counter++; if(counter<101) if(counter<101) { {goto sumadd;goto sumadd; } }} } 3.4 C51的数组与指针 C51 C51语言的构造数据类型主要有数组、指针和结构等在单片机系统语言的构造数据类型主要有数组、指针和结构等在单片机系统中,数组的应用比较广泛,指针则次之,结构用的相对较少。

      这里我们中,数组的应用比较广泛,指针则次之,结构用的相对较少这里我们只讨论数组和指针只讨论数组和指针3.4.1 数组 数组是同类型变量的一个有序集合数组是同类型变量的一个有序集合 数组用一个名字来标识,称为数组名数组用一个名字来标识,称为数组名 数组中的每个变量称为数组元素数组中的每个变量称为数组元素 数组有一维、二维、三维和多维数组之分数组有一维、二维、三维和多维数组之分C51C51语言中常用的一维、二语言中常用的一维、二维数组和字符数组维数组和字符数组 数组中各元素的顺序用下标表示,下标为数组中各元素的顺序用下标表示,下标为N N的元素可以表示为数组名的元素可以表示为数组名[N][N]改变改变[ ][ ]中的下标就可以访问数组中所有的元素中的下标就可以访问数组中所有的元素 1.一维数组 类型说明符类型说明符 数组名数组名[ [元素个数元素个数];]; int demo1[10]; int demo1[10];初始化:初始化: int a[5]={1,2,3,4,5}; int a[5]={1,2,3,4,5}; int b[6]={1,2,6}; int b[6]={1,2,6}; 例3-23: 2.二维数组或多维数组类型说明符类型说明符 数组名数组名[ [行数行数][][列数列数];];float demo2[3][4];float demo2[3][4];//demo2 //demo2 数组有数组有3 3 行行4 4 列共列共12 12 个实型元素个实型元素int a[3][4]=int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};{{1,2,3,4},{5,6,7,8},{9,10,11,12}};////全部初始化全部初始化3.字符数组若一个数组的元素是字符型的,则该数组就是一个字符数组。

      例如:若一个数组的元素是字符型的,则该数组就是一个字符数组例如: char a[12]={"Chong Qing"}; char a[12]={"Chong Qing"};////字符数组字符数组 char add[3][6]= char add[3][6]={"weight","height","width"};{"weight","height","width"};////字符串数组字符串数组 4.查表#define uchar unsigned char#define uchar unsigned charuchar code tempt[]={32,34,36,37,39,41};uchar code tempt[]={32,34,36,37,39,41};/*/*数组数组, ,设置在设置在EPROMEPROM中中, ,长度为实际输入的数值数长度为实际输入的数值数 */ */uchar ftoc(uchar degc)uchar ftoc(uchar degc){ {return tempt[degc];}return tempt[degc];}void main( )void main( ){ {uchar x;uchar x;x=ftoc(5);/* x=ftoc(5);/* 得到与得到与5℃5℃相应的华氏温度值相应的华氏温度值 */ */} }共阴极共阴极LEDLED的显示字符段码表的显示字符段码表 char code char code SEG[11]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,SEG[11]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};0x6f}; 3.5 C51函数函数是指能够执行特定功能和任务的程序代码段。

      函数是指能够执行特定功能和任务的程序代码段 一个完整的一个完整的C51C51程序是由一个主函数和若干个其他程序是由一个主函数和若干个其他函数组成函数组成 主函数是主函数是main( )main( )函数有且只有一个函数有且只有一个main( )main( )函数使用函数时注意: 函数数目不限制;函数数目不限制; main( ) main( )函数是主函数,可以调用其他函数,而不函数是主函数,可以调用其他函数,而不允许被其他函数调用允许被其他函数调用 除主函数外,其他函数之间允许互相调用除主函数外,其他函数之间允许互相调用 一、函数分类可以从不同的角度分类:可以从不同的角度分类:((1 1〕有无返回值角度〕有无返回值角度((2 2〕数据传送角度〕数据传送角度((3 3〕函数定义角度〕函数定义角度(1〕有无返回值角度无返回值函数、有返回值函数无返回值函数、有返回值函数无返回值函数:执行完成后不向主调函数返回函数值类型说明符为:无返回值函数:执行完成后不向主调函数返回函数值类型说明符为:voidvoid有返回值函数:执行完成后向主调函数返回一个执行的结果有返回值函数:执行完成后向主调函数返回一个执行的结果——返回值。

      返回值 ((2 2〕数据传送角度〕数据传送角度有参函数和无参函数有参函数和无参函数无参函数:主调函数和被调函数之间不进行参数的传递无参函数:主调函数和被调函数之间不进行参数的传递有参函数:主调函数和被调函数之间存在参数的传递有参函数:主调函数和被调函数之间存在参数的传递形式参数形式参数和实际参数和实际参数((3 3〕函数定义角度〕函数定义角度主函数、自定义函数、库函数主函数、自定义函数、库函数自定义函数:是用户根据自己的需要而编写的函数从函数定义的自定义函数:是用户根据自己的需要而编写的函数从函数定义的形式上可以将其划分无参函数、有参函数和空函数形式上可以将其划分无参函数、有参函数和空函数  无参函数无参函数  有参函数有参函数  空函数空函数 二、函数定义有参函数和无参函数定义有参函数和无参函数定义1 1〕无参函数的定义方法〕无参函数的定义方法—P60—P60无参函数的定义形式为:无参函数的定义形式为:返回值类型标识符返回值类型标识符 函数名函数名( )( ){ {函数体函数体; ;} }无参函数一般不带返回值,因此函数返回值类型标识符可以省略。

      无参函数一般不带返回值,因此函数返回值类型标识符可以省略2 2〕有参函数的定义方法〕有参函数的定义方法有参函数的定义形式为:有参函数的定义形式为:P61P61返回值类型标识符返回值类型标识符 函数名函数名( (形式参数列表形式参数列表) )形式参数说明;形式参数说明;{ {函数体函数体; ;} } 函数定义举例:函数定义举例:#include#includeint max(x1,x2)int max(x1,x2)int x1,x2;int x1,x2;{ if(x1>x2){ if(x1>x2) return x1; return x1; else else return x2; } return x2; }void main( )void main( ){ int x1=17;x2=9;{ int x1=17;x2=9; printf(“x1=%d,x2=%d”,x1,x2); printf(“x1=%d,x2=%d”,x1,x2); printf(“max(x1,x2)=%d\n”,max(x1,x2)); } printf(“max(x1,x2)=%d\n”,max(x1,x2)); } 在程序中定义函数应注意:(1)(1)可将形参类型说明放在形参列表中,如:可将形参类型说明放在形参列表中,如:int max(int x1,int x2)int max(int x1,int x2){……..}{……..}(2)(2)函数位置与声明函数位置与声明3.5.2 3.5.2 中断函数中断函数函数类型函数类型 函数名函数名 interrupt n using n interrupt n using n 3.6 C513.6 C51的预处理命令的预处理命令 C51 C51语言中提供了各种预处理命令,其作用类似于语言中提供了各种预处理命令,其作用类似于汇编程序中的伪指令。

      汇编程序中的伪指令 预处理命令通常只进行一些符号的处理,并不执行预处理命令通常只进行一些符号的处理,并不执行具体的硬件操作具体的硬件操作C51C51的预处理命令包括文件包含命令、的预处理命令包括文件包含命令、宏定义指令条件编译指令预处理命令前要加一个宏定义指令条件编译指令预处理命令前要加一个“#”“#”3.6.1 3.6.1 文件包含文件包含#include<#include<文件名文件名> > 或或 #include " #include "文件名文件名““#include ”myfile.h ”#include ”myfile.h ” // //引用自定义文件引用自定义文件myfilemyfile#include #include ////引用库函数文件引用库函数文件stdiostdio#include #include // //引用寄存器文件引用寄存器文件#define MATH_FILE ”c\keil\inc\math1.h”#define MATH_FILE ”c\keil\inc\math1.h”/*/*宏定义自定义宏定义自定义文件文件MATH_FILE */MATH_FILE */#include MATH_FILE //#include MATH_FILE //引用自定义文件引用自定义文件MATH_FILEMATH_FILE 例:文件包含指令的程序示例例:文件包含指令的程序示例 #include#include#include#include〞〞myfile1.h”myfile1.h”void main( )void main( ){ {int i,sum=0;int i,sum=0;for(i=0;i<=20;i++)for(i=0;i<=20;i++){ {sum=sum+fun(i);}sum=sum+fun(i);}printf(“sum=%d\n”,sum);}printf(“sum=%d\n”,sum);}其中其中myfile1.hmyfile1.h文件的内容如下:文件的内容如下:int fun(int i)int fun(int i){ {int mu1;int mu1;mu1=i*i;return mu1;mu1=i*i;return mu1;} } 在使用#INCLUDE命令时,应注意以下几点: #include#include命令出现在程序中的位置,决定了被命令出现在程序中的位置,决定了被包含的文件就从此处引入源文件。

      包含的文件就从此处引入源文件 一个一个#include#include命令只能指定一个被包含文件,命令只能指定一个被包含文件,如果程序中需要包含多个文件则需要使用多个如果程序中需要包含多个文件则需要使用多个包含命令包含命令 采用采用< <文件名文件名> >格式时,在头文件目录中查找指格式时,在头文件目录中查找指定文件,采用定文件,采用" "文件名文件名" "格式时,在当前目录中格式时,在当前目录中查找指定文件查找指定文件 #include#include命令末尾不需要分号命令末尾不需要分号““;;””完毕 #include#include命令只能调入命令只能调入ASCIIASCII文本文件文本文件 3.6.2 宏定义指令1 1.简单的宏定义.简单的宏定义简单的宏定义格式为:简单的宏定义格式为:#define #define 宏替换名宏替换名 宏替换体宏替换体3.6.3 3.6.3 条件编译条件编译1 1..#if#if型型格式如下:格式如下:#if #if 常量表达式常量表达式代码代码1;1;#else#else代码代码2;2;#endif#endif 。

      点击阅读更多内容
      关于金锄头网 - 版权申诉 - 免责声明 - 诚邀英才 - 联系我们
      手机版 | 川公网安备 51140202000112号 | 经营许可证(蜀ICP备13022795号)
      ©2008-2016 by Sichuan Goldhoe Inc. All Rights Reserved.