单片机.docx

上传人:b****8 文档编号:28294023 上传时间:2023-07-10 格式:DOCX 页数:122 大小:244.94KB
下载 相关 举报
单片机.docx_第1页
第1页 / 共122页
单片机.docx_第2页
第2页 / 共122页
单片机.docx_第3页
第3页 / 共122页
单片机.docx_第4页
第4页 / 共122页
单片机.docx_第5页
第5页 / 共122页
点击查看更多>>
下载资源
资源描述

单片机.docx

《单片机.docx》由会员分享,可在线阅读,更多相关《单片机.docx(122页珍藏版)》请在冰豆网上搜索。

单片机.docx

单片机

单片机课程体系改革总体规划

初学单片机几个不易掌握的概念

一、总线:

我们知道,一个电路总是由元器件通过电线连接而成的,在模拟电路中,连线并不成为一个问题,因为各器件间一般是串行关系,各器件之间的连线并不很多,但计算机电路却不一样,它是以微处理器为核心,各器件都要与微处理器相连,各器件之间的工作必须相互协调,所以就需要的连线就很多了,如果仍如同模拟电路一样,在各微处理器和各器件间单独连线,则线的数量将多得惊人,所以在微处理机中引入了总线的概念,各个器件共同享用连线,所有器件的8根数据线全部接到8根公用的线上,即相当于各个器件并联起来,但仅这样还不行,如果有两个器件同时送出数据,一个为0,一个为1,那么,接收方接收到的究竟是什么呢?

这种情况是不允许的,所以要通过控制线进行控制,使器件分时工作,任何时候只能有一个器件发送数据(可以有多个器件同时接收)。

器件的数据线也就被称为数据总线,器件所有的控制线被称为控制总线。

在单片机内部或者外部存储器及其它器件中有存储单元,这些存储单元要被分配地址,才能使用,分配地址当然也是以电信号的形式给出的,由于存储单元比较多,所以,用于地址分配的线也较多,这些线被称为地址总线。

二、数据、地址、指令:

之所以将这三者放在一起,是因为这三者的本质都是一样的──数字,或者说都是一串‘0’和‘1’组成的序列。

换言之,地址、指令也都是数据。

指令:

由单片机芯片的设计者规定的一种数字,它与我们常用的指令助记符有着严格的一一对应关系,不可以由单片机的开发者更改。

地址:

是寻找单片机内部、外部的存储单元、输入输出口的依据,内部单元的地址值已由芯片设计者规定好,不可更改,外部的单元可以由单片机开发者自行决定,但有一些地址单元是一定要有的(详见程序的执行过程)。

数据:

这是由微处理机处理的对象,在各种不同的应用电路中各不相同,一般而言,被处理的数据可能有这么几种情况:

