基于51单片机的简易计算器课程设计(完整代码+完整设计报告)

您所在的位置:网站首页 单片机制作计算器程序 基于51单片机的简易计算器课程设计(完整代码+完整设计报告)

基于51单片机的简易计算器课程设计(完整代码+完整设计报告)

2024-07-17 05:13| 来源: 网络整理| 查看: 265

一、简介

这学期进行了单片机的课程学习,由于有课程设计要做,但本人C语言编程基础很差,借鉴几篇博客的代码和原理,拼凑成了这份报告,参考文献会引用于末尾,虽然水平不高,但报告较完整,还是分享给大家,希望有所帮助。代码冗余,希望理解,功能也有一些缺陷,我写在了报告总结上。

使用的芯片是AT89C52,可以进行连续的四则运算,使结果在LCD屏显示,主要实现以下六个功能:

(1) 可以进行连续的整数、小数、负数之间的四则运算;

(2) 除数为0时报错;

(3) 可以删除输错的数字或符号;

(4) 按下按键时伴随提示音,且有控制开关;

(5) 可以清零操作;

(6) 小数保留两位且要求四舍五入。

按键设计如下:

二、代码

这里我直接放完整代码,在开头进行了引脚定义。报告文件中和代码后面都做了解释,这里就不多说了。

