登入帳戶  | 訂單查詢  | 購物車/收銀台( 0 ) | 在線留言板  | 付款方式  | 聯絡我們  | 運費計算  | 幫助中心 |  加入書簽
會員登入 新註冊 | 新用戶登記
HOME新書上架暢銷書架好書推介特價區會員書架精選月讀2023年度TOP分類閱讀雜誌 香港/國際用戶
最新/最熱/最齊全的簡體書網 品種:超過100萬種書,正品正价,放心網購,悭钱省心 送貨:速遞 / EMS,時效:出貨後2-3日

2024年03月出版新書

2024年02月出版新書

2024年01月出版新書

2023年12月出版新書

2023年11月出版新書

2023年10月出版新書

2023年09月出版新書

2023年08月出版新書

2023年07月出版新書

2023年06月出版新書

2023年05月出版新書

2023年04月出版新書

2023年03月出版新書

2023年02月出版新書

『簡體書』大学计算机应用能力实训教程

書城自編碼: 3021703
分類: 簡體書→大陸圖書→教材研究生/本科/专科教材
作者: 崔舒宁 贾应智 杨振平 谢涛 薄钧戈 张小彬
國際書號(ISBN): 9787302475477
出版社: 清华大学出版社
出版日期: 2017-08-01
版次: 1 印次: 1
頁數/字數: 262/419000
書度/開本: 32开 釘裝: 平装

售價:NT$ 284

我要買

share:

** 我創建的書架 **
未登入.



新書推薦:
中世纪英国的财政、军事与外交(中外文明传承与交流研究书系)
《 中世纪英国的财政、军事与外交(中外文明传承与交流研究书系) 》

售價:NT$ 437.0
缺席者的历史:以色列十个遗失的部落
《 缺席者的历史:以色列十个遗失的部落 》

售價:NT$ 437.0
晚清洋务运动始末
《 晚清洋务运动始末 》

售價:NT$ 447.0
美索不达米亚神话
《 美索不达米亚神话 》

售價:NT$ 391.0
别害怕吵架:教孩子在冲突中学会正向沟通
《 别害怕吵架:教孩子在冲突中学会正向沟通 》

售價:NT$ 274.0
这个甜甜圈不能卖:奇思妙想爆笑绘本(全2册)
《 这个甜甜圈不能卖:奇思妙想爆笑绘本(全2册) 》

售價:NT$ 447.0
生活中的民法典实用全书:应知应懂的法律常识
《 生活中的民法典实用全书:应知应懂的法律常识 》

售價:NT$ 498.0
饲渊
《 饲渊 》

售價:NT$ 223.0

建議一齊購買:

+

NT$ 353
《 电子商务安全原理 》
+

NT$ 223
《 Linux系统及应用 》
+