1·地址(如MOVDPTR,#1000H),即地址1000H送入DPTR。

2·方式字或控制字(如MOVTMOD,#3),3即是控制字。

3·常数(如MOVTH0,#10H)10H即定时常数。

4·实际输出值(如P1口接彩灯,要灯全亮,则执行指令:

MOVP1,#0FFH,要灯全暗,则执行指令:

MOVP1,#00H)这里0FFH和00H都是实际输出值。

又如用于LED的字形码,也是实际输出的值。

理解了地址、指令的本质,就不难理解程序运行过程中为什么会跑飞,会把数据当成指令来执行了。

三、P0口、P2口和P3的第二功能用法初学时往往对P0口、P2口和P3口的第二功能用法迷惑不解,认为第二功能和原功能之间要有一个切换的过程,或者说要有一条指令,事实上,各端口的第二功能完全是自动的,不需要用指令来转换。

如P3.6、P3.7分别是WR、RD信号,当微片理机外接RAM或有外部I/O口时,它们被用作第二功能,不能作为通用I/O口使用,只要一微处理机一执行到MOVX指令,就会有相应的信号从P3.6或P3.7送出,不需要事先用指令说明。

事实上‘不能作为通用I/O口使用’也并不是‘不能’而是(使用者)‘不会’将其作为通用I/O口使用。

你完全可以在指令中按排一条SETBP3.7的指令,并且当单片机执行到这条指令时,也会使P3.7变为高电平,但使用者不会这么去做,因为这通常这会导致系统的崩溃(即死机)。

四、程序的执行过程单片机在通电复位后8051内的程序计数器(PC)中的值为‘0000’,所以程序总是从‘0000’单元开始执行,也就是说:

在系统的ROM中一定要存在‘0000’这个单元,并且在‘0000’单元中存放的一定是一条指令。

五、堆栈堆栈是一个区域,是用来存放数据的,这个区域本身没有任何特殊之处,就是内部RAM的一部份,特殊的是它存放和取用数据的方式,即所谓的‘先进后出,后进先出’,并且堆栈有特殊的数据传输指令,即‘PUSH’和‘POP’,有一个特殊的专为其服务的单元,即堆栈指针SP,每当执一次PUSH指令时,SP就(在原来值的基础上)自动加1,每当执行一次POP指令,SP就(在原来值的基础上)自动减1。

由于SP中的值可以用指令加以改变,所以只要在程序开始阶段更改了SP的值,就可以把堆栈设置在规定的内存单元中,如在程序开始时,用一条MOVSP,#5FH指令,就时把堆栈设置在从内存单元60H开始的单元中。

一般程序的开头总有这么一条设置堆栈指针的指令,因为开机时,SP的初始值为07H,这样就使堆栈从08H单元开始往后,而08H到1FH这个区域正是8031的第二、三、四工作寄存器区,经常要被使用,这会造成数据的浑乱。

不同作者编写程序时,初始化堆栈指令也不完全相同,这是作者的习惯问题。

当设置好堆栈区后,并不意味着该区域成为一种专用内存,它还是可以象普通内存区域一样使用,只是一般情况下编程者不会把它当成普通内存用了。

六、单片机的开发过程这里所说的开发过程并不是一般书中所说的从任务分析开始,我们假设已设计并制作好硬件,下面就是编写软件的工作。

在编写软件之前,首先要确定一些常数、地址,事实上这些常数、地址在设计阶段已被直接或间接地确定下来了。

如当某器件的连线设计好后,其地址也就被确定了,当器件的功能被确定下来后,其控制字也就被确定了。

然后用文本编缉器(如EDIT、CCED等)编写软件,编写好后,用编译器对源程序文件编译,查错,直到没有语法错误,除了极简单的程序外,一般应用仿真机对软件进行调试,直到程序运行正确为止。

运行正确后,就可以写片(将程序固化在EPROM中)。

在源程序被编译后,生成了扩展名为HEX的目标文件,一般编程器能够识别这种格式的文件,只要将此文件调入即可写片。

在此,为使大家对整个过程有个认识,举一例说明:

ORG0000H

LJMPSTART

ORG040H

START:

MOVSP,#5FH;设堆栈

LOOP:

NOP

LJMPLOOP;循环

END;结束

表1

:

03000000020040BB

:

0700400075815F000200431F

表2

020040FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF75815F00020043

表3

表1为源程序,表2是汇编后得到的HEX文件,表3是由HEX文件转换成的目标文件,也就是最终写入EPROM的文件,它由编程器转换得到,也可以由HEXBIN一类的程序转换得到。

学过手工汇编者应当不难找出表3与表1的一一对应关系,值得注意的是从020040后开始的一长串‘FF’,直到7581,这是由于伪指令:

ORG040H造成的结果。

七、仿真、仿真机仿真是单片机开发过程中非常重要的一个环节,除了一些极简单的任务,一般产品开发过程中都要进行仿真,仿真的主要目的是进行软件调试,当然借助仿真机,也能进行一些硬件排错。

一块单片机应用电路板包括单片机部份及为达到使用目的而设计的应用电路,仿真就是利用仿真机来代替应用电路板(称目标机)的单片机部份,对应用电路部份进行测试、调试。

仿真有CPU仿真和ROM仿真两种,所谓CPU仿真是指用仿真机代替目标机的CPU,由仿真机向目标机的应用电路部份提供各种信号、数据,进行调试的方法。

这种仿真可以通过单步运行、连续运行等多种方法来运行程序,并能观察到单片机内部的变化,便于改正程序中的错误。

所谓ROM仿真,就是用仿真机代替目标机的ROM,目标机的CPU工作时,从仿真机中读取程序,并执行。

这种仿真其实就是将仿真机当成一片EPROM,只是省去了擦片、写片的麻烦,并没有多少调试手段可言。

通常这是二种不同类型的仿真机,也就是说,一台仿真机不能既做CPU仿真,又做ROM仿真。

可能的情况下,当然以CPU仿真好。

单片机概述

1、何谓单片机一台能够工作的计算机要有这样几个部份构成:

CPU(进行运算、控制)、RAM(数据存储)、ROM(程序存储)、输入/输出设备(例如:

串行口、并行输出口等)。

在个人计算机上这些部份被分成若干块芯片,安装一个称之为主板的印刷线路板上。

而在单片机中,这些部份,全部被做到一块集成电路芯片中了,所以就称为单片(单芯片)机,而且有一些单片机中除了上述部份外,还集成了其它部份如A/D,D/A等。

天!

PC中的CPU一块就要卖几千块钱,这么多东西做在一起,还不得买个天价!

再说这块芯片也得非常大了。

不,价格并不高,从几元人民币到几十元人民币,体积也不大,一般用40脚封装,当然功能多一些单片机也有引脚比较多的,如68引脚,功能少的只有10多个或20多个引脚,有的甚至只8只引脚。

为什么会这样呢?

功能有强弱,打个比方,市场上面有的组合音响一套才卖几百块钱,可是有的一台功放机就要卖好几千。

另外这种芯片的生产量很大,技术也很成熟,51系列的单片机已经做了十几年,所以价格就低了。

既然如此,单片机的功能肯定不强,干吗要学它呢?

话不能这样说,实际工作中并不是任何需要计算机的场合都要求计算机有很高的性能,一个控制电冰箱温度的计算机难道要用PIII?

应用的关键是看是否够用,是否有很好的性能价格比。

所以8051出来十多年,依然没有被淘汰,还在不断的发展中。

2、MCS51单片机和8051、8031、89C51等的关系

我们平常老是讲8051,又有什么8031,现在又有89C51,它们之间究竟是什么关系?

MCS51是指由美国INTEL公司(对了,就是大名鼎鼎的INTEL)生产的一系列单片机的总称,这一系列单片机包括了好些品种,如8031,8051,8751,8032,8052,8752等,其中8051是最早最典型的产品,该系列其它单片机都是在8051的基础上进行功能的增、减、改变而来的,所以人们习惯于用8051来称呼MCS51系列单片机,而8031是前些年在我国最流行的单片机,所以很多场合会看到8031的名称。

INTEL公司将MCS51的核心技术授权给了很多其它公司,所以有很多公司在做以8051为核心的单片机,当然,功能或多或少有些改变,以满足不同的需求,其中89C51就是这几年在我国非常流行的单片机,它是由美国ATMEL公司开发生产的。

以后我们将用89C51来完成一系列的实验。

 

片机的内部、外部结构

(一)

拿到一块芯片,想要使用它,首先必须要知道怎样连线,我们用的一块称之为89C51的芯片,下面我们就看一下如何给它连线。

1、电源:

这当然是必不可少的了。

单片机使用的是5V电源,其中正极接40引脚,负极(地)接20引脚。

2、振蒎电路:

单片机是一种时序电路,必须提供脉冲信号才能正常工作,在单片机内部已集成了振荡器,使用晶体振荡器,接18、19脚。

只要买来晶振,电容,连上就可以了,按图1接上即可。

3、复位引脚:

按图1中画法连好,至于复位是何含义及为何需要复要复位,在单片机功能中介绍。

4、EA引脚:

EA引脚接到正电源端。

至此,一个单片机就接好,通上电,单片机就开始工作了。

图1

二、任务分析

我们的第一个任务是要用单片机点亮一只发光二极管LED,显然,这个LED必须要和单片机的某个引脚相连,否则单片机就没法控制它了,那么和哪个引脚相连呢?

单片机上除了刚才用掉的5个引脚,还有35个,我们将这个LED和1脚相连。

(见图1,其中R1是限流电阻)

按照这个图的接法,当1脚是高电平时,LED不亮,只有1脚是低电平时,LED才发亮。

因此要1脚我们要能够控制,也就是说,我们要能够让1引脚按要求变为高或低电平。

即然我们要控制1脚,就得给它起个名字,总不能就叫它一脚吧?

叫它什么名字呢?

设计51芯片的INTEL公司已经起好了,就叫它P1.0,这是规定,不可以由我们来更改。

名字有了,我们又怎样让它变'高'或变'低'呢?

叫人做事,说一声就可以,这叫发布命令,要计算机做事,也得要向计算机发命令,计算机能听得懂的命令称之为计算机的指令。

让一个引脚输出高电平的指令是SETB,让一个引脚输出低电平的指令是CLR。

因此,我们要P1.0输出高电平,只要写SETBP1.0,要P1.0输出低电平,只要写CLRP1.0就可以了。

现在我们已经有办法让计算机去将P10输出高或低电平了,但是我们怎样才能计算机执行这条指令呢?

总不能也对计算机也说一声了事吧。

要解决这个问题,还得有几步要走。

第一,计算机看不懂SETBCLR之类的指令,我们得把指令翻译成计算机能懂的方式,再让计算机去读。

计算机能懂什么呢?

它只懂一样东西——数字。

因此我们得把SETBP1.0变为(D2H,90H),把CLRP1.0变为(C2H,90H),至于为什么是这两个数字,这也是由51芯片的设计者--INTEL规定的,我们不去研究。

第二步,在得到这两个数字后,怎样让这两个数字进入单片机的内部呢?

这要借助于一个硬件工具"编程器"。

我们将编程器与电脑连好,运行编程器的软件,然后在编缉区内写入(D2H,90H)见图2,写入……好,拿下片子,把片子插入做好的电路板,接通电源……什么?

灯不亮?

这就对了,因为我们写进去的指令就是让

图2

P10输出高电平,灯当然不亮,要是亮就错了。

现在我们再拨下这块芯片,重新放回到编程器上,将编缉区的内容改为(C2H,90H),也就是CLRP1.0,写片,拿下片子,把片子插进电路板,接电,好,灯亮了。

因为我们写入的()就是让P10输出低电平的指令。

这样我们看到,硬件电路的连线没有做任何改变,只要改变写入单片机中的内容,就可以改变电路的输出效果。

三、单片机内部结构分析

我们来思考一个问题,当我们在编程器中把一条指令写进单片要内部,然后取下单片机,单片机就可以执行这条指令,那么这条指令一定保存在单片机的某个地方,并且这个地方在单片机掉电后依然可以保持这条指令不会丢失,这是个什么地方呢?

这个地方就是单片机内部的只读存储器即ROM(READONLYMEMORY)。

为什么称它为只读存储器呢?

刚才我们不是明明把两个数字写进去了吗?

原来在89C51中的ROM是一种电可擦除的ROM,称为FLASHROM,刚才我们是用的编程器,在特殊的条件下由外部设备对ROM进行写的操作,在单片机正常工作条件下,只能从那面读,不能把数据写进去,所以我们还是把它称为ROM。

几个基本概念

1.      数的本质和物理现象。

我们知道,计算机可以进行数学运算,这可令我们非常的难以理解,计算机吗,我们虽不了解它的组成,但它总只是一些电子元器件,怎么可以进行数学运算呢?

我们做数学题如37+45是这样做的,先在纸上写37,然后在下面写45,然后大脑运算,最后写出结果,运算的原材料:

37、45和结果:

82都是写在纸上的,计算机中又是放在什么地方呢?

为了解决这个问题,先让我们做一个实验:

这里有一盏灯,我们知道灯要么亮,要么不亮,就有两种状态,我们可以用’0’和’1’来代替这两种状态,规定亮为’1’,不亮为’0’。

现在放上两盏灯,一共有几种状态呢?

我们列表来看一下:

状态

表达

00

01

10

11

请大家自已写上3盏灯的情况000001010011100101110111

我们来看,这个000,001,101不就是我们学过的的二进制数吗?

本来,灯的亮和灭只是一种物理现象,可当我们把它们按一按的顺序排更好后,灯的亮和灭就代表了数字了。

让我们再抽象一步,灯为什么会亮呢?

看电路1,是因为输出电路输出高电平,给灯通了电。

因此,灯亮和灭就可以用电路的输出是高电平还是低电平来替代了。

这样,数字就和电平的高、低联系上了。

(请想一下,我们还看到过什么样的类似的例子呢?

(海军之)灯语、旗语,电报,甚至红、绿灯)

2.      位的含义:

通过上面的实验我们已经知道:

一盏灯亮或者说一根线的电平的高低,可以代表两种状态:

0和1。

实际上这就是一个二进制位,因此我们就把一根线称之为一“位”,用BIT表示。

3.      字节的含义:

  一根线可以表于0和1,两根线可以表达00,01,10,11四种状态,也就是可以表于0到3,而三根可以表达0-7,计算机中通常用8根线放在一起,同时计数,就可以表过到0-255一共256种状态。

这8根线或者8位就称之为一个字节(BYTE)。

不要问我为什么是8根而不是其它数,因为我也不知道。

(计算机世界是一个人造的世界,不是自然界,很多事情你无法问为什么,只能说:

它是一种规定,大家在以后的学习过程中也要注意这个问题)

1.      存储器的工作原理:

1、存储器构造

存储器就是用来存放数据的地方。

它是利用电平的高低来存放数据的,也就是说,它存放的实际上是电平的高、低,而不是我们所习惯认为的1234这样的数字,这样,我们的一个谜团就解开了,计算机也没什么神秘的吗。

图2

图3

 

让我们看图2。

这是一个存储器的示意图:

一个存储器就象一个个的小抽屉,一个小抽屉里有八个小格子,每个小格子就是用来存放“电荷”的,电荷通过与它相连的电线传进来或释放掉,至于电荷在小格子里是怎样存的,就不用我们操心了,你可以把电线想象成水管,小格子里的电荷就象是水,那就好理解了。

存储器中的每个小抽屉就是一个放数据的地方,我们称之为一个“单元”。

有了这么一个构造,我们就可以开始存放数据了,想要放进一个数据12,也就是00001100,我们只要把第二号和第三号小格子里存满电荷,而其它小格子里的电荷给放掉就行了(看图3)。

可是问题出来了,看图2,一个存储器有好多单元,线是并联的,在放入电荷的时候,会将电荷放入所有的单元中,而释放电荷的时候,会把每个单元中的电荷都放掉,这样的话,不管存储器有多少个单元,都只能放同一个数,这当然不是我们所希望的,因此,要在结构上稍作变化,看图2,在每个单元上有个控制线,我想要把数据放进哪个单元,就给一个信号这个单元的控制线,这个控制线就把开关打开,这样电荷就可以自由流动了,而其它单元控制线上没有信号,所以开关不打开,不会受到影响,这样,只要控制不同单元的控制线,就可以向各单元写入不同的数据了,同样,如果要某个单元中取数据,也只要打开相应的控制开关就行了。

2、存储器译码

那么,我们怎样来控制各个单元的控制线呢?

这个还不简单,把每个单元元的控制线都引到集成电路的外面不就行了吗?

事情可没那么简单,一片27512存储器中有65536个单元,把每根线都引出来,这个集成电路就得有6万多个脚?

不行,怎么办?

要想法减少线的数量。

我们有一种方法称这为译码,简单介绍一下:

一根线可以代表2种状态,2根线可以代表4种状态,3根线可以代表几种,256种状态又需要几根线代表?

8种,8根线,所以65536种状态我们只需要16根线就可以代表了。

图4

3、存储器的选片及总线的概念

至此,译码的问题解决了,让我们再来关注另外一个问题。

送入每个单元的八根线是用从什么地方来的呢?

它就是从计算机上接过来的,一般地,这八根线除了接一个存储器之外,还要接其它的器件,如图4所示。

这样问题就出来了,这八根线既然不是存储器和计算机之间专用的,如果总是将某个单元接在这八根线上,就不好了,比如这个存储器单元中的数值是0FFH另一个存储器的单元是00H,那么这根线到底是处于高电平,还是低电平?

岂非要打架看谁历害了?

所以我们要让它们分离。

办法当然很简单,当外面的线接到集成电路的引脚进来后,不直接接到各单元去,中间再加一组开关(参考图4)就行了。

平时我们让开关打开着,如果确实是要向这个存储器中写入数据,或要从存储器中读出数据,再让开关接通就行了。

这组开关由三根引线选择:

读控制端、写控制端和片选端。

要将数据写入片中,先选中该片,然后发出写信号,开关就合上了,并将传过来的数据(电荷)写入片中。

如果要读,先选中该片,然后发出读信号,开关合上,数据就被送出去了。

注意图4,读和写信号同时还接入到另一个存储器,但是由于片选端不同,所以虽有读或写信号,但没有片选信号,所以另一个存储器不会“误会”而开门,造成冲突。

那么会不同时选中两片芯片呢?

只要是设计好的系统就不会,因为它是由计算控制的,而不是我们人来控制的,如果真的出现同时出现选中两片的情况,那就是电路出了故障了,这不在我们的讨论之列。

从上面的介绍中我们已经看到,用来传递数据的八根线并不是专用的,而是很多器件大家共用的,所以我们称之为数据总线,总线英文名为BUS,总即公交车道,谁者可以走。

而十六根地址线也是连在一起的,称之为地址总线。

2.      半导体存储器的分类

按功能可以分为只读和随机存取存储器两大类。

所谓只读,从字面上理解就是只可以从里面读,不能写进去,它类似于我们的书本,发到我们手回之后,我们只能读里面的内容,不可以随意更改书本上的内容。

只读存储器的英文缩写为ROM(READONLYMEMORY)

所谓随机存取存储器,即随时可以改写,也可以读出里面的数据,它类似于我们的黑板,我可以随时写东西上去,也可以用黑板擦擦掉重写。

随机存储器的英文缩写为RAM(READRANDOMMEMORY)这两种存储器的英文缩写一定要记牢。

注意:

所谓的只读和随机存取都是指在正常工作情况下而言,也就是在使用这块存储器的时候,而不是指制造这块芯片的时候。

否则,只读存储器中的数据是怎么来的呢?

其实这个道理也很好理解,书本拿到我们手里是不能改了,可以当它还是原材料——白纸的时候,当然可以由印刷厂印上去了。

顺便解释一下其它几个常见的概念。

PROM,称之为可编程存储器。

这就象我们的练习本,买来的时候是空白的,可以写东西上去,可一旦写上去,就擦不掉了,所以它只能用写一次,要是写错了,就报销了。

EPROM,称之为紫外线擦除的可编程只读存储器。

它里面的内容写上去之后,如果觉得不满意,可以用一种特殊的方法去掉后重写,这就是用紫外线照射,紫外线就象“消字灵”,可以把字去掉,然后再重写。

当然消的次数多了,也就不灵光了,所以这种芯片可以擦除的次数也是有限的——几百次吧。

FLASH,称之为闪速存储器,它和EPROM类似,写上去的东西也可以擦掉重写,但它要方便一些,不需要光照了,只要用电学方法就可以擦除,所以就方便许多,而且寿面也很长(几万到几十万次不等)。

再次强调,这里的所有的写都不是指在正常工作条件下。

不管是PROM、EPROM还是FLASHROM,它们的写都要有特殊的条件,一般我们用一种称之为“编程器”的设备来做这项工作,一旦把它装到它的工作位置,就不能随便改写了。

片机的内外部结构分析

(二)

一、程序的完善

上一次我们的程序实在是没什么用,要灯亮还要重写一下片子,下面我们要让灯不断地闪烁,这就有一定的实用价值了,比如可以把它当成汽车上的一个信号灯用了。

怎样才能让灯不断地闪烁呢?

实际上就是要灯亮一段时间,再灭一段时间,也就是说要P10不断地输出高和低电平。

怎样实现这个要求呢?

请考虑用下面的指令是否可行:

SETBP1.0

CLRP1.0

……

这是不行的,有两个问题,第一,计算机执行指令的时间很快,执行完SETBP10后,灯是灭了,但在极短时间(微秒级)后,计算机又执行了CLRP10指令,灯又亮了,所以根本分辨不出灯曾灭过。

第二,在执行完CLRP10后,不会再去执行SETBP10指令,所以以后再也没有机会让灭了。

为了解决这两个问题,我们可以做如下设想,第一,在执行完SETBP10后,延时一段时间(几秒或零点几秒)再执行第二条指令,就可以分辨出灯曾灭过了。

第二在执行完第二条指令后,让计算机再去执行第一条指令,不断地在原地兜圈,我们称之为

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 农林牧渔 > 林学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1