赞
踩
本次设计的题目是:基于51单片机的简易计算机设计。
设计内容:
方案一:采用七段数码管进行静态显示。 当单片机系统中使用静态数码管显示时,需要在每一个数码管上添加一个锁存器,当需要某个数码管显示其他内容时,只需要修改与其相连的锁存器的值即可。 当数码管处于静态显示方式时,所有位选线(数码管的公共端)连接在一起,而各个数码管的段选线(数码管上各笔段的引出线)是相互分离的。优点是数码管显示无闪烁,亮度高,软件控制比较容易;缺点是:需要的硬件电路较多(每一个数码管都需要一个锁存器),同时由于所有数码管都处于被点亮状态,所以需要的电流很大,当数码管的数量增多时,对电源的要求也就随之增高。
方案二:采用LCD1602液晶显示屏显示。能够同时显示16x02即32个字符,1602LCD 液晶具有功耗低、显示内容丰富、清晰,显示信息量大,显示速度较快,界面友好等而得到广泛应用,因此使用1602液晶显示屏,可以方便的显示多种字符,特别适用于洗衣机洗涤模式、洗涤强度和倒计时的双行实时显示。通过D0-D7引脚向LCD写指令字或写数据以使LCD实现不同的功能或显示相应的数据。P0口作为液晶显示的数据端口,与D0-D7连接。P2.1-P2.3口作为其控制端口,控制LCD液晶显示屏显示输出数据,与RS,RW,E,连接 。
综合考虑最终采用方案二,采用LCD1602液晶显示屏实时计算器的运算过程和运算结果。
方案一:采用独立式按键控制洗衣操作。独立按键式直接用I/O口线构成的单个按键电路,其特点是每个按键单独占用一根I/O口线,每个按键的工作不会影响其他I/O口线的状态。独立按键的软件常采用查询式结构。先逐位查询没跟I/O口线的输入状态,如某一根I/O口线输入为低电平,则可确认该I/O口线所对应的按键已按下,然后,再转向该键的功能处理程序。独立式按键电路配置灵活,软件结构简单,可根据实际需要灵活编码,可以直接读取,检测占用时间较少,不受其它因素影响。但每个按键必须占用一个I/O口线,因此,在按键较多时,I/O口线浪费较大,不宜采用。
方案二:采用矩阵按键控制洗衣操作。矩阵键盘又称行列键盘,是用四条I/O线作为行线,四条I/O线作为列线组成的键盘,在行线和列线的每个交叉点上设置一个按键。
按键的位置由行号和列号唯一确定,因此可以分别对行号和列号进行二进制编码,然后两值合成一个字节,高4位是行号,低4位是列号。这样键盘上按键的个数就为4*4个,这种行列式键盘结构能有效地提高单片机系统中I/O口的利用率。缺点:必须扫描检测按键情况,程序复杂,占用时间较多。
常见的识别按键的方法如扫描法:按键按下时,与此键相连的行线与列线导通,行线在无按键按下时处在高电平。如果所有的列线都处在高电平,则按键按下与否不会引起行线电平的变化,因此必须使所有列线处在低电平。这样,当有按键按下时,改键所在的行电平才回由高变低,才能判断相应的行有键按下。
方案三:采用Proteus自带的KEYPAD-SMALLCALC矩阵键盘,具有方案二矩阵按键的所有优点和功能,同时简单易操作,不需要多个按钮和电路线,节省资源。
综合考虑最终采用方案三,KEYPAD-SMALLCALC矩阵键盘控制运算。因为计算器运算需要0~9、+、-、*、/、、=、CL共16个按键,同等条件下使用Proteus自带的KEYPAD-SMALLCALC矩阵按键占用IO口资源较少,并且简单,连线较少。
利用STC89C51单片机、LCD1602电子显示屏、矩阵键盘实现了4位数以内的加减乘除运算、清零功能。
1、能实现当前运算过程和运算结果的实时显示;
2、能实现清零功能;
3、能实现错误提示和复位功能。
本设计以单片机 AT89C51为控制核心, 采用模块化设计, 共分以下几个功能模块:单片机控制系统模块、 电源模块、 时钟模块、 复位模块、 矩阵键盘控制模块和显示模块等。 计算器主要有4位整数以内的加减乘除运算功能和清零功能。
图2.1 系统结构设计框图
各模块功能如下:
单片机最小系统又称为最小应用系统,即用最少的元器件组成单片机可以工作的系统。一般应包括:电源、单片机、晶振电路、复位电路等。
以 AT89C51 单片机为核心,选用12MHZ的晶振,由于晶振的频率越高,单片机的运行速度就越快,但考虑到单片机的运行速度快会导致对存储器的要求就会变高,因此 12MHZ 晶振为最佳选择。外接电容的值虽然没有严格的要求,但是外接电 容的大小会影响振荡器的频率高低、振荡器的稳定性和起振的快速性,因此我们选用30pF的电容作为起振电容。复位电路为按键高电平复位,当按键按下,RES端为高电平,当高电平持续4us的时间就可以使单片机复位。如图3.1所示为单片机最小系统图。
图3.1单片机最小系统图
AT89C51单片机是一种高效微控制器, 也是低功耗高性能单片机。 单片机是本设计的核心主要起控制作用, 采用 40 引脚双列直插封装形式, 32 个外部双向输入/输 出(I/O)埠, 同时内含 2 个外中断口, 2 个 16 位可程序设计定时计数器, 2 个全双工串行通信口,因为受引脚数目 的限制, 所以有不少引脚具有第二功能。外形及引脚排列如图 3-2 所示。
AT89C51单片机的主要管脚功能:
VCC: 供电电压。 GND: 接地。
P0 口: P0 口为一个 8 位漏级开路双向 I/O 口, 每脚可吸收 8TTL 门电流。 当 P1 口的管脚第一次写 1 时, 被定义为高阻输入。 P0 能够用于外部程序数据存储器, 它可以被定义为数据/地址的第八位。
P1 口: P1 口是一个内部提供上拉电阻的 8 位双向 I/O 口, P1 口缓冲器能接收输出4TTL 门电流。 P1 口管脚写入 1 后, 被内部上拉为高, 可用作输入, P1 口被外部下拉为低电平时, 将输出电流, 这是由于内部上拉的缘故。
P2 口: P2 口为一个内部上拉电阻的 8 位双向 I/O 口, P2 口缓冲器可接收, 输出 4个 TTL 门电流, 当 P2 口被写 1 时, 其管脚被内部上拉电阻拉高, 且作为输入。 并因此作为输入时, P2 口的管脚被外部拉低, 将输出电流。
P3 口: P3 口是 8 个带内部上拉电阻的双向 I/O 口, 可接收输出 4 个 TTL 门电流。当 P3 口写入 1 后, 它们被内部上拉为高电平, 并用作输入。 作为输入, 由于外部下拉为低电平, P3 口将输出电流(ILL) 这是由于上拉的缘故。 RST: 复位输入。 当振荡器复位器件时, 要保持 RST 脚两个机器周期的高电平时间。
ALE/PROG: 当访问外部内存时, 地址锁存允许的输出电平用于锁存地址的地位字节。 在 FLASH 程序设计期间, 此引脚用于输入程序设计脉冲。 在平时, ALE 端以不变的频率周期输出正脉冲信号, 此频率为振荡器频率的 1/6。 因此它可用作对外部输出的脉冲或用于定时目的。
PSEN : 外部程序内存的选通信号。 在由外部程序内存取指期间, 每个机器周期两次 PSEN 有效。 但在访问外部数据存储器时, 这两次有效的 PSEN 信号将不出现。
EA/VPP: 当 EA保持低电平时, 则在此期间外部程序内存(0000H-FFFFH), 不 管是否有内部程序内存。 注意加密方式 1 时, EA将内部锁定为 RESET; 当 EA端保持高电平时, 此间内部程序内存。在 FLASH 程序设计期间, 此引脚也用于施加 12V 程序设计电源 (VPP)。
电源电路模块为系统电路和其他模块提供+5V 电源。 供电电源可由开关电源提供。
时钟电路模块的设计:
由于 AT89C51单片机芯片内有时钟振荡电路, 因此本系统单片机采用内部时钟方式,只要在单片机的 XTAL1和 XTAL2引脚外接石英晶体和微调电容, 就构成了自激振荡器并在单片机内部产生时钟脉冲信号,具体电路设计如下图所示。
工作原理:时钟信号通常用两种电路形式得到:内部振荡和外部振荡。 在 XTAL1 和 XTAL2 引脚上外接定时组件,就能构成自激振荡电路。定时组件通常采用石英晶体和电容组成的并联谐振电路。一般电容 C4 和 C5 主要起频率微调作用,电容值可选取为 30pF 左右或 40pF左右;晶体振荡器,简称晶振,其晶振频率(fosc) 范围为 1. 2MHz~12MHz, 本设计中选择12MHz。晶体振荡频率越高,系统的时钟频率也越高,单片机的运行速率就越快。
复位电路使单片机或系统中的其他部件处于某种确定的状态。 当在 MCS-51 系列单片的 RST 引脚处引入高电平并保持 2 个机器周期, 单片机内部就执行复位操作。 复位操作有两种基本形式:一种是上电复位, 另一位是按键复位。 本设计采用按键复位方式。 如图 3-4 所示。
工作原理:当按下按键时, RST 直接与 VCC 相连,出现 2 个以上的高电平形成复位,同时电解电容被短路放电;按键松开时,电容充电,电流流过电阻,RST 为高电平,仍然是复位,充电完成后,电容相当于开路,RST 为低电平,正常工作。
在单片机应用系统中, 对于系统的运行状态和运行结果, 通常都需要直观显示出来。本设计采用LCD1602液晶显示屏显示, 显示电路如图3-2所示:
LCD1602,工业字符型液晶,能够同时显示16x02即32个字符(16列2行),故简称1602。1602LCD 液晶具有功耗低、显示内容丰富、清晰,显示信息量大,显示速度较快,界面友好等特点,可以方便的显示多种字符。通过D0-D7引脚向LCD写指令字或写数据以使LCD实现不同的功能或显示相应的数据。P0口作为液晶显示的数据端口,与D0-D7连接。P2.1-P2.3口作为其控制端口,控制LCD液晶显示屏显示输出数据,与RS,RW,E,连接 。
图3-2 显示电路(LCD1602液晶显示屏)
LCD采用标准的14脚(无背光)或16脚(带背光)接口,各引脚接口说明如表3-3所示。
表3-3引脚接口说明表
编号 | 符号 | 引脚说明 | 编号 | 符号 | 引脚说明 |
1 | GND | 电源地 | 9 | D2 | 数据 |
2 | VCC | 电源正极 | 10 | D3 | 数据 |
3 | V0 | 液晶显示偏压 | 11 | D4 | 数据 |
4 | RS | 数据/命令选择 | 12 | D5 | 数据 |
5 | R/W | 读/写选择 | 13 | D6 | 数据 |
6 | E | 使能信号 | 14 | D7 | 数据 |
7 | D0 | 数据 | 15 | BLA | 背光源正极 |
8 | D1 | 数据 | 16 | BLK | 背光源负极 |
第1脚:GND为地电源。
第2脚:VCC接5V正电源。
第3脚:V0为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度。
第4脚:RS为寄存器选择,高电平时选择数据寄存器,低电平时选择指令寄存器。
第5脚:R/W为读写信号线,高电平时进行读操作,低电平时进行写操作。当RS和R/W共同为低电平时可以写入指令或者显示地址,当RS为低电平R/W为高电平时可以读忙信号,当RS为高电平R/W为低电平时可以写入数据。
第6脚:E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。
第7~14脚:D0~D7为8位双向数据线。
第15脚:背光源正极。
第16脚:背光源负极。
矩阵按键线反法的原理为:首先使P1口的高四位输出高电平,P1口低四位输出低电平,这时键盘的行线被拉高,列线被拉低。如果有按键按下,则某一条行线将被拉低,此时读取P1口高四位,读取到的将不再全为高电平,说明有按键按下。根据读取到0值的I/O口所连接的行线,就可以判断出按下的按键位于哪一行。接下来使P1口的高四位输出低电平,P1口低四位输出高电平(即与上次输出的电平相反,因此称为线反法)。如果有按键按下,此时读取P1口低四位,读取到的将不再全为高电平,根据读取到0值的I/O口所连接的列线,就可以判断出按下的按键位于哪一列。综合按键所在的行线与列线,即可唯一确定按键所在位置,进而获取按键的键值。
protues中的KEYPAD-SMALLCALC直接就是4*4的矩阵键盘,如上图所示。
使用反转法键盘扫描,输入行值(或列值),读列值(或行值);输入列值(或行值),读行值(或列值),将两次读入数据组合,通过读入数据组合判断按键位置。
本次的设计主程序是根据每个模块的功能来进行编写,先对各个模块进行初始化,然后再按照各自不同来分模块编写。
当仿真程序中的单片机上电,进入程序后,先将单片机,LCD1602,按键等进行初始化,LCD显示初始固定数值“ 0 ”,程序开始等待按键按下,当有按键按下,单片机检测一次,确定按下,单片机调用程序,同时刷新一次,显示当前操作结果。完后,程序返回按键等待,如此循环执行。
其具体流程图如图所示。
主程序代码:略。
LCD1602在上电以后,应该先等待50ms左右,让其内部芯片初始化后再对其进行操作。在对其操作时,应参考其时序图,先把命令写入其内部寄存器设置它的工作方式和状态。要显示数据的时候,先设置好显示坐标,再往里面写入要显示的ASCII码,LCD则通过刷新和替换来显示新的数据。
流程图如下:
程序如下:
- // 描述: 1602液晶写指令
- void write_com(uchar com) //1602液晶写指令
- {
- rs=0; //写指令
- lcden=0; //使能1602
- P0=com; //写入指令com
- LCD_Delay_ms(1); //延时1ms
- lcden=1; //使能1602
- LCD_Delay_ms(2); //延时2ms
- lcden=0; //使能1602
- }
-
- // 描述:1602液晶写数据
- void write_date(uchar date) //1602液晶写数据
- {
- rs=1; //写数据
- lcden=0; //使能1602
- P0=date; //写入数据date
- LCD_Delay_ms(1); //延时1ms
- lcden=1; //使能1602
- LCD_Delay_ms(2); //延时2ms
- lcden=0; //使能1602
- }
-
- // 描述:指定x,y写入字符函数
- void W_lcd(unsigned char x,unsigned char y,unsigned char Data)
- {
- if (y == 0){write_com(0x80 + x);} //第一行
- else{write_com(0xc0 + x);} //第二行
- write_date( Data); //写入数据
- }
-
- //指定x,y写入字符串函数
- void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
- {
- if (y == 0){write_com(0x80 + x);} //第一行
- else{write_com(0xC0 + x);} //第二行
- while (*s) //
- {write_date( *s); s++;} //写入数据
- }
-
- // 描述:初始化液晶,及画面初始化
- void init_lcd(void) //初始化液晶,及画面初始化
- {
- lcden=0; //使能1602
- write_com(0x38); //8 位总线,双行显示,5X7 的点阵字符
- LCD_Delay_us(100); //延时100us
- write_com(0x0c); //开显示,无光标,光标不闪烁
- write_com(0x06); //光标右移动
- write_com(0x01); //清屏
- write_com(0x80); //DDRAM 地址归0
- }