NT$ 331
《 全国大学生数学竞赛辅导指南(第2版) 》
編輯推薦:
本书包含以下5个实训项目,并通过多个实例讲解MFC编程、C#编程和HTML CSS编程。(1)c#窗体程序的开发。这个项目面向那些基本没有程序设计经验和完整学过程序设计课程的学生,通过项目培训具有基本的程序开发能力。(2)MFC 游戏编程。面向学习过c的学生,通过该项目进一步掌握Windows编程。(3)单片机的应用开发。面向学习过C语言的学生,利用学过的知识,做一些单片机的应用开发。(4)网上订餐系统。这是一个c#开发的Web项目,面向已经学习过c#语言的学生。(5)医院管理系统。这是一个c#开发的Web管理系统,面向医学专业的学生。
內容簡介:
本书包含C#窗体程序开发、MFC 游戏编程、单片机应用开发、网上订餐系统、医院管理系统共5个实训项目,目标是通过实训提高学生的程序编写能力和软件开发能力。
本书适于作为高等院校非计算机专业的本科生教材,也可以供对软件开发感兴趣的读者自学参考。
目錄
第1章 音乐播放器设计1
1.1 环境准备1
1.1.1 在工具箱中添加WMP组件1
1.1.2 WMP组件外观2
1.1.3 最简单的音乐播放器设计3
1.2 WMP组件的基本使用5
1.2.1 WMP组件类(axWindowsMediaPlayer)5
1.2.2 媒体类型(IWMPMedia接口)6
1.2.3 播放列表类型(IWMPPlaylist接口)7
1.2.4 WMP组件的播放列表应用7
1.2.5 WMP控件模式设置10
1.3 音乐播放器设计11
1.3.1 设计思想11
1.3.2 功能设计12
1.3.3 播放器界面设计12
1.3.4 关键技术14
1.3.5 功能实现22
编程练习29
第2章 MFC游戏编程31
2.1 Windows游戏编程回顾31
2.2 C Windows游戏编程方式31
2.2.1 Win32 SDK DirectX31
2.2.2 MFC编程33
2.3 设计游戏33
2.3.1 设计文档33
2.3.2 游戏的基本构成33
2.4 俄罗斯方块34
2.4.1 要点分析34
2.4.2 编写步骤35
2.5 走迷宫50
2.5.1 要点分析50
2.5.2 编程步骤50
2.6 MFC游戏编程关键点58
2.6.1 游戏贴图与透明特效58
2.6.2 定时器59
2.6.3 减少图像闪烁60
2.6.4 简单碰撞检测60
编程练习61
第3章 基于单片机的应用系统开发62
3.1 单片机简述62
3.2 认识STC89C52RC单片机62
3.2.1 STC89C52RC单片机的特点63
3.2.2 STC89C52RC工作模式63
3.2.3 STC89C52RC引脚图63
3.3 开发工具Keil Vision 465
3.3.1 安装65
3.3.2 如何创建一个项目66
3.4 烧录软件STC-ISP69
3.5 案例流水灯显示70
3.6 案例呼吸灯显示72
3.7 案例数码管显示数字74
3.8 案例显示字符串77
3.9 案例时钟芯片显示日期82
编程练习90
第4章 网上订餐系统的设计与开发91
4.1 网上订餐系统简介91
4.2 Web项目网络环境介绍及部署91
4.2.1 Web的基本组成91
4.2.2 Web环境部署95
4.3 系统功能结构设计98
4.3.1 系统功能结构概要设计98
4.3.2 系统功能示意图99
4.4 数据库设计102
4.5 系统实现105
4.5.1 用户注册的实现106
4.5.2 用户登录的实现112
4.5.3 菜品选择的实现114
4.5.4 我的订单的实现117
4.5.5 用户管理的实现121
4.5.6 菜品管理的实现121
4.5.7 订单处理的实现126
4.5.8 统计管理的实现130
4.5.9 系统的后续工作132
编程练习132
第5章 HIS系统的开发133
5.1 数据库基础133
5.1.1 基本概念133
5.1.2 在SQL Server中创建数据库和表135
5.1.3 SQL命令的使用139
5.1.4 数据库的设计141
5.2 创建简单的Web应用程序144
5.2.1 Web应用程序的创建过程145
5.2.2 创建欢迎页面147
5.2.3 创建收集信息的页面149
5.2.4 网页之间的跳转和数据的传递152
5.2.5 使用表格进行页面布局155
5.3 数据库访问技术158
5.3.1 C#中访问数据库的一般过程158
5.3.2 使用Repeater控件显示记录160
5.3.3 非空数据验证控件的使用164
5.3.4 向表中添加新的记录168
5.3.5 删除表中记录172
5.3.6 修改表中的记录176
5.4 HIS系统的框架设计178
5.4.1 HIS系统的框架组成178
5.4.2 系统界面的开发过程导航控件、母版页与内容页180
5.4.3 其他页面的界面设计186
5.5 其他问题187
5.5.1 调试程序时频繁出现的问题187
5.5.2 关于本系统的补充说明189
习题191
附录A MFC Windows编程192
A.1 Windows编程的基本思想192
A.2 MFC编程193
A.3 单文档界面应用程序194
A.4 在窗口的客户区输出文字和图形196
A.5 编制消息处理函数198
A.5.1 消息映射199
A.5.2 编制消息处理函数199
A.6 鼠标和键盘消息处理200
A.7 Windows数据类型与变量的命名规则202
A.8 画笔与画刷205
A.9 位图206
A.10 对话框207
A.10.1 对话框的初始化209
A.10.2 对话框的数据交换和数据检验机制209
A.11 常用控件210
A.12 序列化211
A.12.1 打印和打印预览212
A.12.2 自定义类的序列化213
A.13 MDI应用程序213
附录B HTML与CSS基础215
B.1 HTML页面结构215
B.2 HTML行内元素215
B.2.1 图像216
B.2.2 链接216
B.2.3 换行216
B.2.4 强调217
B.3 HTML块元素218
B.3.1 段落218
B.3.2 标题219
B.3.3 水平线220
B.3.4 注释220
B.4 列表221
B.5 表格222
B.6 字符实体223
B.7 音频224
B.8 视频225
B.9 CSS基础226
B.10 CSS选择器227
B.11 CSS的引入方式227
B.12 CSS的属性229
B.13 ID选择器231
B.14 类选择器231
B.15 伪类232
附录C C#语言编程233
C.1 C#语言概述233
C.1.1 C#的类型体系233
C.1.2 C#的流程控制语句235
C.2 Visual Studio集成环境软件安装237
C.3 Visual Studio集成环境使用239
C.4 应用案例244
参考文献263
內容試閱
当今社会计算机和网络技术高速发展,计算机的应用已深入各个领域,计算机操作和应用能力已成为当代各专业大学生都应熟练掌握的一项基本技能。但是,大多数非计算机专业的学生在程序设计能力的培养上,重点在于对语法的掌握,这距离编写优良的程序或者进行小型的软件开发都还有一定的距离。
计算机课程是一门实践性和操作性很强的课程,注重学生动手能力的培养是计算机教学的突出特色之一。为此,西安交通大学在全校范围的一年级本科生中开设了小学期计算机程序设计能力和应用能力实训课程,目标是通过实训提高学生的程序编写能力和软件开发能力。
经过两年的实践,笔者将实训过的项目进行精心挑选,形成了本教材。本教材集中了5个实训项目:①C#窗体程序的开发。这个项目面向那些基本没有程序设计经验和完整学过程序设计课程的学生,目标是通过项目培训具有基本的程序开发能力。②MFC游戏编程。面向学习过C的学生,目标是通过该项目进一步掌握Windows编程。③单片机的应用开发。面向学习过C语言的学生,目标是利用学过的知识,做一些单片机的应用开发。④网上订餐系统。这是一个C#开发的Web项目,面向已经学习过C#语言的学生。⑤医院管理系统。面向医学院的学生,这是一个C#开发的Web管理系统。
学生用集中的2周时间来完成其中的一个项目。每天进行大约6个小时的实训,通过共大约60个小时的实训来进一步提高编程能力和计算机的应用能力。全书共分5章,分别对应上述5个项目。本书同时提供3个附录,分别介绍MFC编程、C#编程和HTML CSS编程。
本书由崔舒宁(第2章和附录A)主编,杨振平编写第1章和附录B,薄钧戈编写第3章,谢涛编写第4章和附录C,贾应智编写第5章。全书由张小彬统稿。西安交通大学电信学院桂小林教授审阅了全部书稿并提出了宝贵的意见。由于本书编写时间紧张,疏漏错误之处请广大读者指正。联系邮箱:cuishuning@sina.com。
本书的配套课件与源代码可以从清华大学出版社网站www.tup.com.cn下载,资源下载与使用中的问题请联系fuhy@tup.tsinghua.edu.cn。

崔舒宁
2017年4月


