
课 程 设 计
课 程 单片机的控制系统课程设计
题 目 基于单片机的计算器
院 系
专业班级
学生姓名
学生学号
指导教师
2013年 7 月 7 日
第一章 绪 论
1.1 系统开发背景
随着社会的发展,科学的进步,人们的生活水平在逐步的提高,尤其是微电子技术的发展,犹如雨后春笋般的变化。电子产品的更新速度快就不足惊奇了。计算器在人们的日常中是比较的常见的电子产品之一。如何使计算器技术更加的成熟,充分利用已有的软件和硬件条件,设计出更出色的计算器,使其更好的为各个行业服务,成了如今电子领域重要的研究课题。
1.2课题简介
当今社会,随着人们物质生活的不断提高,电子产品已经走进了家家户户,无论是生活或学习,还是娱乐和消遣几乎样样都离不开电子产品,大型复杂的计算能力是人脑所不能胜任的,而且比较容易出错。计算器作为一种快速通用的计算工具方便了用户的使用。计算器可谓是我们最亲密的电子伙伴之一。本设计着重在于分析计算器软件和开发过程中的环节和步骤,并从实践经验出发对计算器设计做了详细的分析和研究。
单片机由于其微小的体积和极低的成本,广泛的应用于家用电器、工业控制等领域中。在工业生产中。单片微型计算机是微型计算机的一个重要分支,也是颇具生命力的机种。单片微型计算机简称单片机,特别适用于控制领域,故又称为微控制器。本系统就是充分利用了8051芯片的I/O引脚。系统以采用MCS-51系列单片机Intel8051为中心器件来设计计算器控制器,实现了能根据实际输入值显示并存储的功能,计算程序则是参照教材。至于位数和功能,如果有需要可以通过设计扩充原系统来实现。
1.3 单片机的发展现状
单片机的发展趋势:低功耗CMOS化;微型单片化;主流与多品种共存;单片机从8位、16位到32位,数不胜数,应有尽有,有与主流C51系列兼容的,也有不兼容的,但它们各具特色,互成互补,为单片机的应用提供广阔的天地。 纵观单片机的发展历程,可以发现单片机的发展趋势大致有:
1、低功耗CMOS化
MCS-51系列的8051推出时的功耗达630mW,而现在的单片机普遍都在100mW左右,随着对单片机功耗的要求越来越低,现在的各个单片机制造商基本都采用了CMOS(互补金属氧化物半导体工艺)。像80C51就采用了HMOS(即高密度金属氧化物半导体工艺)和CHMOS(互补高密度金属氧化物半导体工艺)。CMOS虽然功耗较低,但由于其物理特征决定了其工作速度不够高,而CHMOS则具备了高速和低功耗的特点,这些特征,更适合于在要求低功耗象电池供电的应用场合。所以这种工艺将是今后一段时期内单片机发展的主要途径。
2、微型单片化
现在常规的单片机普遍都是将处理器(CPU)、随机存取数据存储(RAM)、只读程序存储器(ROM)、并行和串行通信接口、中断系统、定时电路、时钟电路集成在一块单一的芯片上,增强型的单片机集成了如A/D转换器、PMW(脉宽调制电路)、WDT(看门狗),有些单片机将LCD(液晶)驱动电路都集成在单一的芯片上,这样单片机包含的单元电路就更多,功能就更强大。甚至单片机厂商还可以根据用户的要求量身定做,制造出具有自己特色的单片机芯片。
此外,现在的产品普遍要求体积小、重量轻,这就要求单片机除了功能强和功耗低外,还要求其体积要小。现在的许多单片机都具有多种封装形式,其中SMD(表面封装)越来越受欢迎,使得由单片机构成的系统正朝微型化方向发展。
3、主流与多品种共存
现在虽然单片机的品种繁多,各具特色,但仍是以80C51为核心的单片机占主流,兼容其结构和指令系统的有PHILIPS公司的产品,ATMEL公司的产品和中国的Winbond系列单片机。因此以80C51为核心的单片机占据了半壁江山。而Microchip公司的PIC精简指令集(RISC)也有着强劲的发展势头,中国的HOLTEK公司近年的单片机产量与日俱增,以其价低质优的优势,占据一定的市场份额。此外还有MOTOROLA公司的产品,日本几大公司的专用单片机。在一定的时期内,这种形势将得以延续,将不存在某个单片机一统天下的垄断局面,走的是依存互补,相辅相成、共同发展的道路。
1.4 设计目的
本设计旨在进一步掌握单片机理论知识,理解嵌入式单片机系统的硬软件设计,加强对实际应用系统设计的能力。通过本设计的学习,使我掌握单片机程序设计和微机接口应用的基本方法,并能综合运用本科阶段所学软、硬件知识分析实际问题,提高解决毕业设计实际问题的能力,为单片机应用和开发打下良好的基础。
1、对字符液晶显示模块的工作原理,如初始化、清屏、显示、调用及外特性有较清楚的认识,并会使用LCD(液晶显示模块)实现计算结果的显示;掌握液晶显示模块的驱动和编程,设计LCD和单片机的接口电路,以及利用单片机对液晶模块的驱动和操作:
2、在充分分析内部逻辑的概念,进行软件和调试,学会使用,并能够以其为平台设计出具有四则运算能力简易计算器的硬件电路和软件程序。
第二章 系统硬件设计及说明
2.1系统组成及总体框图
图2-1 系统组成及总体框图
2.2元件简介
2.2.1 ATS52特点
1、ATS52的功能特性描述
ATS52 是一种低功耗、高性能CMOS8位微控制器,具有 8K 在系统可编程Flash 存储器。使用Atmel 公司高密度非 易失性存储器技术制造,与工业80C51 产品指令和引脚完 全兼容。片上Flash允许程序存储器在系统可编程,亦适于 常规编程器。在单芯片上,拥有灵巧的8 位CPU 和在系统 可编程Flash,使得ATS52为众多嵌入式控制应用系统提 供高灵活、超有效的解决方案。
ATS52具有以下标准功能: 8k字节Flash,256字节RAM, 32 位I/O 口线,看门狗定时器,2 个数据指针,三个16 位 定时器/计数器,一个6向量2级中断结构,全双工串行口, 片内晶振及时钟电路。
此外, ATS52 可降至0Hz 静态逻 辑操作,支持2种软件可选择节电模式。空闲模式下,CPU 停止工作,允许RAM、定时器/计数器、串口、中断继续工 作。掉电保护方式下,RAM内容被保存,振荡器被冻结, 单片机一切工作停止,直到下一个中断或硬件复位为止。8 位微控制器 8K 字节在系统可编程 Flash。同时该芯片还具有PDIP、TQFP和PLCC等三种封装形式,以适应不同产品的需求。
2、ATS52引脚功能
ATS52 单片机为40 引脚芯片见图2-2。
图2-2 ATS52引脚图
(1)口线:P0、P1、P2、P3 共四个八位口。
P0口:P0口是一个8位漏极开路的双向I/O口。作为输出口,每位能驱动8个TTL逻辑电平。对P0端口写“1”时,引脚用作高阻抗输入。当访问外部程序和数据存储器时,P0口也被作为低8位地址/数据复用。在这种模式下,P0不具有内部上拉电阻。
P1口:P1 口是一个具有内部上拉电阻的8 位双向I/O 口,p1 输出缓冲器能驱动4 个TTL 逻辑电平。对P1 端口写“1”时,内部上拉电阻把端口拉高,此时可以作为输入口使用。
P2口:P2 口是一个具有内部上拉电阻的8 位双向I/O 口,P2 输出缓冲器能驱动4 个TTL 逻辑电平。对P2 端口写“1”时,内部上拉电阻把端口拉高,此时可以作为输入口使用。作为输入使用时,被外部拉低的引脚由于内部电阻的原因,将输出电流(IIL)。
在访问外部程序存储器或用16位地址读取外部数据存储器(例如执行MOVX @DPTR) 时,P2 口送出高八位地址。在这种应用中,P2 口使用很强的内部上拉发送1。
在使用8位地址(如MOVX @RI)访问外部数据存储器时,P2口输出P2锁存器的内容。
P3 口:P3口是一个具有内部上拉电阻的8 位双向I/O 口,P3 输出缓冲器能驱动4个TTL逻辑电平。对P3 端口写“1”时,内部上拉电阻把端口拉高,此时可以作为输入口使用。作为输入使用时,被外部拉低的引脚由于内部电阻的原因,将输出电流(IIL)。
P3口亦作为ATS52特殊功能(第二功能)使用,如表2-1所示。
表2-1 P3口管脚 备选功能:
| 端口引脚 | 第二功能 | 端口引脚 | 第二功能 |
| P3.0 | RXD(串行输入口) | P3.4 | T0(记时器0外部输入) |
| P3.1 | TXD(串行输出口) | P3.5 | T1(记时器1外部输入) |
| P3.2 | /INT0(外部中断0) | P3.6 | /WR(外部数据存储器写选通) |
| P3.3 | /INT1(外部中断1) | P3.7 | /RD(外部数据存储器读选通) |
(2)其他引脚说明:
RST:复位输入。晶振工作时,RST脚持续2 个机器周期高电平将使单片机复位。
ALE/PROG:当访问外部程序存储器或数据存储器时,ALE(地址锁存允许)输出脉冲用于锁存地址的低8位字节。
PSEN:程序储存允许(PSEN)输出是外部程序存储器的读选通信号,当ATS52由外部程序存储器取指令(或数据)时,每个机器周期两次PSEN有效,即输出两个脉冲,在此期间,当访问外部数据存储器,将跳过两次PSEN信号。
EA/VPP:外部访问允许,欲使CPU仅访问外部程序存储器(地址为0000H-FFFFH),EA端必须保持低电平(接地)。如EA端为高电平(接Vcc端),CPU则执行内部程序存储器的指令。
XTAL1:反向振荡放大器的输入及内部时钟工作电路的输入。
XTAL2:来自反向振荡器的输出。
XTAL1,XTAL2接石英晶体振荡器。如图2-3所示外接晶体引脚图。
C2 XTAL2
悬空 XTAL2
C1
XTAL1 外部振荡信号 XTAL1
GND GND
接地 接地
a.内部方式 b.外部方式
图2-3 晶振外接结构引脚图
XTAL1是片内振荡器的反相放大器输入端,XTAL2则是输出端,使用外部振荡器时,外部振荡信号应直接加到XTAL1,而XTAL2悬空。内部方式时,时钟发生器对振荡脉冲二分频,如晶振为12MHz,时钟频率就为6MHz。晶振的频率可以在1MHz-24MHz内选择,在本设计电路中选用了12MHz。电容取20PF左右。机器周期=12×时间周期,如12MHz的机器周期为1微秒。
(3)控制或复位引脚
RESET 此脚为高电平时(约2个机器周期)可将单片机复位。
RST/VPD——当出现两个机器周期高电平时,单片机复位。复位后,P0~P3输出高电平;SP寄存器为07H;其它寄存器全部清0;不影响RAM状态。如图2-4所示。
图2-4按键电平复位
2.2.2 74LS08简要说明
74LS08逻辑图:
图2-5 74LS08逻辑图
引出端符号 :1A-4A 输入端 1B-4B 输入端 1Y-4Y 输出端
74LS08功能表:
表2-2 74LS08功能表(Y=AB)
| Inputs | Output | |
| A | B | Y |
| L L H H | L H L H | L L L H |
1、应用简介
模块内部自带字符发生存储器(CGROM),字符有:阿拉伯数字、英文字母的大小写、常用的符号、和日文假名等,每一个字符都有一个固定的代码,比如大写的英文字母“A”的代码是(41H),显示时模块把代码41H发给液晶模块,我们就能在液晶上看到字母“A”。
1602液晶模块内部的控制器共有11条控制指令,丰富的指令可以完成液晶的时序控制、工作方式式设置和数据显示等。
采用的LCD1602液晶模块是标准16针插座,接口电路如图2-6所示:关于LCD1602的详细资料见表2-3和表2-4。
图2-6 LCD接口电路
表2-3 LCD1602引脚说明
| 第1脚 | VSS为地电源 |
| 第2脚 | VDD接5V正电源 |
| 第3脚 | V0为液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度。 |
| 第4脚 | RS为寄存器选择,高电平选择数据寄存器、低电平选择指令寄存器。 |
| 第5脚 | RW为读写信号线,高电平时进行读操作,低电平时进行写操作。 当RS和RW共同为低电平时 (00)可以写入指令或者显示地址; 当RS为低电平RW为高电平时(01)可以读入忙信号; 当RS为高电平RW为低电平时(10)可以写入数据。 |
| 第6脚 | E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。 |
| 第7~14脚 | D0~D7为8位双向数据线。 |
| 第15~16脚 | 背光阳极和背光阴极。 |
| 指令1 | 清显示 指令码01H, 光标复位到地址00H位置; |
| 指令2 | 光标复位 指令码02H, 光标返回到地址00H位置 ; |
| 指令3 | 光标和显示模式设置 I/D位 → 光标移动方向,高电平右移,低电平左移; S 位 → 屏幕上所有文字是否左移或者右移,高电平有效,低电平无效; |
| 指令4 | 显示开关控制 D 位 → 控制整体显示的开与关,高电平表示开显示,低电平表示关显示; C 位 → 控制光标的开与关,高电平表示有光标,低电平表示无光标; B 位 → 控制光标是否闪烁,高电平闪烁,低电平不闪烁 ; |
| 指令5 | 光标或显示移位 S/C位 → 高电平时移动显示的文字,低电平时移动光标 |
| 指令6 | 功能命令设置 DL位---高电平时为4位数据总线,低电平时为8位总线; N—位低电平时为单行显示,高电平时为双行显示; F—位低电平时显示5x7的点阵字符,高电平时为5x10的点阵字符; |
| 指令7 | 字符发生器RAM地址设置 |
| 指令8 | DDRAM地址设置 |
| 指令9 | 读忙信号和光标地址 BF位 → 为忙标志位,高电平表示忙,此时模块不能接收命令或者数据 |
| 指令10 | 写数据 |
| 指令11 | 读数据 |
3.1 设计方案的确定
本设计需要使用LCD液晶显示屏和编码键盘。故选择静态显示和用编码键盘。使用LCD液晶显示屏显示运算结果。主程序进行初始化,其他的程序选择模块式的方式。首先对每个模块进行调试, 当模块调试成功后,逐一的加入主程序中,最后完成整个软件部分的设计。
3.2计算器硬件方案及硬件资源分配
3.2.1 硬件资源分配
主要用到的硬件:ATS52 LCD液晶显示屏 编码键盘
硬件分配:1、P0、P3口:做为输出口,控制LCD液晶显示屏显示数据的结果。
2、P1口:做为输入口,与键盘连接,实现数据的输入。
3、LCD液晶显示屏显示输出。
下图为总体硬件结构。(如图3-1 所示为整个系统的原理图)
图3-1 计算器原理图
前面叙述了该系统的设计说明,系统采用了比较简单的设计方案,所以该系统的硬件设计的总外围电路不会产生过多的干扰。在下面的阐述中,对系统的外围电路分别予以介绍。键盘部分采用编码键盘,显示部分采用LCD液晶显示屏完全能够很好的实现显示方面的要求。
3.2.2 键盘电路的设计
键盘可分为两类:编码键盘和非编码键盘。编码键盘是较多按键(20个以上)和专用驱动芯片的组合,当按下某个按键时,它能够处理按键抖动、连击等问题,直接输出按键的编码,无需系统软件干预。通用计算机使用的标准键盘就是编码键盘。在智能仪器中,使用并行接口芯片8279或串行接口芯片HD7279均可以组成编码键盘,同时还可以兼顾数码管的显示驱动,其相关的接口电路和接口软件均可在芯片资料中得到。当系统功能比较复杂,按键数量很多时,采用编码键盘可以简化软件设计。非编码键盘成本低廉。(如图3-2)
图3-2 编码键盘电路
3.2.3 显示电路的设计
当系统需要显示少量数据时,采用LCD液晶显示屏进行显示是一种经济实用的方法。P0口作为液晶显示的数据端口,P3.5-P3.7口作为其控制端口,控制LCD液晶显示屏显示输出数据。
最终电路如图3-3所示:
图3-3 LCD液晶显示屏显示
第四章 计算器的软件设计
4.1计算器的软件规划
简易计算器的程序主要包括以下功能模块:
1、定时查键模块,分为读键程序、判键程序段、运算操作子程序等部分;
2、基于LCD液晶显示屏的显示模块;
3、主模块,为系统的初始化。
4.2 键盘扫描的程序设计
键盘扫描子程序,首先读出P1的低四位,然后读出P1口的高四位。然后键值并显示缓存。然后将键如的值转换为ASCII码然后就可以软件来设置硬件按键各个键代表的内容。
读键程序使用的是反转法读键,不管键盘矩阵的规模大小,均进行两次读键。第一次所有行线均输出低电平,从所有读入键盘信息(列信息);第二次所有列线均输出低电平,从所有行线读入键盘信息(行信息)。
数字键按下则将相应的数字送入缓存区,功能键按下则执行相应的程序。
4.3 显示模块的程序设计
显示模块程序首先要对显示模块进行初始化;然后控制光标的位置;定义液晶显示的控制端口,用SBIT指令完成;然后设置清屏、关闭显示、归位、开显示、显示位置的首地址等等。
主程序流程图 显示终端流程图 计算子程序流程图
图4-1计算器流程图
第五章 仿真及调试
在程序设计方法上,模块化程序设计是单片机应用中最常用的程序设计方法。设计的中心思想是把一个复杂应用程序按整体功能划分成若干相对的程序模块,各模块可以单独设计、编程和调试,然后组合起来。这种方法便于设计和调试,容易实现多个程序共存,但各个模块之间的连接有一定的难度。根据需要我们可以采用自上而下的程序设计方法,此方法先从主程序开始设计,然后再编制各从属程序和子程序,层层细化逐步求精,最终完成一个复杂程序的设计。这种方法比较符合人们的日常思维,缺点是一级的程序错误会对整个程序产生影响。(如图5-1所示程序仿真图)
功能和操作:加减乘除运算和显示。
1、上电后,屏幕初始化。
2、计算。按下数字键,屏幕显示要运算的第一个数字,再按下符号键,然后再按下数字键,屏幕显示要运算的第二个数字,最后按下“﹦”号键,屏幕上显示出计算结果。
3、如果要再次计算,可以按下“ON/C”键清零,或者按下单片机的复位键,重新初始化。
图5-1程序仿真图
结 论
在硬件的制作过程中我走了好多的弯路,主要是在系统还没有设计很有把握就开始动手制作了。后来发现与设计的要求还有偏差,反复的改过了几次,浪费了大量的时间和体力。感受到设计人员要有耐心,要认真的从要求开始研究。软件的编写过程中费了很大的力气,因为软件的编写要求很高,要很细心,一不小心就会调用错误,很深刻的体会到作为软件编程人员是绝不能粗心大意的。一个程序的完成的速度和质量高低与细心与否有着很大联系。编程时,我充分使用了结构化的思想。这样因为语句较少,程序调试比较方便,功能模块可以逐一的调试,充分体现了结构化编程的优势。当每个模块都完成时,将其功能加到一起就完成了整体的设计。
参考文献
[1]张毅刚.单片机原理及应用[M].北京:高等教育出版社,2010.
[2]蔡美琴.MCS-51系列单片机系统及其应用[M].北京:高等教育出版社,2004.
[3]胡汉才.单片机原理及接口技术[M].北京:清华大学出版社,1996.
[4]徐江海.单片机实用教程[M].北京:机械工业出版社,2007.
[5]肖洪兵. 跟我学用单片机[M]. 北京:北京航空航天大学出版社,2002.8
[6]夏继强. 单片机实验与实践教程[M]. 北京:北京航空航天大学出版社, 2001
[7]谭浩强. C语言程序设计[M].北京:清华大学出版社,2000.
[8]刘福基. C语言程序设计与实训教程[M].北京:科学出版社,2004.
[9]张磊. C语言程序设计[M].北京:高等教育出版社,2005.
附 录
1、主函数设计:
/******************函数声明*****************/
#include #include #define uchar unsigned char #define uint unsigned int char translate(int keycode); void arithmetic(); void init_LCM(); void write_data(char ddata); void write_com(char command); void check_BF(); void clearLCD(); void display(long a); void dealerror(); void dataoverflow(); /****************定义变量和数组**************/ long x=0,y=0,num=0; int operators,input,iny=0; char key; char error[5]="error"; char overflow[8]="overflow"; sbit EN=P3^4; sbit R_W=P3^5; sbit RS=P3^6; /******************主函数*****************/ main() { EA=1; EX0=1; IT0=1; P2=0xff; display(0); init_LCM(); write_data(0x30); while(1) { } } 2、分块程序设计: (1)、键盘输入检测程序设计: 有键按下时,单片机响应外部中断0,转入外部中断0中断处理函数,在中断处理函数中完成对按键的判断,以进行下一步的程序处理。 /**********键值转化为键盘上按键值函数*************/ char translate(int keycode) { switch(keycode) { case 0: return '7'; break; case 1: return '4'; break; case 2:return '1'; break; case 3:return 'c'; break; case 4:return '8'; break; case 5:return '5'; break; case 6:return '2'; break; case 7:return '0'; break; case 8:return '9'; break; case 9:return '6'; break; case 10:return '3'; break; case 11:return '='; break; case 12:return '/'; break; case 13:return '*'; break; case 14:return '-'; break; case 15:return '+'; break; } } /***********外部中断0处理函数*************/ void INT_0(void) interrupt 0 using 0 { key=translate(P2&0x0f); if(key<='9'&&key>='0') //判断按下的键是否为数值 { num=num*10+(key-'0'); if (operators>0) { y=num; iny=1; } else x=num; if(num<134217728&&num>-134217728) //当前数值是否超出限定范围 { display(num); } else dataoverflow(); } else { switch(key) { case 'c': x=0; y=0; num=0; iny=0; operators=0; display(num); break; case '=': arithmetic(); iny=0; operators=0; num=0; break; case '+': if (operators) arithmetic(); operators=1; num=0; break; case '-': if (operators) arithmetic(); operators=2; num=0; break; case '*': if (operators) arithmetic(); operators=3; num=0; break; case '/': if (operators) arithmetic(); operators=4; num=0; break; } } } (2)、算术运算程序设计: /**********算术运算函数*************/ void arithmetic() { if (iny) { switch(operators) { case 1: x=x+y; num=x; if(num<134217728&&num>-134217728) { display(num); } else dataoverflow(); break; case 2: x=x-y; num=x; if(num<134217728&&num>-134217728) { display(num); } else dataoverflow(); break; case 3: x=x*y; num=x; if(num<134217728&&num>-134217728) { display(num); } else dataoverflow(); break; case 4: if (y==0) dealerror(); else { x=x/y; num=x; if(num<134217728&&num>-134217728) { display(num); } else dataoverflow(); } break; } y=0; } } (3)、LCD显示程序设计: 利用LCD静态显示,通过程序向LCD写指令字或数据使LCD完成不同功能或显示相应数据。 /**************LCD初始化函数*************/ void init_LCM() { write_com(0x30); write_com(0x30); write_com(0x30); write_com(0x38); write_com(0x08); write_com(0x01); write_com(0x06); write_com(0x0e); } /***********LCD写数据函数*************/ void write_data(char ddata) { RS=1;/*写指令*/ R_W=0; EN=1;/*使能信号开*/ P1=ddata;/*将数据送入p1口*/ EN=0;/*使能信号关*/ check_BF(); } /***********LCD写指令函数*************/ void write_com(char command) { RS=0;/*写指令*/ R_W=0; EN=1;/*使能信号开*/ P1=command;/*将数据送入p1口*/ EN=0;/*使能信号关*/ check_BF(); } /************LCD检查忙碌函数***********/ void check_BF() { char i,x=0x80; P1=0xff; while(x&0x80) { RS=0; R_W=1; EN=1; x=P1; EN=0; for (i=0;i<10;i++); } EN=0;/*关闭使能信号*/ } /**********LCD清屏函数**********/ void clearLCD() { write_com(0x01); } /**********LCD显示函数**********/ void display(long a) { long temp,b,c=-1; int lenth=1,i,j; clearLCD(); if(a<0) { a=a*c; write_data('-'); } temp=a; while((temp=temp/10)!=0) { lenth++; } for(i=lenth;i>0;i--) { b=1; for(j=0;j b=b*10; } write_data(0x30+a/b); a=a%b; } } (4)、错误处理及提示程序设计: /**********除数为处理函数**********/ void dealerror() { int i=0; clearLCD(); for(i=0;i<5;i++) write_data(error[i]); } /*********数值溢出处理函数**********/ void dataoverflow() { int i=0; clearLCD(); for(i=0;i<8;i++) write_data(overflow[i]); }