程序如下:
略。
使用反转法键盘扫描,输入行值(或列值),读列值(或行值);输入列值(或行值),读行值(或列值),将两次读入数据组合,通过读入数据组合判断按键位置。流程图如下:
程序如下:
- short keycheckdown() /* 反转法键盘扫描 */
-
- {
- short temp1,temp2,temp,a=0xff;
- P1=0xf0; /* 输入行值(或列值) */
- LCD_Delay_ms(20); /* 延时 */
- temp1=P1; /* 读列值(或行值) */
- P1=0xff;
- LCD_Delay_ms(20); /* 延时 */
- P1=0x0f; /* 输入列值(或行值) */
- LCD_Delay_ms(20); /* 延时 */
- temp2=P1; /* 读行值(或列值) */
- P1=0xff;
- temp=(temp1&0xf0)|(temp2&0xf); /* 将两次读入数据组合 */
- switch(temp) /* 通过读入数据组合判断按键位置 */
- {
- case 0xe7 :a=0x0d;break;// 按键/
- case 0x7b :a=0x0e; break;// 按键=
- case 0x7d :a=0;break;// 按键0
- case 0x7e :a=0x0f; break;// 按键CE
- case 0xd7 :a=0x0c;break;// 按键*
- case 0xeb :a=0x9;break; // 按键9
- case 0xed :a=0x8;break; // 按键8
- case 0xee :a=0x7;break; // 按键7
- case 0xb7 :a=0x0b;break;// 按键-
- case 0xdb :a=0x6;break; // 按键6
- case 0xdd :a=0x5;break; // 按键5
- case 0xde :a=0x4;break; // 按键4
- case 0x77 :a=0x0a;break;// 按键+
- case 0xbb :a=3;break; // 按键3
- case 0xbd :a=2;break; // 按键2
- case 0xbe :a=1;break; // 按键1
- default :a=0xff;
- }
- return a; /* 返回按键值 */
- }