基于单片机的应用系统开发
本章主要讲解单片机的设备(STC89C52RC)、开发环境(Keil Vision 4、烧录软件STC-ISP),并为读者提供5个实验案例,从简单的流水灯、呼吸灯和数码管显示,逐步扩展到在LCD12864液晶显示字符串以及利用时钟芯片DS1302显示日期。通过对案例的练习,让读者更好地去理解单片机的工作原理,提高程序代码编写能力,进而了解怎样利用单片机去实现从物理世界到计算机世界的转换,例如按键的检测、温度的转换、时间和字符串的显示等内容。
3.1单片机简述
目前,各个领域都有单片机的踪迹,不只是手机、计算机、玩具、冰箱、空调、电磁炉等和我们生活息息相关的物件,也包括汽车、机器人、飞机、导弹导航装备等高科技设备,这些设备都包含一个或多个单片机。可以说,我们每天用到的电子设备基本都有单片机的存在。如果读者想成为一名硬件工程师,单片机的学习是了解计算机原理和结构的最佳选择。
一台计算机需要由CPU、RAM、ROM、输入输出设备等部件构成,这些部件被分成多个芯片并安装在主板上。单片机将这些部件集中安装到一块集成电路芯片上,具有体积小、质量轻、价格便宜的特点,为学习、应用和开发提供了便利条件。
单片机是一种控制芯片,它是一个微型计算机。如果在单片机的基础上添加了晶振、存储器、锁存器、逻辑门、译码器、按钮等部件就组成了单片机系统。一般的单片机有40脚封装,也有一些功能强大的单片机有更多引脚,如68引脚,早期的单片机也有10个或者20个引脚。一般主流的单片机包括CPU、4KB容量的RAM、128 KB容量的ROM、2个16位定时计数器、4个8位并行口、全双工串行口、ADCDAC、SPI、I2C、ISP、IAP。
单片机支持汇编编程和C51编程,两种编程方法各有利弊。汇编编程使用传统的汇编代码,具有代码精简、占用资源少、运行效率高的优点,然而可读性不强、不易移植;C51编程使用专用的C语言编程,C语言具有模块化管理编程方便、可移植性强、适合编写大程序等优点,缺点是占用资源较多,执行效率没有汇编高。本书采用Keil c51进行编程。
3.2认识STC89C52RC单片机
STC89C52RC单片机是宏晶科技有限公司推出的一种具有高速、低功耗、超强抗干扰特点的小型单片机,其程序的电可擦写特性,使得开发与实验比较容易,为很多嵌入式控制系统提供了一种高性价比的方案。
3.2.1 STC89C52RC单片机的特点
(1)它是增强型的8051单片机,可以任意选择6时钟机器周期和12时钟机器周期,指令系统和引脚上完全兼容MCS-51系列的单片机。
(2)工作电压范围:3.8~2.0V(3V单片机)5.5~3.3V(5V单片机)。
(3)工作频率范围:0~40MHz,相当于普通8051的0~80MHz,实际工作频率可 达48MHz。
(4)用户应用程序空间:8KB。
(5)片上集成RAM:512B。
(6)通用IO口(32个),复位后为:P1P2P3P4是准双向口弱上拉,P0口是漏极开路输出,作为总线扩展用时,不用加上拉电阻,作为IO口用时,需加上拉电阻。
(7)ISP(在系统可编程)IAP(在应用可编程),无需专用编程器,无需专用仿真器,可通过串口(输入口RXD P3.0,输出口TXD P3.1)直接下载用户程序。
(8)具有EEPROM(带电可擦写可编程只读存储器)和看门狗功能。
(9)具有3个16位定时器计数器。即定时器T0、T1、T2。
3.2.2STC89C52RC工作模式
(1)掉电模式:典型功耗
(2)空闲模式:典型功耗2mA。
(3)正常工作模式:典型功耗4~7mA。
3.2.3 STC89C52RC引脚图
如图3-1所示,具体功能说明如下。

图3-1 STC89C52RC引脚图
(1)VCC(40引脚):电源电压。
(2)GND(20引脚):接地。
(3)P0端口(P0.0~P0.7,39~32引脚):P0端口是一个漏极开路的8位双向IO口。作为输出端口,每个引脚能驱动8个TTL负载,对端口P0写入1时,可以作为高阻抗输入。在访问外部程序和数据存储器时,P0口也可提供低8位地址和8位数据的复用总线,P0端口内部上拉电阻有效。在Flash ROM编程时,P0端口接收指令字节,而在校验程序时,则输出指令字节,注意在验证时,需外接上拉电阻。
(4)P1端口(P1.0~P1.7,1~8引脚):P1端口是一个带内部上拉电阻的8位双向IO口。P1端口的输出缓冲器可驱动(吸收或者输出电流方式)4个TTL输入。P1端口用作输入口使用时,端口写入1,通过内部的上拉电阻把端口拉到高电位,这样被外部拉低的引脚会输出一个电流。在对Flash ROM编程和程序校验时,P1端口接收低8位地址。此外,P1.0和P1.1还可以作为定时器计数器2的外部技术输入(P1.0T2)和定时器计数器2的触发输入(P1.1T2EX),具体功能如表3-1所示。
表3-1 P1.0和P1.1引脚复用功能

引脚号
功 能 特 性

P1.0
T2(定时器计数器2外部计数输入),时钟输出

P1.1
T2EX(定时器计数器2捕获重装触发和方向控制)


(5)P2端口(P2.0~P2.7,21~28引脚):P2端口是一个带内部上拉电阻的8位双向IO端口。P2端口的输出缓冲器可以驱动(吸收或输出电流方式)4个TTL输入。P2端口用作输入口时,端口写入1时,通过内部的上拉电阻把端口拉到高电平,被外部信号拉低的引脚会输出一个电流。在对Flash ROM编程和程序校验期间,P2端口可以接收高位地址和一些控制信号。
(6)P3端口(P3.0~P3.7,10~17引脚):和P2端口类似,P3端口也是一个带内部上拉电阻的8位双向IO端口。P3端口的输出缓冲器可驱动(吸收或输出电流方式)4个TTL输入。P3端口作为输入口使用时,对端口写入1,通过内部的上拉电阻把端口拉到高电位,因此那些被外部信号拉低的引脚会输入一个电流。在对Flash ROM编程或程序校验时,P3端口会接收一些控制信号。P3端口除作为一般IO口外,还有其他一些复用功能,如表3-2所示。
表3-2 P3端口引脚复用功能

引脚号
复 用 功 能

P3.0
RXD(串行输入口)

P3.1
TXD(串行输出口)

P3.2
(外部中断0输入)

P3.3
(外部中断1输入)

P3.4
T0(定时器0的外部计数输入)

P3.5
T1(定时器1的外部计数输入)

P3.6
(外部数据存储器写选通输出)

P3.7
(外部数据存储器读选通输出)

