【51单片机】LCD1602 液晶显示实验指导书

您所在的位置:网站首页 市面上流行的单片机 【51单片机】LCD1602 液晶显示实验指导书

【51单片机】LCD1602 液晶显示实验指导书

2024-07-03 05:19| 来源: 网络整理| 查看: 265

LCD1602 液晶显示实验

        来介绍一种非常简单且常用的显示装置——LCD1602 液晶显示器,使用它可以显示更多的字符数字。这将有助于我们清晰的观察程序的运行结果,更加方便我们的后续调试和开发。

        我们的开发板上集成了一个 LCD1602 液晶显示器接口,将LCD1602 液晶对应插入即可。

        本章要实现的功能是:系统运行时,在 LCD1602 液晶上显示字符信息。

        本章节可分为如下几部分内容:

        一、 LCD1602 介绍

        二、 硬件设计

        三、 软件设计

        四、 实验现象

 保姆级烧录教程

 一些有趣的LCD1602显示实验

点击在线浏览本文档,支持在线评论和互动。

本实验所有文档资料下载(蓝奏云)密码:9drm

本实验所有教学视频及PPT资源下载(百度云)

一、LCD1602介绍 1.1 LCD1602简介和引脚定义

        LCD1602 液晶也叫 LCD1602 字符型液晶,它能显示 2 行字符信息,每行又能显示 16 个字符。它是一种专门用来显示字母、数字、符号的点阵型液晶模块。它是由若干个 5x7 或者 5x10的点阵字符位组成,每个点阵字符位都可以用显示一个字符, 每位之间有一个点距的间隔,每行之间也有间隔,起到了字符间距和行间距的作用,正因为如此,它不能很好的显示图片。其实物图如下所示:

图1 图1:LCD1602液晶实物图

        大家手上拿到的 LCD1602 外观可能和图1不一样,这是由于不同厂家设计所致,但使用方法是一样的。在上图可以看到有 16 个管脚孔,从左至右管脚编号是 1-16,其功能定义如下所示:

        1 脚:VSS,接地。

        2 脚:VDD,电源正极(4.5~5.5V都可)。

        3 脚:VO,对比度调节。液晶显示偏压信号,用于调整 LCD1602 的显示对比度,一般会外接电位器用以调整偏压信号,注意此脚电压为 0 时可以得到最强的对比度。

        4 脚:RS,数据/指令选择端,1为数据,0为指令。当此脚为高电平时,可以对 1602 进行数据字节的传输操作,而为低电平时,则是进行命令字节的传输操作。命令字节,即是用来对 LCD1602 的一些工作方式作设置的字节;数据字节,即使用以在 1602 上显示的字节。值得一提的是,LCD1602 的数据是 8 位的。

        5 脚:R/W,读/写选择端,1为读,0为写。当此脚为高电平可对 LCD1602 进行读数据操作, 反之进行写数据操作。

        6 脚:E,使能信号,1为数据有效,下降沿执行命令。其实是 LCD1602 的数据控制时钟信号,利用该信号的上升沿实现对 LCD1602 的数据传输。

        7~14 脚:数据输入/输出。8 位并行数据口,而 51 单片机一组 IO 也是 8 位,使得对 LCD1602 的数据读写大为方便。

        15 脚:A,背光灯电源正极。

        16 脚:K,背光灯电源负极。

        下面给出各引脚功能速览表和其内部原理图:

图2:各引脚功能速览表

图3:LCD1602液晶原理图 1.2 LCD1602内部结构

图4:内部结构框图

      DDRAM(Data Display Random Access Memory ):数据显示存储器。

可读取,可写入。如图5所示,可显示位置为40*2,共计80个字符。即是第一行 00H~27H,和第二行的40H~67H。

图5:DDRAM(数据显示区)

     CGRAM(Character Generation Random Access Memory):用户字符发生器。

可以自定义用户的字模库(最多八个字符)。

      CGROM(Character Generation Read Only Memory):字符发生器。

出厂默认设置的字模库,与标准ASCII码基本一致。并在此基础上加入片假名和部分特殊符号的支持。具体支持范围如图六所示:

图6:CGRAM+CGROM(字模库)

        读取方式也很简单,例如想获得"A"在字模库中的位置,由图6可知,其二进制位置为 0100 0000B,转换为16进制是 40H。

        屏幕显示:显示字符数据,16*2。

