单片机课程设计报告书 设计题目:基于51单片机的简易计算器 学生姓名: 学生学号: 所在班级: 自动化 指导教师: 目录 引言 3 第一章 设计目的及方案 1.设计目的 3 2.设计方案 3 第二章 硬件基础 1.AT89S52简介 4 2.L1602简介 4 3.4*4键盘矩阵简介 5 第三章 程序设计 6 第四章 系统总述 1.系统流程图 11 2.系统电路图 12 3.实物连接图 12 第五章 总结体会 13 引言 众所周知单片机是一种集成在电路芯片,是采用超大 规模集成电路技术把具有数据处理能力的中央处理器CPU随机存储器RAM、只读存储器ROM、多种I/O口和中断系统、定时器/计时器等功能(可能还包括显示驱动电路、脉宽调制电路、模拟多路转换器、A/D转换器等电路)集成到一块硅片上构成的一个小而完善的计算机系统。 目前,一个学习与应用单片机的高潮正在工厂、学校及企事业单位大规模地兴起。过去习惯于传统电子领域的工程师、技术员正面临着全新的挑战,如不能在较短时间内学会单片机,势必会被时代所遗弃,只有勇敢地面对现实,挑战自我,加强学习,争取在较短的时间内将单片机技术融会贯通,才能跟上时代的步伐。 它所给人带来的方便也是不可否定的,它在一块芯片内集成了计算机的各种功能部件,构成一种单片式的微型计算机。20世纪80年代以来,国际上单片机的发展迅速,其产品之多令人目不暇接,单片机应用不断深入,新技术层出不穷。20世纪末,电子技术获得了飞速的发展,在其推动下,现代电子产品几乎渗透了社会的各个领域,有力地推动了社会生产力的发展和社会信息化程度的提高,同时也使现代电子产品性能进一步提高,产品更新换代的节奏也越来越快。 设计目的: 本设计要制作的是单片机于生活中最为常见的一种应用—简易计算器。这要求我们以单片机为核心,在熟悉、掌握各种外围接口电路芯片的工作原理和控制方法的前提下根据所学的知识以及编写程序来选取合适的器件设计简易计算器使之实现加减乘除以及清零的功能。 设计方案: 根据计算器的功能要求,选择AT89C51为主控机,通过扩展必要的外围接口电路,实现对计算器的设计。外部主要由4*4矩阵键盘和一个液晶显示屏构成,内部由一块AT89S52单片机构成。计算器电路包括四个部分:选用LCD作为显示部分,矩阵键盘作为输入部分,运算模块,单片机控制部分。模块图如图所示:
本简易计算器AT89S52单片机作为核心。简易计算器显示电路由LCD1602组成, 制作一个单片机计时装置需要的材料需要有软硬件的支持,硬件方面AT89S52单片机,晶振,液晶屏LCD1602,键盘等部分构成。软件部分在keil环境下用C语言编写。本系统可进行简易的计算。电路采用AT89S52单片机作为核心,功耗小,能在3V的低压工作,电压可选用3~5V电压供电。 第二章 硬件基础 1.AT89S52简介: 主要性能: 与MCS-51单片机产品兼容 8K字节在系统可编程Flash存储器 1000次擦写周期 全静态操作:0Hz~33MHz 三级加密程序存储器 32个可编程I/O口线 三个16位定时器/计数器 八个中断源 全双工UART串行通道 低功耗空闲和掉电模式 掉电后中断可唤醒 看门狗定时器 双数据指针 掉电标识符 功能特性描述: AT89S52是一种低功耗、高性能CMOS8位微控制器,具有8K 在系统可编程Flash 存储器。使用Atmel 公司高密度非易失性存储器技术制造,与工业80C51 产品指令和引脚完全兼容。片上Flash允许程序存储器在系统可编程,亦适于常规编程器。在单芯片上,拥有灵巧的8 位CPU 和在系统可编程Flash,使得AT89S52为众多嵌入式控制应用系统提供高灵活、超有效的解决方案。 AT89S52具有以下标准功能: 8k字节Flash,256字节RAM,32 位I/O 口线,看门狗定时器,2 个数据指针,三个16 位定时器/计数器,一个6向量2级中断结构,全双工串行口,片内晶振及时钟电路。另外,AT89S52 可降至0Hz 静态逻辑操作,支持2种软件可选择节电模式。空闲模式下,CPU停止工作,允许RAM、定时器/计数器、串口、中断继续工作。掉电保护方式下,RAM内容被保存,振荡器被冻结,单片机一切工作停止,直到下一个中断或硬件复位为止。 2.1602液晶显示器简介: 液晶(Liquid Crystal)是一种高分子材料,因其特殊的物理、化学、光学特性,广泛应用轻薄显示器上。 液晶显示器(Liquid Crystal Display,LCD)的主要原理是以电流刺激液晶分子产生点、线、面并配合背部灯管构成画面。 各种型号的液晶通常是按照显示字符的行数或液晶点阵的行、列数来命名。例如,1602表示每行显示16个字符,一共可以显示两行。这类液晶通常称为字符型液晶,只能显示ASCII码字符。12232表示液晶显示画面由122列、32行组成,共有122*32个点来显示各种图形。用户可以通过程序控制这些点中任何一个点显示或不显示,从而构成各种图形画面。因此,12232称为图形型液晶。 液晶体积小,功耗低,显示操作简单。但其有致命的弱点,即使用温度范围很窄。通用型液晶工作温度为0到+55摄氏度,存储温度为-20到+60摄氏度。 主要参数: 显示容量:16*2个字符 芯片工作电压:4.5~5.5V 工作电流:2.0mA 模块最佳工作电压:5.0V 字符尺寸:2.95*4.35(WXH)mm RAM地址映射图:
向图中的 00~0F、40~4F 地址中的任意处写入显示数据时,液晶可立即显示出来; 当写入到 10~27 或 50~67 地址时,必须通过移屏指令将他们一移入可显示区域方可正常 显示。 实验箱4*4键盘实物图: 4*4键盘电路图:
编码后按键功能:
3.实物连接图: 单片机是我所学专业的主要课程之一,不仅培养了我综合运用所学知识,发现,提出,分析和解决实际问题的能力,而且提高了我实际动手操作能力.现实生活中,单片机在应用可以说得是无处不在。因此在大学中说掌握单片机的开发技术是十分重要的,也是十分必要的。 我在刚刚拿到课程设计题目时有点迷惘,毕竟在前几周的理论学习中没有扎实的掌握单片机的理论知识,面对芯片和五颜六色的导线,不知道如何下手,好在通过上网和图书馆查阅相关资料,自己认真钻研以及虚心询问同学,终于解决了一个又一个的困难和障碍,成功完成了任务。 通过本次的单片机课程设计,不仅丰富了我的理论知识,而且在实践过程中更令我学会了坚持、耐心和努力。此次单片机课程设计需要运用到许多之前所学过的知识,令我认识到自己以前学习的一些不足之处,例如对以前所学知识的理解不够深刻,掌握得不够牢固,运用不够灵活。这让我懂得了认真学习的重要性,以及要孜孜不倦地钻研所学过的知识,做得融会贯通,不能一览而过,不求甚解。在边学习边动手的过程中,我对AT89S52单片机的构造以及原理有了进一步的了解,同时也加深和巩固了我对单片机汇编语言的认识。除此之外,由于是第一次做单片机,因此在此次课程设计的过程中,无论是电路绘制还是汇编语言编写都难免遇到了不少困难和障碍,例如汇编语言编写出错、电路元件无从入手等。在面对困难和障碍时,我庆幸自己没有选择退缩和逃避,而是通过各种方法,迎难而上,以坚持、耐心和努力勇敢无畏地面对困难,克服困难,解决困难。让我发现问题、分析问题、解决问题以及动手实践的能力都有了很大的提高,并了解到理论知识与实践相结合的重要意义。 从这次的课程设计中,我才真正明白理论结合实际的道理,在以后的学习中,更要把理论联系实际,把我们所学的理论知识用到实际当中,学习单机片机即是如此,出色的程序最终用实际操作来实现才是完美。十分庆幸拥有这次课程设计,让我受益匪浅。
单片机源程序如下:
- #include<reg52.h>
- #include<stdio.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define CHECK_BUSY
- sbit RS = P2^4;
- sbit RW = P2^5;
- sbit EN = P2^6;
- void Delay10ms(unsigned int c)
- {
- unsigned char a,b;
- for (;c>0;c--)
- {
- for(b=38;b>0;b--)
- {for(a=130;a>0;a--);
- }
- }
- }
- //判忙函数
- bit LCD_Check_Busy()
- {
- #ifdef CHECK_BUSY
- P0= 0xFF;
- RS=0;
- RW=1;
- EN=0;
- _nop_();
- EN=1;
- return (bit)(P0 & 0x80);
- #else
- return 0;
- #endif
- }
- //命令函数
-
- void write_com(uchar com)
- {
- while(LCD_Check_Busy());
- RS=0;
- RW=0;
- EN=1;
- P0= com;
- _nop_();
- EN=0;
- }
- //数据函数
-
- void write_dat(uchar dat)
- {
- while(LCD_Check_Busy());
- RS=1;
- RW=0;
- EN=1;
- P0= dat;
- _nop_();
- EN=0;
- }
- //字符函数
-
- void LCD_Write_Char(uchar x,uchar y,uchar dat)
- {
- if (y == 0)
- {
- write_com(0x80 + x);
- }
- else
- {
- write_com(0xC0 + x);
- }
- write_dat( dat);
- }
- //字符串函数
- void Write_String(uchar x,uchar y,uchar *s)
- {
-
- while (*s)
- {
- LCD_Write_Char(x,y,*s);
- s++;
- x++;
- }
- }
- //初始化函数
-
- void LCD_Init()
- {
- write_com(0x38);
- Delay10ms(20);
- write_com(0x06);
- Delay10ms(20);
- write_com(0x0C);
- write_com(0x01);
- }
- //按键扫描函数
-
- uchar KeyScan()
- {
- unsigned char cord_h,cord_l;
- P3=0x0f;
- cord_h=P3&0x0f;
- if(cord_h!=0x0f)
- {
- Delay10ms(40);
- if((P3& 0x0f)!=0x0f)
- {
- cord_h=P3&0x0f;
- P3=cord_h|0xf0;
- cord_l=P3&0xf0;
- while((P3&0xf0)!=0xf0);//等待松开并输出
- return(cord_h+cord_l);//键盘最后组合码值
- }
- }
- return(0xff);
- }
- unsigned char KeyPro()
- {
- switch(KeyScan())
- {
- case 0x7e:return '1';break;//按下相应的键所显示相应的值
- case 0x7d:return '2';break;
- case 0x7b:return '3';break;
- case 0x77:return '+';break;
- case 0xbe:return '4';break;
- case 0xbd:return '5';break;
- case 0xbb:return '6';break;
- case 0xb7:return '-';break;
- case 0xde:return '7';break;
- case 0xdd:return '8';break;
- case 0xdb:return '9';break;
- case 0xd7:return 'x';break;
- case 0xee:return '0';break;
- case 0xed:return '.';break;
- case 0xeb:return '=';break;
- case 0xe7:return '/';break;
- default:return 0xff;break;
- }
- }
- main()
- {
- unsigned char num,i,sign;
- unsigned char temp[16];
- bit firstflag;
- float a=0,b=0;
- unsigned char s;
- LCD_Init(); //初始化液晶屏
- Delay10ms(40);//延时
- write_com(0x01);
- Write_String(0,0,"I LIKE MCU");
- Write_String(0,1,"HBKJXY");
- for(s=0;s<25;s++)
- Delay10ms(300);
- write_com(0x01);
- while (1) //主循环
- {
- num=KeyPro(); //扫描键盘
- if(num!=0xff) //如果扫描是按键有效值则进行处理
- {
- if(i==0)
- write_com(0x01);
- if(('+'==num)|| (i==16) || ('-'==num) || ('x'==num)|| ('/'==num) || ('='==num))//输入数字最大值16,输入符号表示输入结束
- {
- i=0;
- if(firstflag==0)
- {
- sscanf(temp,"%f",&a);
- firstflag=1;
- }
- else
- sscanf(temp,"%f",&b);
- for(s=0;s<16;s++)
- temp[s]=0;
- LCD_Write_Char(0,1,num);
-
- if(num!='=') //判断当前符号位并做相应处理
- sign=num;
- else
- {
- firstflag=0; //检测到输入=号,判断上次读入的符号
- switch(sign)
- {
- case '+':a=a+b;
- break;
- case '-':a=a-b;
- break;
- case 'x':a=a*b;
- break;
- case '/':a=a/b;
- break;
- default:break;
- }
- sprintf(temp,"%g",a);
- Write_String(1,1,temp);//显示到液晶屏
- sign=0;a=b=0; //数据清零
- for(s=0;s<16;s++)
- temp[s]=0;
- }
- }
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
基于51单片机的简易计算器 .docx
(422.11 KB, 下载次数: 32)
|