(7)RST(9引脚):复位输入。当输入连续两个机器周期以上的高电平时有效,用来完成单片机的复位初始化操作。看门狗计时完成后,RST引脚输出96个晶振周期的高电平。特殊寄存器AUXR上的DISRTO位可以使此功能无效。DISRTO默认状态下,复位高电平是有效的。
(8)ALE(30引脚):ALE(地址锁存控制信号)是访问外部程序存储器时,锁存低8位地址的输出脉冲。在Flash编程时,引脚也用作编程输入脉冲。一般情况下,ALE以晶振六分之一的固定频率输出脉冲,可用来作为外部定时器或时钟使用。然而,需要注意的是,每次访问外部数据存储器时,ALE脉冲将会跳过。可以通过将ALE使能标志位(地址位8EH的SFR的第0位)置为1,ALE操作将会无效,置1后,ALE仅在执行MOVX或MOV指令时有效,否则ALE将被拉高。
(9)(29引脚):是外部程序存储器选通信号。当AT89C51RC从外部程序存储器执行外部代码时,在每个机器周期被激活两次,而访问外部数据存储器时,将不被激活。
(10)VPP(31引脚):是访问外部程序存储器控制信号。为使能从0000H到FFFFH的外部程序存储器读取指令,需接GND。加密方式为1时,将内部锁定位RESET,如需执行内部程序指令,需接VCC。在Flash编程期间,也接收12V的VPP电压。
(11)XTAL1(19引脚):振荡器反相放大器和内部时钟发生电路的输入端。
(12)XTAL2(18引脚):振荡器反相放大器的输入端。
3.3开发工具Keil Vision 4
Keil Vision是美国Keil Software公司出品的MCS51架构兼容单片机C语言软件开发环境,它集编辑、编译、仿真等于一体,其界面和常用的微软VC的界面相似,界面友好,易学易用,具有强大的软件仿真功能。Keil 提供了包括C编译器、宏汇编、连接器、库管理和一个功能强大的仿真调试器等在内的完整开发方案。使用汇编语言或C语言需要使用编译器,以便把写好的程序编译为机器码,才能把HEX可执行文件写入单片机内。Keil Vision是众多单片机应用开发软件中最优秀的软件之一,很多开发MCS51系列单片机应用的工程师或普通单片机爱好者,都在使用Keil Vision完成开发工作。
3.3.1安装
(1)运行安装程序,如图3-2所示。

图3-2运行安装Keil程序
(2)按照提示,完成安装过程,如图3-3所示。
(3)完成安装,出现如图3-4所示图标即表示安装完成。

图3-3 Keil安装过程 图3-4 完成Keil安装
3.3.2如何创建一个项目
使用Keil软件新建一个项目并编译运行生成HEX文件。
(1)启动Keil软件,双击图标,运行Vision。
(2)创建一个工程文件。在菜单栏里单击ProjectNew Vision Project菜单项,如图3-5所示,将打开一个对话框,如图3-6所示,输入文件名即可成功创建一个新的工程,Vision将会创建一个以*.uvproj为名字的新工程文件。建议每个工程都使用独立的文件夹。工程文件创建后,从设备数据库中选择一个CPU芯片(一般用的是Atmel的AT89C51或AT89C2051,本书选择AT89C52微控制器),如图3-7所示。

图3-5 创建工程文件截图

图3-6 新建工程文件对话框截图

图3-7 选择CPU芯片截图
(3)创建成功一个工程后,Vision会给所选择的CPU芯片添加合适的启动代码,单击是按钮,完成新建项目,如图3-8所示。

图3-8 添加启动代码截图
(4)创建一个新的源文件,并将源文件加载到新建的工程中。通过单击FileNew菜单项可以创建一个新的源文件,这时会打开一个空的文本编辑窗口,输入相应代码,通过FileSave As可以保存为.c文件。源文件创建好后,需要将此文件添加到工程中,通过右击Project WorkspaceFiles页中的文件组,然后在弹出的菜单中选择Add Files to Group菜单项,将打开文件对话框,选择已创建好的*.c源文件,就完成了源文件的添加,如图3-9所示。

图3-9 添加源文件到项目中截图
(5)第一次使用时,需要进行设置,确保每次运行项目都生成HEX文件。右击Target 1,选择Options for ''Target 1''菜单项,在弹出的对话框中选择Target标签页,填写晶体的大小,再选择Output标签页,选中Create HEX File多选按钮,单击OK按钮确定,如图3-10所示。设置完成后,每次编译都会生成一个十六进制文件。

图3-10 编译生成十六进制文件选项截图
(6)编写完成代码。
(7)编译运行项目。选择菜单ProjectRebuild All Target Files,或单击快捷方式图标,在Build Output窗口,提示creating hex file from "XXX"... "XXX" - 0 Errors, 0 Warnings,如图3-11所示,则表示编译成功,且生成HEX文件成功。

图3-11 Build Output编译成功窗口截图
3.4烧录软件STC-ISP
STC-ISP 是一款单片机下载编程烧录软件,是针对STC系列单片机而设计的,可下载STC89系列、12C2052系列、12C5410等系列的STC单片机,使用简便,现已被广泛使用。
将生成的HEX文件烧到单片机的过程如下。
(1)连接单片机和计算机,打开烧录工具(本书使用的是STC-ISP烧录工具),如图3-12所示。

图3-12 烧录工具STC-ISP界面截图
(2)进行设置,如图3-12左上角选择相应的单片机型号(如选STC89C52),选择正确的端口号(如COM4)。
(3)打开程序文件。单击如图3-12所示的打开程序文件按钮,将弹出对话框,如图3-13所示,选择之前生成的*.hex文件。
(4)下载编程。单击如图3-12所示的下载编程按钮,重新关闭、打开单片机开关,如果提示操作成功!表示烧录工作成功完成,如图3-14所示。

图3-13 选择*.hex文件对话框截图

图3-14完成烧录工作界面截图
3.5案例流水灯显示
LED灯显示流水的效果,时间间隔为0.1s,硬件电路如图3-15所示,单片机的P1.0~P1.7接口上分别接了8个LED灯,输出为0时,LED灯亮,重复循环P1.0P1.1 P1.2P1.7P1.0P1.1P1.2P1.7亮。通过该案例进一步熟悉Keil仿真软件和烧录工具的使用,了解并熟悉单片机IO口和LED等的电路结构。

图3-15 流水灯的硬件电路图
1.要点分析
(1)延时程序的设计。由于单片机指令执行的时间很短(s数量级),如果要达到LED灯间流水的时间间隔为0.1s,在执行某一条指令时,需要引用一个延时程序。石英晶体的频率是12MHz,一个机器周期=112MHz*12=1s,因此我们可以设计延时程序如下:

void delay10msvoid
{
unsigned char i,j,k;
fori=5;i0;i--
forj=4;j0;j--
fork=248;k0;k--;
}