图7:屏幕显示区

         由图5和图7对比可知:不是所有的地址都可以直接用来显示字符数据,只有第一行中的 00-0F,第二行中的 40-4F 才能显示,其他地址只能用于存储。

        要显示字符时要先输入显示字符地址,也就是告诉模块在哪里显示字符,例如第二行第一个字符的地址是 40H,那么是否直接写入 40H 就可以将光标定位在第二行第一个字符的位置呢?这样不行,因为写入显示地址时要求最高位 D7 恒定为高电平 1 所以实际写入的数据应该是 01000000B(40H)+10000000B(80H)=11000000B(C0H)。

        在 1602 中我们就用前 16 个就行了。第二行也一样用前 16 个地址。

      AC(Aid Carry):辅助进位,即光标位置。

 指向下一位字符的位置,并在显示完毕后,自动加一。

1.3 LCD1602常用指令 图8:LCD1602液晶显示指令集(标红为常用命令)

      在使用 LCD1602 时,我们要掌握一些常用指令,这些指令对于 LCD1602 初始化是必须的。

(1)清屏指令

图9:清屏指令

功能:

清除液晶显示器,即将 DDRAM 的内容全部填入"空白"的 ASCII 码 20H;

光标归位,即将光标撤回液晶显示屏的左上方;

将地址计数器(AC)的值设为 0。

也就是说 清屏指令是0x01

(2)模式设置指令

图10:模式设置指令

功能:

设定每次写入 1 位数据后光标的移位方向,并且设定每次写入的一个字符是否移动。

I/D:0=写入新数据后光标左移 1=写入新数据后光标右移

S:0=写入新数据后显示屏不移动 1=写入新数据后显示屏整体右移1 个字符

也就是说 写入新数据后光标右移,显示屏不移动的命令是0x06

(3)显示开关控制指令

图11:显示开关控制 图11:显示开关控制

功能:

控制显示器开/关、光标显示/关闭以及光标是否闪烁。

D:0=显示功能关 1=显示功能开

C:0=无光标 1=有光标

B:0=光标闪烁 1=光标不闪烁

也就是说 显示开,光标关,闪烁关的指令是 0x0c

(4)功能设定指令

图12:功能设定指令

功能:

设定数据总线位数、显示的行数及字型。

DL:0=数据总线为 4 位 1=数据总线为 8 位

N:0=显示 1 行 1=显示 2 行

F:0=5×7 点阵/每字符 1=5×10 点阵/每字符

也就是说 数据总线8位,显示2行,5*7点阵/字符的命令是0x38

1.4 LCD1602的使用

        要使用 LCD1602,首先需要对其初始化,即通过写入一些特定的指令实现。然后选择要在 LCD1602 的哪个位置显示,并将所要显示的数据发送到 LCD 的 DDRAM。使用 LCD1602 通常都是用于写数据进去,很少使用读功能。LCD1602 操作步骤如下所示:

(1)初始化

发送指令0x38 //八位数据接口,两行显示,5*7点阵

发送指令0x0C //显示开,光标关,闪烁关

发送指令0x06 //数据读写操作后,光标自动加一,画面不动

发送指令0x01 //清屏

(2)写命令(RS=0),设置显示坐标

(3)写数据(RS=1)

