单片机原理课程设计OLED电子计算器.docx

上传人:叶*** 文档编号:35575872 上传时间:2022-08-22 格式:DOCX 页数:21 大小:31.54KB
返回 下载 相关 举报
单片机原理课程设计OLED电子计算器.docx_第1页
第1页 / 共21页
单片机原理课程设计OLED电子计算器.docx_第2页
第2页 / 共21页
点击查看更多>>
资源描述

《单片机原理课程设计OLED电子计算器.docx》由会员分享,可在线阅读,更多相关《单片机原理课程设计OLED电子计算器.docx(21页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、课程设计(论文)任务书 电气与电子工程学院 系 自动化 专业 13 班级 1班 一、 课程设计(论文)题目 计算器设计 二、 课程设计(论文)工作自 2016 年 1 月 5 日起至 2016 年 1 月 15 日止。三、 课程设计(论文)的内容要求: 实现五位数(可为带小数数)的加减乘除运算,通过按键输入十进制数据。利用八位数码管显示运算结果。 学生签名: 2016 年 1 月 日课程设计(论文)评审意见(1)题目复杂程度: 复杂( )、较复杂( )、一般( )、简单( )(2)总体方案的选择是否正确:正确()、较正确()、欠正确()、不正确() (3) 系统能否满足任务要求:满足()、较满

2、足()、欠满足()、不满足() (4) 元器件选择是否合理:合理()、较合理()、欠合理()、不太合理() (5) 学习实践态度:好()、较好()、一般()、不太好() (6) 独立工作能力:强()、较强()、一般()、较差() (7) 回答问题是否正确:正确()、较正确()、基本正确()、大多不正确() (8) 图表是否符合标准:符合()、较符合()、基本符合()、大多不符合() (9) 撰写是否规范整洁:规范整洁()、较规范()、欠规范()、不太规范() 总评成绩:优( )、良( )、中( )、与格( )、不与格( )评阅人 职称副教授 2016 年 1 月 日目录第一章课程设计题目分析1

3、1.1 课程设计题目要求11.2 课程设计题目要求分析1第二章设计思想和设计说明22.1 设计思想22.2 设计说明2第三章硬件选型33.1 单片机选型33.2 LCD选型33.3 其他器件选型33.4 使用软件说明4第四章硬件原理44.1 硬件整体框图44.2 矩阵键盘电路54.3 复位电路54.4 晶振电路64.5 LCD电路6第五章程序设计原理75.1 程序设计流程75.2 按键扫描程序85.3 输入数据存储与转换算法85.4 LCD驱动8第六章系统功能描述9第七章设计总结和心得体会10附录1 STC89C52RC资料12附录2 器件选型13附录3 硬件原理图14附录4 程序清单15参考

4、文献21第一章 课程设计题目分析1.1 课程设计题目要求本次课程设计要求设计一个能实现五位数(可为带小数数)的加减乘除运算的计算器,通过按键输入十进制数据。利用八位数据码管显示运算结果。在经过指导老师的批准后,将题目要求改为用LCD显示运算的结果。1.2 课程设计题目要求分析分析题目要求可知,本次设计要用到的知识有键盘的设计、单片机I/O口的操作、数制的转换与数值的运算、LCD的驱动显示。键盘设计部分的主要任务是设计一个用来输入数值、运算符以与结果显示操作的键盘。单片机的I/O口一是用来接收外部输入的数据,主要是键盘输入的数据,并对这些数据进行判断和处理,第二是用来输出处理过后的数据,主要是将

5、数据输出到LCD上以驱动LCD显示相应的内容。数制转换与数值运算部分的主要任务有:将键盘输入的十进制数据进行十六进制以与二进制的转换,这些操作由单片机内部自动完成;输入数值的整型以与浮点型的处理,这部分需要通过编程实现;运算结果的整型以与浮点型的控制,这部分需要通过编程实现,LCD驱动数据的整型和浮点型向字符型的转换,这部分需要通过编程实现。LCD驱动显示部分主要用来显示输入的两个操作数、一个操作运算符与一个运算结果。通过以上分析可知,本次课程设计的难点在于数制转换与数值运算部分以与LCD驱动显示部分。在进行课程设计之前需要准备的知识有:Keil软件的使用,Altium Designer软件的

6、使用,数值转换与数值运算相关算法的了解,LCD接口以与驱动的了解。第二章 设计思想和设计说明2.1 设计思想从以上的分析可知,本次课程设计可分为两大部分,第一部分是键盘数据的输入与处理,第二部分是LCD部分的输出驱动与显示。按照上述分类,本次设计的硬件部分采用先分开调试后联合调试的方法,即先分开调试键盘部分和LCD部分的硬件电路,待各部分的电路都调试通过后,再将两部分电路联合调试,采用这种调试方法,不仅能提高设计的效率,降低出错率,还能在出现问题时快速找到问题的所在。考虑到LCD底层驱动程序较为复杂,以与本人对汇编语言的掌握不是太好,本次课程设计的程序语言采用C语言进行编写,并采用模块化编程的

7、思想,将LCD的驱动以与键盘部分的驱动分为两个模块进行编写,同样采用先独立调试再联合调试的方法。2.2 设计说明本次设计的详细软硬件资料见附录。设计报告中使用的简写如下:l LCD:Liquid Crystal Display(液晶显示器);l ROM:Read only memory(只读存储器);l RAM:Random access memory(随机存取存储器);l SRAM:Static random access memory(静态随机存取存储器);l PCB:Printed circuit board(印制电路板)。第三章 硬件选型3.1 单片机选型在设计初期采用AT89C51单

8、片机进行调试,发现在LCD的驱动调试好以后占用的ROM已经接近4K,考虑到键盘部分的程序还未编写,所以最终的程序大小可能会超过4K,因此就需要扩展片外的ROM,为了节约设计的制作成本和简化设计的硬件电路,于是采用STC89C52RC单片机进行调试,STC89C52RC单片机拥有8K的Flash RAM以与512B的SRAM和5K的EEPROM,RAM大大小以与ROM的大小完全足够本次设计使用,而且价格适中。STC89C52RC的具体特性见附录1。3.2 LCD选型根据以往做项目的经验,LCD的驱动芯片选用SSD1306 12864液晶显示屏驱动芯片,芯片接口支持SPI协议和IIC协议,通过单片

9、机I/O口的模拟配置就可以驱动显示。LCD模块选择中景园电子的0.96寸LCD模块,其内部集成SSD1306驱动芯片,支持3.35V电源输入,符合本次设计的要求。3.3 其他器件选型考虑到PCB制作成本的问题,本次设计的电路板使用万能板进行焊制。由于LCD的驱动代码较多,为了加快系统的运行速度,晶振采用11.0592MHz的频率,同时也为了方便串口调试时的使用。其他器件的选型见附录2。3.4 使用软件说明本次课程设计的软硬件设计在windows 7系统下进行。程序编写使用Keil uVision4软件;硬件电路图的绘制使用Altium Designer软件;原理框图的绘制使用Microsoft

10、 Viso软件;使用stc-isp-15xx-v6.85I软件进行程序的仿真调试与下载。第四章 硬件原理4.1 硬件整体框图硬件整体框图如图1所示。图1 硬件整体框图本设计硬件整体分为六个小部分,分别为:矩阵键盘电路、复位电路、晶振电路、LCD电路、电源电路和STC89C52RC电路,下面对前四部分进行详细说明。4.2 矩阵键盘电路矩阵键盘电路如图2所示,采用44矩阵键盘,共四行四列十六个按键,占用八个I/O口。图2 矩阵键盘电路矩阵键盘的四个行分别与单片机的P1.0P1.3相连接,四个列分别与单片机的P3.4P3.7相连接,采用行列扫描的方法来检测按下的按键,具体的做法是:检测时先让一列为低

11、电平(此时确定了列),其余几列为高电平,然后立即轮流检测各个行是否有低电平出现,如果检测到了某一行有低电平(此时确定了行),就可以确定是那个按键被按下了。图中的S1S10分别对用十进制数09,S11代表小数点,S12代表等号,S13S16分别代表加、减、乘、除四个运算符。4.3 复位电路复位电路如图3所示。图3 复位电路在复位按键没有按下时,复位引脚通过下拉电阻和地GND相连接,为低电平,当复位按键按下时,复位引脚和VCC接通,使单片机复位。4.4 晶振电路晶振电路如图4所示。11.0592MHz的晶振两端通过两个33皮法的电容接地,组成时钟电路,通过引脚输入到单片机内部以提供时钟。图4 晶振

12、电路4.5 LCD电路LCD电路如图5所示。图5 LCD电路LCD与STC89C52RC之间通过J1相连接,由单片机的I/O口模拟SPI接口驱动LCD进行工作。接口引脚CLK、MOSI、D/C、CS1、FSO、CS2分别与单片机的P0.0P0.5通过上拉电阻相连接。第五章 程序设计原理5.1 程序设计流程 程序的设计流程图如图6所示。下面对程序的几个主要部分进行说明。图6 程序设计流程图5.2 按键扫描程序 键盘扫描函数的定义为void keyScan();在程序中依次给PO口赋值0XFE、0XFD、0XFB、0XF7来依次使键盘的四个行线为0,然后用temp=P0来读取P0口的状态以用于后面

13、的计算,然后将temp的值与0XF0相“与“判断temp的高四位是否有0,如果temp的高四位没有0,那么与0XF0相与的结果必然等于0XF0,就说明没有按键被按下,如果temp的高四位有0,那么与0XF0相与的结果必然不等于0XF0,就说明有按键被按下,然后再通过P0口的值来判断具体是那个按键被按下。5.3 输入数据存储与转换算法输入的数据用两个整型变量和两个字符串来存储其定义分别为: int BP_dat,AP_dat unsigned char BP_str=“”,AP_str=“” 。输入的数字用变量key表示 ,小数点前的整数部分的计算方式为BP_dat=BP_dat*10+key。

14、小数点后小时部分的计算方式为(float)(AP_dat)/(10(strlen(AP_str),然后使用语句BP_dat+(float)(AP_dat)/(10(strlen(AP_str)便可得到输入的操作数。由于LCD显示函数的输入只能是字符型的数据,因此使用sprintf(BP_str,%d,BP_dat)函数将整型的数据转换成字符型。其他部分程序见附录4。5.4 LCD驱动LCD的底层驱动使用SSD1306的开源驱动程序,在此底层驱动的基础上自己编写显示函数。第六章 系统功能描述本次课程设计的作品实物图如图7所示。图7 作品实物图按键的对应关系如图8所示。图8 按键功能对应关系作品可

15、实现四个浮点数的加减乘除四则运算,但在计算乘除法,特别是两个浮点数的乘除法时会会产生数据精度被削减的问题,此问题暂时没有找到解决的方法,有待日后改进。第七章 设计总结和心得体会本次课程设计历时两周,在课程设计的过程中遇到了许多的问题,同时也学到了许多知识。在最初的硬件调试时总是遇到下载器检测不到单片机的情况,为了找出问题所在,我首先检查单片机的最小系统是否正常工作,检查发现电源供电正常,复位电路连接正常,晶振电路能正常起振,最后仔细查阅数据手册才知道,STC89C52RC单片机和以前使用的其他类型的单片机不同,它采用的是高电平复位,而以前自己使用的单片机是低电平复位,在修改了复位电路后,下载器

16、便能正常检测到单片机。在调试LCD的驱动时总是遇到显示乱码和错位的问题,通过在程序中设置断点的调试方法发现是数据格式转换是出现了问题,主要是在整型数据和浮点数转为字符型时出现的问题,通过查阅C语言的相关书籍发现,使用sprintf()函数可以很好地实现数值向字符串的转换,但是8051内核运行这个函数总是显得有些吃力,为了到达较好的显示效果,只能舍弃了运行速度。在对两个数进行运算时,特别是浮点数的运算时,运算结果有时出现精度降低或者是数值溢出的问题,通过查阅开发手册得知,在Keil C51中unsigned int型数据占两个字节,数据范围为065535,signed int型数据占两个字节数据

17、范围为-32768+32767,float类型数据占四个字节,数据范围为:1.175494E-383.402823E+38,而自己输入的数据或运算的结果可能超出了上述的范围值,因此造成数据溢出并显示错误,在修改了数据的存储类型后,上述的问题得到了有效的解决,但是输入的数值和运算的结果却有了一定的范围限制。本次课程设计的作品到目前位置仍有一些缺陷,比如输入数据位数的问题和计算结果精度降低的问题,由于时间的原因,只能在以后的时间里慢慢完善。通过本次课程设计,不仅让我在课堂上学到的东西学以致用,更重要的是提高了我的动手能力和解决问题的能力,为以后的工作打下了很好的基础。附录1 STC89C52RC资

18、料STC89C52RC单片机是宏晶科技推出的新一代高速/低功耗/超强抗干扰的8051内核单片机,指令代码完全兼容传统8051单片机,12时钟/机器周期和6时钟/机器周期可以任意选择。其主要特性如下:l 增强型8051单片机,12时钟/机器周期和6时钟/机器周期可以任意选择,指令代码完全兼容传统8051。l 工作电压:5.5V3.3V。l 工作频率范围:040MHz。l 用户应用程序存储空间为8K。l 片上集成512B的RAM。l 32个I/O口,复位后P1/P2/P3为准双向口/弱上拉,PO口为漏极开路,作为总线扩展时不用加上拉电阻,作为I/O口时需要加上拉电阻。l ISP/IAP。l 3个1

19、6为定时/计数器。l 4路外部中断,下降沿或低电平触发。STC89C52RC的引脚图如图9所示。图9 STC89C52RC引脚图附录2 器件选型器件名称型号数量单片机STC89C52RC1按键四角按键17电阻10K欧姆1晶振11.0592MHz1瓷片电容33pF2芯片座40DIP1排孔1*81液晶LCD128641附录3 硬件原理图附录4 程序清单源文件1:calculator.c#include #include #include#include#includeuser_define.huchar point=.;float op1;float op2;float ans;int BP_da

20、t=0; /小数点之前的数据int AP_dat=0; /小数点之后的数据uint en89=1;uint pFlag=0; /小数点输入标志uint asf=0; /等号按键标志uint optCS; /输入运算符类型uint line_f=0; /行控制uint bplen; /整数部分长度uchar BP_str=; /整数部分存放数组uchar AP_str=; /小数部分存放数组uchar ansCode=; /运算结果存放数组/*初始化显示*/void init_dis() oledDisp(0,0,); oledDisp(4,0,); oledDisp(6,0,ans:);/*数

21、值计算函数*/void numSelc(int key)if(pFlag=0) BP_dat=BP_dat*10+key; sprintf(BP_str,%d,BP_dat); bplen=strlen(BP_str)*8+24; oledDisp(line_f,16,BP_str);else AP_dat=AP_dat*10+key; sprintf(AP_str,%d,AP_dat); oledDisp(line_f,bplen,AP_str);/*延时函数,毫秒级*/void delay_ms(uint a) uint i,j; for(i=a;i0;i-) for(j=110;j0;j

22、-);/*键盘扫描*/void keyScan() uchar temp; int key; P1=0XFE; temp=P1; temp=temp&0XF0; if(temp!=0XF0) delay_ms(10); temp=P1; temp=temp&0XF0; if(temp!=0XF0) temp=P1; switch(temp) case 0XEE: key=0;break;case 0XDE: key=1;break;case 0XBE: key=2;break;case 0X7E: key=3;break; while(temp!=0XF0) temp=P1; temp=tem

23、p&0XF0; numSelc(key); P1=0XFD; temp=P1; temp=temp&0XF0; if(temp!=0XF0) delay_ms(10); temp=P1; temp=temp&0XF0; if(temp!=0XF0) temp=P1; switch(temp) case 0XED: key=4;break;case 0XDD: key=5;break;case 0XBD: key=6;break;case 0X7D: key=7;break; while(temp!=0XF0) temp=P1; temp=temp&0XF0; numSelc(key); P1=

24、0XFB; temp=P1; temp=temp&0XF0; if(temp!=0XF0) delay_ms(10); temp=P1; temp=temp&0XF0; if(temp!=0XF0) temp=P1; switch(temp) case 0XEB: key=8;break;case 0XDB: key=9;break;case 0XBB: pFlag=1;break;case 0X7B: asf=1;pFlag=0;break; while(temp!=0XF0) temp=P1; temp=temp&0XF0; if(pFlag=1&en89=1) oledDisp(line

25、_f,strlen(BP_str)*8+16,point); /计算小数点显示的地址 en89=0; else if(asf=1) if(strlen(AP_str)=0) op2=BP_dat; else op2=BP_dat+(float)(AP_dat)/(10(strlen(AP_str); /得到第二个运算数 switch(optCS) case 0:ans=op1+op2;break;case 1:ans=op1-op2;break;case 2:ans=op1*op2;break;case 3:ans=op1/op2;break; sprintf(ansCode,%f,ans);

26、 /将浮点型数据转换为字符串以显示在LCD上 oledDisp(6,32,ansCode); pFlag=0; BP_dat=0; AP_dat=0; else numSelc(key); P1=0XF7; temp=P1; temp=temp&0XF0; if(temp!=0XF0) delay_ms(10); temp=P1; temp=temp&0XF0; if(temp!=0XF0) temp=P1; switch(temp) case 0XE7: optCS=0;break;case 0XD7: optCS=1;break;case 0XB7: optCS=2;break;case

27、0X77: optCS=3;break; while(temp!=0XF0) temp=P1; temp=temp&0XF0; if(strlen(AP_str)=0) op1=BP_dat; else op1=BP_dat+(float)(AP_dat)/(10(strlen(AP_str); /转换得到第一个运算数 line_f=4; AP_dat=0; BP_dat=0; pFlag=0; en89=1; switch(optCS) case 0:oledDisp(2,1,+);break;case 1:oledDisp(2,1,-);break; case 2:oledDisp(2,1

28、,*);break;case 3:oledDisp(2,1,/);break;void main(void)CS2=1;CS1=0;initLcd(); /初始化LCDclr_SCR(); init_dis(); /初始化显示P3=0X00;while(1)keyScan(); /循环按键扫描头文件: user_define.h#ifndef _USER_DEFINE_H_#define _USER_DEFINE_H_#define uchar unsigned char #define uint unsigned int#define ulong unsigned longsbit CLK=

29、P00; /接口定义:CLKsbit MOSI=P01; /接口定义:MOSIsbit DC=P02; /接口定义:DCsbit CS1=P03; /接口定义:OLED的片选CS1sbit FSO=P04; /字库IC接口定义:FSOsbit CS2=P05; /字库IC接口定义:CS2void oledDisp(uchar y,uchar x,uchar *text); /函数声明void clr_SCR();void initLcd();void delay_ms(uint a) ;#endif源文件: oled_driver.c#include#include #includeuser_

30、define.h/*写指令到LCD模块*/void wr_CMD(int data1) char i;DC=0;CLK=0;for(i=0;i8;i+)if(data1&0x80) MOSI=1;else MOSI=0;CLK=1;_nop_();CLK=0; data1=1;/*写数据到LCD模块*/void wr_DAT(int data1)char i;DC=1;CLK=0;for(i=0;i8;i+)if(data1&0x80) MOSI=1;else MOSI=0;CLK=1;_nop_();CLK=0; data1 4) | 0x10);/设置列地址的高4位wr_CMD(page

31、& 0x0f) | 0x00);/设置列地址的低4位/*全屏清屏*/void clr_SCR()unsigned char i,j;CS1=0;CS2 = 1;for(i=0;i8;i+)wr_CMD(0xb0+i);wr_CMD(0x00);wr_CMD(0x10);for(j=0;j0;j-)lcd_Add(column,page);for (i=0;i0;j-)lcd_Add(column,page);for (i=0;i8;i+)wr_DAT(*dp);/写数据到LCD,每写完一个8位的数据后列地址自动加1dp+;page+;CS1=1;/*送指令到晶联讯字库IC*/void wrCM

32、D_ROM( uchar datu )uchar i;for(i=0;i8;i+ )if(datu&0x80)MOSI = 1;elseMOSI = 0;datu = datu1;CLK=0;CLK=1;/*从晶联讯字库IC中取汉字或字符数据(1个字节)*/static uchar rdDat_ROM( )uchar i;uchar ret_data=0;CLK=1;for(i=0;i8;i+)FSO=1;CLK=0;ret_data=ret_data1;if( FSO )ret_data=ret_data+1;elseret_data=ret_data+0;CLK=1;return(ret_

33、data);/*从相关地址(addrHigh:地址高字节,addrMid:地址中字节,addrLow:地址低字节)*中连续读出DataLen个字节的数据到 pBuff的地址*/void gnBD_rom(uchar addrHigh,uchar addrMid,uchar addrLow,uchar *pBuff,uchar DataLen )uchar i;CS2 = 0;CS1=1;CLK=0;wrCMD_ROM(0x03);wrCMD_ROM(addrHigh);wrCMD_ROM(addrMid);wrCMD_ROM(addrLow);for(i = 0; i 0x00)if(text

34、i=0xb0) &(texti=0xa1)fontaddr = (texti- 0xb0)*94; fontaddr += (texti+1-0xa1)+846;fontaddr = (ulong)(fontaddr*32);addrHigh = (fontaddr&0xff0000)16; /地址的高8位,共24位addrMid = (fontaddr&0xff00)8; /地址的中8位,共24位addrLow = fontaddr&0xff; /地址的低8位,共24位/*取32个字节的数据,存到fontbuf32*/gnBD_rom(addrHigh,addrMid,addrLow,fon

35、tbuf,32 );/*显示汉字到LCD上,y为页地址,x为列地址,fontbuf为数据*/disp_16X16(y,x,fontbuf);i+=2;x+=16;else if(texti=0xa1) &(texti=0xa1)/*Address = (MSB - 0xa1) * 94 + (LSB - 0xA1)*32+ BaseAdd;BaseAdd=0*/fontaddr = (texti- 0xa1)*94; fontaddr += (texti+1-0xa1);fontaddr = (ulong)(fontaddr*32);addrHigh = (fontaddr&0xff0000)16; /地址的高8位,共24位addrMid = (fontaddr&0xff00)8; /地址的中8位,共24位addrLow = fontaddr&0xff; /地址的低8位,共24位/*取32个字节的数据,存到fontbuf32*/gnBD_rom(addrHigh,addrMid,addrLow,fontbuf,32 );/*

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 初中资料

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