delay10msvoid程序有三层循环,循环的总次数为Num=5*4*248=4960;每次循环都有一次条件判断(如j0)和一次减减(如j--),这将消耗两个机器周期,因此,总的机器周期为Sum=Num*2=9920,又知一个机器周期时间为1s,那么delay10msvoid程序的延时时间为t=Sum*1s=9920s 10ms。
(2)LED灯流水的效果。由于输出为0时,LED灯亮,因此初始定义P1=0x01(P1.0~P1.6亮,P1.7灭),然后每隔0.1s时间,P1则向左循环一位,再取反(P1.0~P1.6灭,P1.7亮),达到LED灯从左向右流水的效果。
2.实验步骤
第一步:设计一个延迟函数。
第二步:初始化P1端口。
第三步:为了达到流水灯从左向右的流水效果,按照循环再取反的设计。
3.参考答案

#include
void delay100msvoid 延迟函数
{
unsigned char i,j,k;
fori=50;i0;i--
forj=4;j0;j--
fork=248;k0;k--;
}
int main主函数
{
unsigned int i;
P1=0x01;初始P1
此循环即表示每隔0.1s时间,P1则向左循环一位,再取反
fori=0;i
{
P1=~0x01
delay100ms;
}
return 0;
}

4.效果演示
如图3-16所示。

图3-16 流水灯演示图
3.6案例呼吸灯显示
呼吸灯就是让LED灯时亮时暗,利用LED灯的余辉和人眼的暂留效应,看上去如同呼吸一样。通过该案例进一步熟悉LED灯工作的原理及学习呼吸灯显示方法。
1.要点分析
假设每个亮暗周期为T,亮的时长为time_on,暗的时长则为T-time_on。根据亮和暗的时长不同,LED灯的亮度将会发生变化。具体设计时可以让LED灯亮的时间越来越长,再越来越小,如此循环,实现LED灯的亮度发生渐变,达到呼吸灯的效果。
2.实验步骤
第一步:设计一个延迟函数。
第二步:初始化P1端口,P1 = 0x00(LED灯全亮)。
第三步:LED灯先亮time_on时间,全灭后,再暗T-time_on(T为亮暗周期)时间;亮的时间越来越长,然后暗的时间越来越长。
3.参考答案

#include
延迟函数
void delayunsigned int time
{
int i=0;
whiletime--
{
}
}
主函数
int main
{
unsigned int time_on=200;
bit flag = 1;
while1
{
P1 = 0x00;
delaytime_on;先全亮,再延迟time_on时间
P1=0xff;
delay3000-time_on; 再全灭,再延迟3000-time_on时间
iftime_on2800
{
flag=0;
}
else iftime_on
{
flag=1;
}
ifflag==1亮的时间越来越长
{
time_on =100;
}
else暗的时间越来越长
{
time_on-=100;
}
}
}

4.效果演示
如图3-17所示。

图3-17 呼吸灯演示图
3.7案例数码管显示数字
在时钟信号的作用下,使一位数码管显示0~9中的某一数字,八位数码管从左向右依次显示0~7。通过该案例了解数码管的工作原理及学习七段数码管的显示方法。
1.要点分析
(1)数码管结构。LED数码管显示器内部是由7个条形发光二极管以及一个小圆点发光二极管组成的,每一个发光二极管称为一个字段,因此其控制原理类似于发光二极管的控制原理。常见数码管有10根管脚,管脚排列如图3-18(a)所示,其中COM为公共端。根据发光二极管的接线形式不同,可以分为共阳极(发光二极管阳极都接在一个公共点上)和共阴极(发光二极管阴极都接在一个公共点上)。在使用时,共阳极数码管接电源,如图3-18(c)所示,共阴极数码管接地,如图3-18(b)所示。

图3-18 数码管管脚排列图
(2)数码管显示原理。LED数码管显示器段码图如图3-19所示,加上正电压发光,加零电压的则不能发光,亮暗的组合形成不同的字型,这种组合称为字型码。共阳极和共阴极的字形码组合是不同的。本书将以如图3-20和图3-21所示的数码管硬件连接图为例进行说明。如果是共阳极数码管,由于COM端连接高电平,因此数据段为低电平时,对应的发光二极管亮。则如果要显示数字1,则
dp g f e d c b a对应电平为
1 1 1 1 1 0 0 1
即为0Xf9H,其他诸如0,2,3,4,5,6,7,8,9数字类似。

图3-19 数码管段码图 图3-20数码管硬件连接图1

图3-21 数码管硬件连接图2
2.实验步骤
第一步:定义数据位DIG_DATA、锁存位DIG_STCP、移位位DIG_SHCP,以及数字0~9对应电平显示NUMCODE[10]和8个数码管SELCODE[9]的顺序。
第二步:初始化数码管,所有数据清零,数码管不显示。
第三步:设计函数digOutputunsigned char Select, unsigned char Data,在Select指定的位上显示数字Data,并且循环调用digOutputchar,char函数。
3.参考答案