LCD1602的延时程序设计,程序如下:
- // 描述: 延时t _us函数
- void LCD_Delay_us(unsigned int t)
- {
- while(t--); //t=0,退出
- }
-
- // 描述: 延时t _ms函数
- void LCD_Delay_ms(unsigned int t)
- {
- unsigned int i,j;
- for(i=0;i<t;i++) //执行t次循环
- for(j=0;j<113;j++) //执行113次循环;
- }
本设计用Proteus 8.9软件作图,C语言对单片机进行控制操作,易读好懂,用Keil μVision5软件进行了调试。
软件调试一般分为以下四个阶段:
1、编写程序并查错;
2、在 C 语言的编译系统中编译源程序
3、对程序进行编译连接,并及时发现程序中存在的错误;
4、改正错误。
在本次调试中出现的问题有:
1、在程序中有的函数名未定义;
2、在抄录程序时,少录入一些字符,如:”“{”“-”“;、 、等符号,而出现错误;
3、有一些函数名录入时少写一个字母或顺序颠倒;
4、没有注意函数名的调用及定义;
5、芯片引脚定义出错而导致没有实验现象.
修改完毕后得到以下调试成功界面:
使用Proteus绘制原理图,并将Keil编译生成得*.hex程序文件录入到AT89C51模拟单片机中,点击运行后开始显示设定好的初始值:“0”,初始值可在系统初始化程序中自由更改。然后输入数字和运算符号进行运算,在LCD1602液晶显示屏上显示运算过程和运算结果。
Proteus仿真初始化显示如图5.1所示。
图5.1 计算器初值显示
(1)加法运算:实现两个数相加,如图所示。
(2)减法运算:实现两个数相减,如图所示。
(3)乘法运算:实现两个数相乘,如图所示。
(4)除法运算:实现两个数相除,如图所示。
(5)报错提示:第一个数对0直接做除运算,如图所示。
本次设计主要是以单片机最小系统、KEYPAD-SMALLCALC矩阵键盘和LCD1602液晶模块组成,设计了一个简易计算器,利用单片机控制,系统成本低廉,功能精准实用。通过最后的硬件和软件的模拟调试,本课题的研究工作已经达到预期的要求,归纳起来有以下几点:
(1)本课题实现了简易计算器的基本运算功能。
(2)系统硬件设计使用的有芯片AT89C51,电容,晶振,电阻,lcd1602液晶显示屏,KEYPAD-SMALLCALC矩阵键盘等。
(3)系统软件设计包括LCD初始化程序、LCD1602运算显示程序,矩阵键盘程序,延时函数程序等,完成了简易计算器的4位数以内的加减乘除等基本功能。
本次设计可以说是软硬结合,又以硬件为主,软件为辅。 当今科技发展迅速,单片机嵌入式开发有着光明的前景。通过 Proteus 仿真实现了所要求的全部功能,且可以满足对系统安全及稳定性的需求。并且另设复位电路来保证当LCD出现显示错误时能够重新开始输入数据进行运算,使本设计功能趋于完善,满足现阶段的发展需要。
由于单片机具有经济实用、开发简便等特点, 所以依然在工业控制、 家电等领域占据广泛的市场。 通过对本系统的设计,我学习到了硬件开发和软件开发的基本流程并有了一定的驾御此开发过程的能力。 通过实际的程序设计和不断的调试过程,我更加熟练地掌握了单片机相关程序的程序设计方法,在不断的设计过程中,我对单片机系统有了更深刻的认识,进一步熟悉和掌握了单片机的结构以及它的工作原理,对定时、中断程序等有了更深地认识,学到了如何熟练使用仿真软件Proteus8.9和程序设计软件Keil uVision5。
私信获取完整版源代码。
[1]高汉昆,张斌.单片机在自动化控制系统中的应用分析[J].数字通信世界,2023,(11):145-147.
[2]贺佩.单片机技术在电子产品设计中的应用[J].电子技术,2023,52(11):210-211.
[3]闫景富.基于Proteus的单片机仿真实验教学设计[J].集成电路应用,2023,40(11):406-407.
[4]董占国,卢晓雄,武鸿熙等.单片机汇编启动文件分析及作用[J].自动化应用,2023,64(08):92-96.
[5]张晓培,蒋庆华,庄远等.“C语言与单片机技术及应用”课程内容整合与资源重构[J].科技视界,2022,(25):153-155.
[6]陈忠平,刘琼.51单片机C语言程序设计经典实例[M].电子工业出版社:202106.424.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。