#include "reg52.h" typedef unsigned int u16; typedef unsigned char u8; #define KEY_PORT P1 //矩阵按键 sbit rw=P2^5; sbit rs=P2^6; sbit e=P2^7; sbit KEY1=P3^1; sbit KEY2=P3^0; sbit KEY3=P3^2; sbit KEY4=P3^3; code u8 ERROR[]=" ERROR!";//除数为0时,显示 code u8 wel[]=" Welcome!"; u8 negative1,negative2,fuhao,jjcc,jjcc,key_value,decimal1,decimal2,j1,x,symbol0,beep=200,be=0,be2,key=1; //第一负号标志、第二负号标志、有无运算符标志、运算符标志、按键值、第一小数标志、第二小数标志、错误显示循环变量、欢迎显示循环变量、连续计算标志、蜂鸣器循环次数、蜂鸣器开关标志、独立按键松开标志 float number1,number2,result,resulted; //第一组合数、第二组合数、结果、连续计算上次结果 u16 dec1,dec2,mul1,mul2;//第一小数、第二小数、第一小数位数还原标记、第二小数位数还原标记 long num1,num2;//第一整数、第二整数 void write_comm(u16 c);//写命令 void write_data(u16 dat);//写数据 void lcdinit(void);//lcd、变量初始化 void resultShow(float value);//结果显示 void getFuhao(key_value);//获取运算符 void getNum(key_value);//获取数字 void calculate(void);//计算 void delect(void);//删除 void numShow(u16 zhengshu);//整数显示 void getNeg(key_value);//负号、减号判断 void buzzer(beep);//蜂鸣器 //延时 void delay(u16 ten_us) { while(ten_us--); } void buzzer(beep) { while(beep--)//循环 200 次 { rw=!rw;//产生一定频率的脉冲信号 delay(100); } rw=0;//关闭蜂鸣器 } //按键 void key_scan(void) { key_value=0; KEY_PORT=0xf7;//给第一列赋值 0,其余全为 1 if(KEY_PORT!=0xf7)//判断第一列按键是否按下 { delay(1000);//消抖 switch(KEY_PORT)//保存第一列按键按下后的键值 { case 0x77: key_value=1;buzzer(beep);getNum(key_value);break; case 0xb7: key_value=4;buzzer(beep);getNum(key_value);break; case 0xd7: key_value=7;buzzer(beep);getNum(key_value);break; case 0xe7: buzzer(beep); key_value=10;//"." if(fuhao==0) { decimal1 = 1; write_data('.'); } else if(fuhao==1) { decimal2 = 1; write_data('.'); } break; } } while(KEY_PORT!=0xf7);//等待按键松开 KEY_PORT=0xfb;//给第二列赋值 0,其余全为 1 if(KEY_PORT!=0xfb)//判断第二列按键是否按下 { delay(1000);//消抖 switch(KEY_PORT)//保存第二列按键按下后的键值 { case 0x7b: key_value=2;buzzer(beep);getNum(key_value);break; case 0xbb: key_value=5;buzzer(beep);getNum(key_value);break; case 0xdb: key_value=8;buzzer(beep);getNum(key_value);break; case 0xeb: key_value=0;buzzer(beep);getNum(key_value);break; } } while(KEY_PORT!=0xfb);//等待按键松开 KEY_PORT=0xfd;//给第三列赋值 0,其余全为 1 if(KEY_PORT!=0xfd)//判断第三列按键是否按下 { delay(1000);//消抖 switch(KEY_PORT)//保存第三列按键按下后的键值 { case 0x7d: key_value=3;buzzer(beep);getNum(key_value);break; case 0xbd: key_value=6;buzzer(beep);getNum(key_value);break; case 0xdd: key_value=9;buzzer(beep);getNum(key_value);break; case 0xed: buzzer(beep); key_value=11;//"=" write_data('='); calculate(); if(symbol0==0)//显示错误时影响光标 { resulted = result; write_comm(0xC0); resultShow(result); } else symbol0=0; break; } } while(KEY_PORT!=0xfd);//等待按键松开 KEY_PORT=0xfe;//给第四列赋值 0,其余全为 1 if(KEY_PORT!=0xfe)//判断第四列按键是否按下 { delay(1000);//消抖 switch(KEY_PORT)//保存第四列按键按下后的键值 { case 0x7e: key_value=12;buzzer(beep);getFuhao(key_value);break;//"+" case 0xbe: key_value=13;buzzer(beep);getNeg(key_value);break;//"-" case 0xde: key_value=14;buzzer(beep);getFuhao(key_value);break;//"*" case 0xee: key_value=15;buzzer(beep);getFuhao(key_value);break;//"/" } } while(KEY_PORT!=0xfe);//等待按键松开 if(key==1 && (KEY1==0||KEY2==0||KEY3==0||KEY4==0))//任意按键按下 { delay(1000);//消抖 key=0; if(KEY1==0) { buzzer(beep); write_comm(0x01); lcdinit();//AC resulted=0; } else if(KEY2==0) { buzzer(beep); delect(); } else if(KEY3==0) { buzzer(beep); write_comm(0x01); lcdinit(); resultShow(resulted);//连续计算 } else if(KEY4==0) { buzzer(beep); be=be+1; be2=be%2; if(be2==0) { beep=200; } else if(be2==1) { beep=0; } } } else if(KEY1==1&&KEY2==1&&KEY3==1&&KEY4==1) //无按键按下 { key=1; } } void getNeg(key_value) { if(key_value == 13) { if(resulted==0) { if(fuhao == 0)//第一个负号 { if(num1 == 0 && dec1 == 0) { write_data('-'); negative1 = 1; } else { write_data('-'); jjcc=1; fuhao=1; } } else if(fuhao == 1)//第二个负号 { if(num2 == 0 && dec2 == 0) { negative2 = 1; write_data('-'); } } } else if(resulted!=0) { if(fuhao == 0) { write_data('-'); jjcc=1; fuhao=1; } else if(fuhao == 1) { if(num2 == 0 && dec2 == 0) { negative2 = 1; write_data('-'); } } } } } //计算 void calculate() { if(resulted!=0) { number1 = resulted; number2 = (float)num2 + (float)dec2/(float)mul2; } else { number1 = (float)num1+ (float)dec1/(float)mul1; number2 = (float)num2 + (float)dec2/(float)mul2;//类型转换 } if(negative1==1) number1 = -number1;//给负号 if(negative2==1) number2 = -number2; switch(jjcc) { case 0: result = number1 + number2;break; case 1: result = number1 - number2;break; case 2: result = number1 * number2;break; case 3: if(number2==0) { symbol0=1; write_comm(0x01); for(j1=0;j1


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3