/** * @brief LCD1602初始化函数 * @param 无 * @retval 无 */ void LCD_Init() { LCD_WriteCommand(0x38);//八位数据接口,两行显示,5*7点阵 LCD_WriteCommand(0x0c);//显示开,光标关,闪烁关 LCD_WriteCommand(0x06);//数据读写操作后,光标自动加一,画面不动 LCD_WriteCommand(0x01);//光标复位,清屏 }

        下面给出LCD1602 的时序图和时序参数图:

图13:LCD1602 的时序图和时序参数图

        在此,不需要读出它的数据的状态或者数据本身。所以只需要看图13写时序:

  1. 当要写指令字,设置 LCD1602 的工作方式时:需要把 RS 置为低电平,RW 置为低电平,然后将数据送到数据口 D0~D7,最后 E 引脚一个高脉冲将数据写入。也就是:

/** * @brief LCD1602写命令 * @param Command 要写入的命令 * @retval 无 */ void LCD_WriteCommand(unsigned char Command) { LCD_RS=0; //写命令置0 LCD_RW=0; //1为读,0为写 P0=Command; //把命令通过P0口传送(D0~D7连到P0口的情况下) LCD_EN=1; //拉高使能引脚 LCD_Delay(); //1ms 延时 LCD_EN=0; //拉低使能引脚,数据写入完毕 LCD_Delay(); //1ms 延时 }

2.当要写入数据字,在 1602 上实现显示时:需要把 RS 置为高电平,RW 置为低电平,然后将数据送到数据口 D0~D7,最后 E 引脚一个高脉冲将数据写入。也就是:

/** * @brief LCD1602写数据 * @param Data 要写入的数据 * @retval 无 */ void LCD_WriteData(unsigned char Data) { LCD_RS=1; //写数据置1 LCD_RW=0; //1为读,0为写 P0=Data; //把数据通过P0口传送(D0~D7连到P0口的情况下) LCD_EN=1; //拉高使能引脚 LCD_Delay(); //1ms 延时 LCD_EN=0; //拉低使能引脚,数据写入完毕 LCD_Delay(); //1ms 延时 }

        写指令和写数据,差别仅仅在于 RS 的电平不一样而已。

        当要写命令字节的时候,时间由左往右,RS 变为低电平,R/W 变为低电平, 注意看是 RS 的状态先变化完成。然后这时,DB0~DB7 上数据进入有效阶段,接着 E 引脚有一个整脉冲的跳变,接着要维持时间最小值为tpw=400ns 的 E 脉冲宽度。然后E 引脚负跳变,RS 电平变化,R/W 电平变化。这样便是一个完整的LCD1602写命令的时序。

 从图13可以看到,以上给的时间参数全部是 ns 级别的,而 51 单片机的机器周期是 1us,指令周期是 2-4 个机器周期,所以理论上即便在程序里不加延时程序,也可以很好的配合 LCD1602 的时序要求了。但实际上在使能E拉高时要延时1ms左右,不然写入数据会失败,这个要多加注意。

二、 硬件设计

        本实验使用到硬件资源如下:

        (1)LCD1602 液晶

        开发板上集成了一个 LCD1602 液晶接口,下面来看下开发板上 LCD1602 液晶接口电路,如下图所示:

图14:普中A2开发板LCD1602液晶接口电路

        从上图中可知,LCD1602 的 8 位数据口 DB0-DB7 与单片机的 P0.0-P0.7 管脚连接,LCD1602 的 RS、RW、E 脚与单片机的 P2.6、P2.5、P2.7 管脚连接。RJ1 是一个电位器,用来调节 LCD1602 对比度即显示亮度。

注意:这里原理图是使用的 8 位 LCD1602 接口设计,是可以兼容 4 位 LCD1602 的。对于非标准接口的 LCD1602,我们也会通过转接板将其转接为对应开发板接口的。对于 4 位 LCD1602 在传输数据的时候需要将 8 位的数据截成两段,先发送高四位,在发送低四位。其它引脚操作方法不变。

三、 软件设计

        本章所要实现的功能是:在 LCD1602 液晶上显示字符信息。程序框架如下:

        (1)编写 LCD1602 显示函数

        (2)编写主函数

        本章软件的重点是如何对 LCD1602 进行写命令和数据。

        3.1 LCD1602驱动函数

        在第一步 1.4 LCD1602的使用 我们已经了解到了LCD1602的初始化,写命令及写数据操作,现在我们给出写命令和写数据时,11.0592MHz 调用可延时1ms的代码(此代码可由辅助软件计算写出):

//函数定义: /** * @brief LCD1602延时函数,11.0592MHz调用可延时1ms * @param 无 * @retval 无 */ void LCD_Delay() { unsigned char i, j; i = 2; j = 199; do { while (--j); } while (--i); }         3.2 LCD1602显示函数

        (1) LCD1602设置光标位置

        因为写入显示地址时要求最高位 D7 恒定为高电平 1,所以命令的最高位要全赋为1,而显示位是从0开始的,所以第一行的写入命令是 0x80| (lie-1)。

        而LCD1602的存储是每行40个字符,所以第二行第一位是在第一行的基础上加0x40。

/** * @brief LCD1602设置光标位置 * @param hang 行位置,范围:1~2 * @param lie 列位置,范围:1~16 * @retval 无 */ void LCD_SetCursor(unsigned char hang,unsigned char lie) //设置光标位置 { if(hang==1) { LCD_WriteCommand(0x80|(lie-1)); //因为写入显示地址时要求最高位 D7 恒定为高电平 1 } else if(hang==2) { LCD_WriteCommand(0x80|(lie-1+0x40)); //LCD的存储是每行40,所以第二行第一位是在第一行的基础上加0x40 } }

        (2) 在LCD1602指定位置上显示一个字符

/** * @brief 在LCD1602指定位置上显示一个字符 * @param hang 行位置,范围:1~2 * @param lie 列位置,范围:1~16 * @param Char 要显示的字符 * @retval 无 */ void LCD_ShowChar(unsigned char hang,unsigned char lie,char Char) { LCD_SetCursor(hang,lie); LCD_WriteData(Char); }

        (3) 在LCD1602指定位置开始显示所给字符串

/** * @brief 在LCD1602指定位置开始显示所给字符串 * @param hang 起始行位置,范围:1~2 * @param lie 起始列位置,范围:1~16 * @param String 要显示的字符串 * @retval 无 */ void LCD_ShowString(unsigned char hang,unsigned char lie,char *String) { unsigned char i; LCD_SetCursor(hang,lie); for(i=0;String[i]!='\0';i++) { LCD_WriteData(String[i]); } }

        (4) 在LCD1602指定位置开始显示所给数字

789 这是最初的数

把各个数分开之后的数

i指数字的个数

i 和标红文字的关系

789/100%10

7

3

10^(3-1)

789/10%10

8

2

10^(2-1)

789/1%10

9

1

10^(1-1)

/** * @brief 返回值=X的Y次方 */ int LCD_Pow(int X,int Y) { unsigned char i; int Result=1; for(i=0;i0;i--) { LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0');//加'0'是因为要转换成数字格式,不然会显示ASCII码 } }         3.3 主程序

        将上述代码整合在main.c(主程序)里面,得到如下完整代码:

#include //引脚配置: sbit LCD_RS=P2^6; sbit LCD_RW=P2^5; sbit LCD_EN=P2^7; void LCD_Delay() //11.0592MHz调用可延时1ms { unsigned char i, j; i = 2; j = 199; do { while (--j); } while (--i); } void LCD_WriteCommand(unsigned char Command) //LCD1602写命令 { LCD_RS=0; //写命令置0 LCD_RW=0; //1为读,0为写 P0=Command; //把命令通过P0口传送(D0~D7连到P0口的情况下) LCD_EN=1; //拉高使能引脚 LCD_Delay(); //1ms 延时 LCD_EN=0; //拉低使能引脚,数据写入完毕 LCD_Delay(); //1ms 延时 } void LCD_Init() //LCD1602初始化函数 { LCD_WriteCommand(0x38);//八位数据接口,两行显示,5*7点阵 LCD_WriteCommand(0x0c);//显示开,光标关,闪烁关 LCD_WriteCommand(0x06);//数据读写操作后,光标自动加一,画面不动 LCD_WriteCommand(0x01);//光标复位,清屏 } void LCD_WriteData(unsigned char Data) //LCD1602写数据 { LCD_RS=1; //写数据置1 LCD_RW=0; //1为读,0为写 P0=Data; //把数据通过P0口传送(D0~D7连到P0口的情况下) LCD_EN=1; //拉高使能引脚 LCD_Delay(); //1ms 延时 LCD_EN=0; //拉低使能引脚,数据写入完毕 LCD_Delay(); //1ms 延时 } void LCD_SetCursor(unsigned char hang,unsigned char lie) //设置光标位置 { if(hang==1) { LCD_WriteCommand(0x80|(lie-1)); //因为写入显示地址时要求最高位 D7 恒定为高电平 1 } else if(hang==2) { LCD_WriteCommand(0x80|(lie-1+0x40)); //LCD的存储是每行40,所以第二行第一位是在第一行的基础上加0x40 } } void LCD_ShowChar(unsigned char hang,unsigned char lie,char Char)//指定位置显示一个字符 { LCD_SetCursor(hang,lie); LCD_WriteData(Char); } void LCD_ShowString(unsigned char hang,unsigned char lie,char *String)//指定位置开始显示所给字符串 { unsigned char i; LCD_SetCursor(hang,lie); for(i=0;String[i]!='\0';i++) { LCD_WriteData(String[i]); } } int LCD_Pow(int X,int Y)//返回值=X的Y次方 { unsigned char i; int Result=1; for(i=0;i0;i--) { LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0');//加'0'是因为要转换成数字格式,不然会显示ASCII码 } } void main() { LCD_Init(); //LCD初始化 LCD_ShowChar(1,1,'A'); //在1行1列显示字符A LCD_ShowString(1,3,"Hello"); //在1行3列显示字符串Hello LCD_ShowNum(1,9,66,2); //在1行9列显示数字66,长度为2 LCD_ShowString(2,1,"ZhangFuGong"); //在2行1列显示字符串ZhangFuGong LCD_ShowChar(2,13,0xDF); //在2行13列显示编码为0xDF的字符 LCD_ShowChar(2,14,'C'); //在2行14列显示字符C while(1) { } } 四、 实验现象

        使用 USB 线将开发板和电脑连接成功后(电脑能识别开发板上 CH340 串口), 把编译后产生的.hex 文件烧入到芯片内,实现现象如下:在 LCD1602 液晶上显示字符信息。

图15:实验现象

注意:LCD1602 液晶要正确插入到 LCD1602 接口 J2 位置,插反或者差错都会导致显示不正常。如果出现显示看不清的情况,可调节板子 LCD1602 接口下的 RJ1 电位器。如果 LCD1602 无法显示,可重启电源或复位。

图16:引脚和板子匹配示意图 保姆级烧录教程

        本章节实验到此已经完毕,考虑到大家的基础差异较大,刚接触51单片机的小伙伴可能对烧录过程有些困惑,作者便在篇末给大家提供保姆级烧录教程,帮助大家快速掌握单片机程序烧录技巧,希望对大家有所帮助!

本教程所需软件下载(win系统)

        1. 开发板准备工作(以普中A2开发板为例)

        (1)检查单片机芯片型号是否为 STC89C52RC

图17:普中A2开发板单片机芯片

        (2)单片机与计算机建立通信

图18:用micro-usb线一端连接单片机

图19:用micro-usb线另一端连接计算机USB口         2. 烧录软件的准备操作

        (1)下载并打开上述链接所提供的软件。

        下载完成后。鼠标右键软件图标,选择 以管理员身份运行 ,在弹出的对话框中选择 是 ,软件开始运行。(没有管理员选项的直接鼠标左键双击运行也可)。

图20:鼠标右键图标界面

        (2)芯片型号选择

        如果芯片型号与图17一致,直接按照图示箭头依次选择即可。不同的话则依据各自型号选择相应系列。

图21:芯片型号选择

        (3)检查串口

        检查串口是否有红框圈中的 USB-SERIAL CH340 字样(后面的COM口不用管,每台电脑都可能不一致)。有的话证明你的电脑已经装了CH340驱动;没有的话也没关系,下载下面链接的驱动安装软件,双击运行,按照提示操作即可。CH340驱动软件下载(win系统)

图22:电脑识别开发板上 CH340 串口

        (4)打开程序文件

        按照图示操作,找到已经编译生成的.hex文件,单击选中后点击打开。

图23:打开程序文件        图24:找到.hex文件并打开  3. 烧录程序

        (1)点击 下载/编程 按钮

    点击 下载/编程 按钮,看到软件右侧显示,正在检测单片机。

图25:下载/编程

        

(2)开关单片机开发板

 此时找到图26中,开发板的 POWER 白色按键:

 1. 若此时是上电状态,则按两下白色按键,即关机后重新开机。

 2. 若此时是断电状态,则按一下白色按键,即重新开机。

图26:Power键

        (3)烧录成功

  软件显示操作成功,此时程序已经烧录进单片机,单片机将按照程序开始执行操作。

图27:烧录成功 一些有趣的LCD1602显示实验(基于普中A2开发板)         1. 温度传感器读取实验(利用DS18B20芯片)

        (1) 实验代码

#include //引脚配置: sbit LCD_RS=P2^6; sbit LCD_RW=P2^5; sbit LCD_EN=P2^7; #define LCD_DataPort P0 float T; void Delay(unsigned int xms) { unsigned char i, j; while(xms--) { i = 2; j = 239; do { while (--j); } while (--i); } } void LCD_Delay() //11.0592MHz调用可延时1ms { unsigned char i, j; i = 2; j = 199; do { while (--j); } while (--i); } /** * @brief LCD1602写命令 * @param Command 要写入的命令 * @retval 无 */ void LCD_WriteCommand(unsigned char Command) { LCD_RS=0; LCD_RW=0; LCD_DataPort=Command; LCD_EN=1; LCD_Delay(); LCD_EN=0; LCD_Delay(); } /** * @brief LCD1602写数据 * @param Data 要写入的数据 * @retval 无 */ void LCD_WriteData(unsigned char Data) { LCD_RS=1; LCD_RW=0; LCD_DataPort=Data; LCD_EN=1; LCD_Delay(); LCD_EN=0; LCD_Delay(); } /** * @brief LCD1602设置光标位置 * @param Line 行位置,范围:1~2 * @param Column 列位置,范围:1~16 * @retval 无 */ void LCD_SetCursor(unsigned char Line,unsigned char Column) { if(Line==1) { LCD_WriteCommand(0x80|(Column-1)); } else if(Line==2) { LCD_WriteCommand(0x80|(Column-1+0x40)); } } /** * @brief LCD1602初始化函数 * @param 无 * @retval 无 */ void LCD_Init() { LCD_WriteCommand(0x38);//八位数据接口,两行显示,5*7点阵 LCD_WriteCommand(0x0c);//显示开,光标关,闪烁关 LCD_WriteCommand(0x06);//数据读写操作后,光标自动加一,画面不动 LCD_WriteCommand(0x01);//光标复位,清屏 } /** * @brief 在LCD1602指定位置上显示一个字符 * @param Line 行位置,范围:1~2 * @param Column 列位置,范围:1~16 * @param Char 要显示的字符 * @retval 无 */ void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char) { LCD_SetCursor(Line,Column); LCD_WriteData(Char); } /** * @brief 在LCD1602指定位置开始显示所给字符串 * @param Line 起始行位置,范围:1~2 * @param Column 起始列位置,范围:1~16 * @param String 要显示的字符串 * @retval 无 */ void LCD_ShowString(unsigned char Line,unsigned char Column,char *String) { unsigned char i; LCD_SetCursor(Line,Column); for(i=0;String[i]!='\0';i++) { LCD_WriteData(String[i]); } } /** * @brief 返回值=X的Y次方 */ int LCD_Pow(int X,int Y) { unsigned char i; int Result=1; for(i=0;i0;i--) { LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0'); } } sbit OneWire_DQ=P3^7; /** * @brief 单总线初始化 * @param 无 * @retval 从机响应位,0为响应,1为未响应 */ unsigned char OneWire_Init(void) { unsigned char i; unsigned char AckBit; OneWire_DQ=1; OneWire_DQ=0; i = 247;while (--i); //Delay 500us OneWire_DQ=1; i = 32;while (--i); //Delay 70us AckBit=OneWire_DQ; i = 247;while (--i); //Delay 500us return AckBit; } /** * @brief 单总线发送一位 * @param Bit 要发送的位 * @retval 无 */ void OneWire_SendBit(unsigned char Bit) { unsigned char i; OneWire_DQ=0; i = 4;while (--i); //Delay 10us OneWire_DQ=Bit; i = 24;while (--i); //Delay 50us OneWire_DQ=1; } /** * @brief 单总线接收一位 * @param 无 * @retval 读取的位 */ unsigned char OneWire_ReceiveBit(void) { unsigned char i; unsigned char Bit; OneWire_DQ=0; i = 2;while (--i); //Delay 5us OneWire_DQ=1; i = 2;while (--i); //Delay 5us Bit=OneWire_DQ; i = 24;while (--i); //Delay 50us return Bit; } /** * @brief 单总线发送一个字节 * @param Byte 要发送的字节 * @retval 无 */ void OneWire_SendByte(unsigned char Byte) { unsigned char i; for(i=0;i


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3