#include
sbit DIG_DATA = P0^2;数据
sbit DIG_STCP = P2^3;锁存
sbit DIG_SHCP = P0^4;移位
#define NUMLENGTH 10
#define SELELENTH 9
unsigned char code NUMCODE[NUMLENGTH]={0xC0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned char code SELCODE[SELELENTH]={0xff,0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
*
按照原理图的连线方法,DIG_SHCP的前8个上升沿导致第一块595的8个数据位保存为设置的值,后8个上升沿导致第二块595的8个数据位保存为设置的值。最后DIG_STCP的上升沿让这些数据出现在对应的输出管脚上,并锁存。本案例中采用共阳极数码管,故高电平时对应的段不亮,低电平时对应的段亮
*
void digOutputunsigned char Select, unsigned char Data
{
unsigned char xdata i;
DIG_SHCP = 0;
DIG_STCP = 0;
for i=0;i
{
DIG_DATA=Data & 0x80 ? 1:0;
DIG_SHCP=1;
DIG_SHCP=0;
Data
}
for i=0;i
{
DIG_DATA=Select & 0x80 ? 1:0;
DIG_SHCP=1;
DIG_SHCP=0;
Select
}
DIG_STCP=1;
DIG_STCP=0;
}
*初始化数码管,所有数据清零,数码管无显示*
void InitDig
{
DIG_STCP=0;
DIG_SHCP=0;
digOutput0x00,0xff;
}
int main
{
unsigned int i;
InitDig;
while1
{
for i=0;i
{
digOutputSELCODE[8-i],NUMCODE[i];
}
}
return 0;
}

4.效果演示
如图3-22所示。

图3-22 数码管显示数字演示图
3.8案例显示字符串
在LCD12864液晶显示屏上显示学校名、专业、学号以及姓名。通过该案例了解LCD12864液晶显示屏的工作原理及学习如何在LCD12864上显示字符串。
1.要点分析
(1)LCD12864说明。LCD12864具有48位并行、2线或者3线串行多接口方式,其显示分辨率为12864,内置8192个16*16点阵汉字以及128 个16*8点ASCII字符集,具有低电压低功耗的特点。模块接口说明见表3-3所示。
表3-3模块接口说明

管脚号
管脚名称
电平
管脚功能描述

1
VSS
0V
电源地

2
VCC
3.0 5V
电源正

3
V0

对比度(亮度)调整

4
RSCS)
HL
RS=H,表示DB7~DB0为显示数据
RS=L,表示DB7~DB0为显示指令数据

5
RWSID
HL
RW=H,E=H,数据被读到DB7~DB0
RW=L,E=HL,DB7~DB0的数据被写到IR或DR

6
ESCLK
HL
使能信号

7
DB0
HL
三态数据线

8
DB1
HL
三态数据线

9
DB2
HL
三态数据线

10
DB3
HL
三态数据线

11
DB4
HL
三态数据线

12
DB5
HL
三态数据线

13
DB6
HL
三态数据线

14
DB7
HL
三态数据线

15
PSB
HL
H:8位或4位并口方式,L:串口方式

16
NC

空脚

17
RESET
HL
复位端,低电平有效

18
VOUT

LCD驱动电压输出端

19
A
VDD
背光源正端( 5V)

20
K
VSS
背光源负端


(2)控制器接口信号说明。RS、RW的配合选择决定控制界面的4种模式如表3-4所示,E信号见表3-5,指令说明见表3-6。
表3-4RS、RW的配合选择决定控制界面的4种模式

RS
RW
功 能 说 明

L
L
MPU写指令到指令暂存器(IR)

L
H
读出忙标志(BF)及地址计数器(AC)的状态

H
L
MPU写入数据到数据暂存器(DR)

H
H
MPU从数据暂存器(DR)中读出数据

表3-5E信号

E状态
执行动作
结果

高低
IO缓冲DR
配合W进行写数据或指令


DRIO缓冲
配合R进行读数据或指令

低低高
无动作


表3-6指令说明

指令
指 令 码
功 能

RS
RW
D7
D6
D5
D4
D3
D2
D1
D0

清除
显示
0
0
0
0
0
0
0
0
0
1
将DDRAM填满"20H",并且设定DDRAM的地址计数器AC到"00H"

地址
归位
0
0
0
0
0
0
0
0
1
X
设定DDRAM的地址计数器AC到"00H",并且将游标移到开头原点位置;这个指令不改变DDRAM的内容

显示状
态开关
0
0
0
0
0
0
1
D
C
B
D=1: 整体显示ON
C=1: 游标ON
B=1:游标位置反白允许

进入点
设定
0
0
0
0
0
0
0
1
ID
S
指定在数据的读取与写入时,设定游标的移动方向及指定显示的移位

游标或
显示移
位控制
0
0
0
0
0
1
SC
RL
X
X
设定游标的移动与显示的移位控制位;这个指令不改变DDRAM的内容

功能
设定
0
0
0
0
1
DL
X
RE
X
X
DL=01:48位数据
RE=1: 扩充指令操作
RE=0: 基本指令操作

设定
CGRAM
地址
0
0
0
1
AC5
AC4
AC3
AC2
AC1
AC0
设定CGRAM 地址

设定
DDRAM
地址
0
0
1
0
AC5
AC4
AC3
AC2
AC1
AC0
设定DDRAM地址(显示位址)
第一行:80H~87H
第二行:90H~97H

读取忙
标志和
地址
0
1
BF
AC6
AC5
AC4
AC3
AC2
AC1
AC0
读取忙标志BF可以确认内部动作是否完成,同时可以读出地址计数器AC的值

写数据
到RAM
1
0
数 据
将数据D7~D0写入到内部的RAM DDRAMCGRAMIRAMGRAM

读出
RAM的值
1
1
数 据
从内部RAM读取数据D7~D0
DDRAMCGRAMIRAMGRAM


2.实验步骤
第一步:定义端口号和要写入的数据。
第二步:初始化LCD12864液晶显示屏。
第三步:分别将要显示的字符串写入LCD12864显示屏:
查忙(类似读取LCD12864的数据);
RS置低;
RW置低;
E置高;
总线放数据(命令);
稍作延时;
E置低。
3.参考答案

#include
#include
#include
#define LCD12864_DATA P0
sbit LCD12864_RS = P2^7;RS=0表示命令,RS=1表示数据
sbit LCD12864_RW = P2^6;RW=0表示写数据,RW=1表示读数据
sbit LCD12864_EN = P2^5;液晶使能控制
sbit LCD12864_RST = P2^2;液晶复位端口
sbit LCD12864_PSB = P2^4;串、并方式控制
unsigned char code LINES[] = {0x80,0x90,0x88,0x98};
*
LCD12864读的时序
1.RS置低;
2.RW置高;
3.E置高;
4.稍作延时;
5.数据出现在总线上;
6.E置低。
*
bit CheckBusy12864void检测忙信号
{
unsigned char xdata i;
LCD12864_RS = 0;
LCD12864_RW = 1;
LCD12864_EN = 1;
_nop_;
i = LCD12864_DATA;
LCD12864_EN = 0;
return i & 0x80 ? 1 : 0;
}
*
LCD12864写的时序
1.RS置低;
2.RW置低;
3.E置高;
4.总线放数据;
5.稍作延时;
6.E置低。
*
void WriteCommand12864unsigned char Cmd
{
whileCheckBusy12864;
LCD12864_RS = 0;
LCD12864_RW = 0;
LCD12864_EN = 1;
LCD12864_DATA = Cmd;写入指令
_nop_;
LCD12864_EN = 0;
}
void WriteData12864unsigned char Data
{
whileCheckBusy12864;
LCD12864_RS = 1;
LCD12864_RW = 0;
LCD12864_EN = 1;
LCD12864_DATA = Data;写入数据
_nop_;
LCD12864_EN = 0;
}
void InitLCD12864void
{
unsigned int xdata a=1000;
LCD12864_RST = 1;液晶复位置为1
LCD12864_PSB = 1;将PSB置为1,通信方式为8位数据并口
WriteCommand128640x30;P6 功能设定基本指令集动作
WriteCommand128640x0c; P6 显示状态整体显示ON,游标OFF,游标位置OFF
WriteCommand128640x01;P6 清除显示将DDRAM 填满20H,并且设定DDRAM 的地址计数器(AC)到00H
WriteCommand128640x06;P6 进入点设定指定在资料的读取与写入时,设定游标移动方向及指定显示的移位
whilea--;
}
*
将字符串写入第Line行,如果宽度超过7,则从位置0开始覆盖;Position的取值范围为0~7,Line的取值范围为0~3
*
void DisString12864const char *str, unsigned char Line,const unsigned char Position
{
char *p = str;
unsigned char xdata j;
ifLine 3
{
return ;
}
j = Position % 8;纵坐标从第几个开始
j= LINES[Line];初始位置向后移动j个字节
WriteCommand12864j;写入纵坐标
while*p
{
WriteData12864*p;
p;
}
}
int main
{
unsigned char xdata str1[20]="西安交通大学";
unsigned char xdata str2[20]="计算机01班";
unsigned char xdata str3[20]="215000156";
unsigned char xdata str4[20]="路人甲";
unsigned int xdata i = 0;
InitLCD12864;
DisString12864str1,0,1;
DisString12864str2,1,1;
DisString12864str3,2,1;
DisString12864str4,3,1;
while1;
return 0;
}

4.效果演示
如图3-23所示。

图3-23LCD12864液晶显示字符串演示图
3.9案例时钟芯片显示日期
DS1302是美国DALLAS公司推出的一种高性能、低功耗并且带有RAM的实时时钟电路,可以对年、月、周、日、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.0~5.5V。通过该案例让读者了解时钟芯片DS1302与单片机的接口以及如何对DS1302编程。
1.要点分析
DS1302的引脚排列如图3-24所示,各引脚说明如表3-7所示,其中RST的输入有两种功能,一是RST接通控制逻辑,允许地址命令序列送入移位寄存器;二是RST提供终止单字节或多字节数据传送。当RST为高电平时,所有的数据传送被初始化,允许对DS1302进行操作。如果在传送过程中RST置为低电平,则会终止此次数据传送,IO引脚变为高阻态。上电运行时,在VCC2.0V之前,RST必须保持低电平。只有在SCLK为低电平时,才能将RST置为高电平。

图3-24 DS1302引脚排列图
表3-7 DS1302引脚功能说明

引脚号
名 称
功 能

1
VCC1
备份电源输入

2
X1
32.768kHz晶振输入

3
X2
32.768kHz晶振输出

4
GND
接地

5
RST
控制移位寄存器复位

6
IO
数据输入输出

7
SLCK
串行时钟

8
VCC2
主电源输入


DS1302 控制字节的最高有效位(位7)必须是逻辑1,如果它为0,则不能把数据写入DS1302中,位6如果为0,则表示存取日历时钟数据,为1表示存取RAM数据;位5至位1指示操作单元的地址;最低有效位(位0)如为0表示要进行写操作,为1表示进行读操作,控制字节总是从最低位开始输出。
在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从低位即位0开始。同样,在紧跟8位的控制指令字后的下一个SCLK脉冲的下降沿读出DS1302的数据,读出数据时从低位0到高位7。
此外,DS1302还有年份寄存器、控制寄存器、充电寄存器、时钟突发寄存器及与RAM相关的寄存器等。时钟突发寄存器可一次性顺序读写除充电寄存器外的所有寄存器内容。DS1302与RAM相关的寄存器分为两类:一类是单个RAM单元,共31个,每个单元组态为一个8位的字节,其命令控制字为C0H~FDH,其中奇数为读操作,偶数为写操作;另一类为突发方式下的RAM寄存器,此方式下可一次性读写所有的RAM的31个字节,命令控制字为FEH(写)、FFH(读)。
2.实验步骤
第一步:变量、显示驱动程序初始化。
第二步:使DS1302没有写保护。
第三步:复位端产生一个高电平。
第四步:写入数据(写DS1302地址延时一段时间向该地址写入数据地址增 加循环,直到写完所有数据)。
第五步:复位端产生一个高电平。
第六步:读取数据(写DS1302地址延时一段时间读取该地址的数据地址增 加循环,直到读完所有数据)。
第七步:显示驱动程序。
第八步:驱动LED显示。
3.参考答案
(1)主函数main.c

#include
#include
#include "system.h"
#include "LCD12864.h"
#include "DS1302.h"
*
日期显示在第几行第几列
*
#define DATA_X 1 注:0是第一行
#define DATA_Y 1
*
时间显示在第几行和第几列
*
#define TIME_X 2
#define TIME_Y 1
*
用于将数据转换为字符输出
*
void BCD2ASCunsigned char *des,const unsigned char Byte
{
*des=Byte4 0x30;
*des 1=Byte & 0x0f 0x30;
}
*
用于设定日期显示格式,调用DisString12864函数
*
void PrintDataTime212864const struct DataTime *pdt
{
unsigned char xdata str[17];
char*p=str;
*p=''2'';
*p=''0'';前两个字符预设成20,因为DS1302里面表示年份的是19开头
BCD2ASCp,pdt-Year;
p =2;
*p=''-'';
BCD2ASCp,pdt-Month;
p =2;
*p=''-'';
BCD2ASCp,pdt-Day;
p =2;
*p=0;
DisString12864str,DATA_X,DATA_Y;参考上一节代码
p=str;
BCD2ASCp,pdt-Hour;
p =2;
*p='':'';
BCD2ASCp,pdt-Minute;
p =2;
*p='':'';
BCD2ASCp,pdt-Second;
p =2;
*p=0;
DisString12864str,TIME_X,TIME_Y;参考上一节代码
}
int main
{
unsigned int xdata i=0;
unsigned char xdata a=1000;
设置时间为16年10月18日15点42分30秒
struct DataTime xdata dt={0x16,0x10,0x18,0x15,0x42,0x30};
SystemInit; 初始化计时设定
InitLCD12864;LCD12864初始化
SetTime&dt;时间设定
while1
{
i;
ReadTime&dt;读入时间
PrintDataTime212864&dt;按先前设定格式打印出时间
whilea--;
}
return 0;
}
(2)初始化计时器设定system.c

#include
#include "config.h"
#include
unsigned int xdata times = 0;
sfr WDT_CONTR = 0xE1;定义STC单片机中新加入的看门狗寄存器
static void DisableWDTvoid
{
WDT_CONTR &= ~1
EA = 1;中断总允许位
}
*
定时器0中断初始化子程序
*
static void SetTimer0void
{
TMOD &= 0xF0;清零T0的控制位(TMOD最左边的二进制4位保留不变,其他位全部清零)
TMOD |= 0x01;配置T0为模式1(将TMOD的最低位设为1,即将定时计数器的其工作方式调整为方式1)
TL0 = T0NS;初始值TL0(16位定时器计数器的低8位)
TH0 = T0NS 8;初始值TH0(16位定时器计数器的高8位)
TL0 = 0;
ET0 = 1;T0中断允许
}
*
初始化时间设定
*
void SystemInitvoid
{
DisableWDT;
SetTimer0;
}

(3)设定日期时间DS1302.c

#include "DS1302.h"
*
设置数据传递(上升沿)
*
void TransmitByteunsigned char Data
{
unsigned char xdata i;
fori=0;i
{
RTC_CLK=0;
RTC_IO=Data & 0x01 ? 1:0;
RTC_CLK=1;上升沿
Data=1;
}
}
*
接收读取数据(下降沿)
*
unsigned char ReceiveByte
{
unsigned char xdata ret,i;
fori=0;i
{
RTC_CLK=0;下降沿,读取数据
ret=1;
ifRTC_IO
{
ret |=0x80;
}
else
{
ret &=~0x80;
}
RTC_CLK=1;
}
return ret;
}
*
写数据操作
*
void WriteDS1302unsigned char Address,unsigned char Data
{
RTC_RST=0;停止工作
RTC_CLK=0;
RTC_RST=1;重新工作
TransmitByteAddress;写入地址
TransmitByteData;
RTC_RST=0;
}
*
读数据操作(先送地址,再读数据)
*
unsigned char ReadDS1302unsigned char Address
{
unsigned char ret;
RTC_RST=0;停止工作
RTC_CLK=0;
RTC_RST=1;重新工作
TransmitByteAddress;写入地址
ret=ReceiveByte;
RTC_RST=0;
return ret;
}
*
初始化DS1302
反复调用WriteDS1302根据ds1302.h中宏定义的日期数据进行设置
*
void SetTimestruct DataTime *pdt
{
WriteDS1302ADR_W_WP,WP_OFF;
WriteDS1302ADR_W_YEAR,pdt-Year; 年
WriteDS1302ADR_W_MONTH,pdt-Month; 月
WriteDS1302ADR_W_DATA,pdt-Day;日
WriteDS1302ADR_W_HOUR,pdt-Hour;小时
WriteDS1302ADR_W_MINUTES,pdt-Minute;分钟
WriteDS1302ADR_W_SECONDS,pdt-Second;秒
WriteDS1302ADR_W_WP,WP_ON; 打开
}
*
反复调用ReadDS1302根据ds1302.h中宏定义的日期数据进行读取
*
void ReadTimestruct DataTime *pdt
{
pdt-Second=ReadDS1302ADR_R_SECONDS;
pdt-Minute=ReadDS1302ADR_R_MINUTES;
pdt-Hour=ReadDS1302ADR_R_HOUR;
pdt-Day=ReadDS1302ADR_R_DATA;
pdt-Month=ReadDS1302ADR_R_MONTH;
pdt-Year=ReadDS1302ADR_R_YEAR;
}

(4)*.h文件system.h

#ifndef _SYSTEM_H_
#define _SYSTEM_H_
extern void SystemInitvoid;
#endif

(5)*.h文件DS1302.h

#include
#ifndef _DS1302_H_
#define _DS1302_H_
*
定义日期数据格式
*
struct DataTime
{
unsigned char Year;
unsigned char Month;
unsigned char Day;
unsigned char Hour;
unsigned char Minute;
unsigned char Second;
};
sbit RTC_IO=P2^1; 实时时钟数据线引脚
sbit RTC_RST=P3^7;实时时钟复位线引脚
sbit RTC_CLK=P3^6;实时时钟时钟线引脚
*
初始化DS1302
设置时间
*
void SetTimestruct DateTime *pdt;
*
显示时间
*
void ReadTimestruct DataTime *pdt;
*
定义控制指令寄存器地址,参考英文手册
*
#define ADR_R_SECONDS 0x81
#define ADR_R_MINUTES 0x83
#define ADR_R_HOUR 0x85
#define ADR_R_DATA 0x87
#define ADR_R_MONTH 0x89
#define ADR_R_DAy 0x8b
#define ADR_R_YEAR 0x8d
#define ADR_R_WP 0x8f
#define ADR_W_SECONDS 0x80
#define ADR_W_MINUTES 0x82
#define ADR_W_HOUR 0x84
#define ADR_W_DATA 0x86
#define ADR_W_MONTH 0x88
#define ADR_W_DAy 0x8a
#define ADR_W_YEAR 0x8c
#define ADR_W_WP 0x8e
*
定义寄存器写保护开关指令,指令最高置0或1
*
#define WP_ON 0x80
#define WP_OFF 0x00
#endif

(6)*.h文件config.h

#ifndef _CONFIG_H_
#define _CONFIG_H_
#define BIT16 0xFFFF
#define BIT8 0xFF
#define FCOS 12000000L
#define CYCLE_TIME0 200定时计数器0中断时间微秒,该值不能大于254
#define T0NS BIT16 - CYCLE_TIME0 *1000000 FCOS 12
#endif

4.效果演示
如图3-25所示。

图3-25 显示日期时间截图
编 程 练 习
1. 编程实现:呼吸灯与流水灯结合,即0、1、2、3、4、5、6、7号LED依次渐亮 渐灭。
2. 编程实现:数码管循环显示数字0~9,时间间隔为0.2s。
3.编程实现:在LCD12864液晶显示屏上同时显示字符串和日期。

 

 

書城介紹  | 合作申請 | 索要書目  | 新手入門 | 聯絡方式  | 幫助中心 | 找書說明  | 送貨方式 | 付款方式 香港用户  | 台灣用户 | 海外用户
megBook.com.tw
Copyright (C) 2013 - 2024 (香港)大書城有限公司 All Rights Reserved.