51单片机矩阵键盘计算器

合集下载

51单片机实现多模式计算器

51单片机实现多模式计算器

51单⽚机实现多模式计算器介绍单⽚机型号: 普中89C51能够最⼤输出4位数结果,保留两位⼩数。

实现计算器⼀些功能。

适⽤于C51单⽚机。

模式1: 加减陈除模式2: 三⾓函数模式3: 阶乘,开⽅,e的x次⽅,log运算若有错误和不规范之处,还恳请各位看官多多指教。

经验吸取保留两位⼩数的时候由于c语⾔float精度、⽆符号整数和浮点数强制类型转换等问题,总是有误差。

我最后选择将结果加上0.005再进⾏强制类型转换(向下取整)从⽽模拟了四舍五⼊,问题得以解决。

long型很重要,单⽚机⾥float 和long型是4个字节,⽽int是2个字节若处理的数据⼤于255,不想溢出的话就不要⽤int调试的时候,可以使⽤在怀疑有错误的地⽅加上led显⽰,或者数码管显⽰的代码。

根据单⽚机上的显⽰来获取错误反馈。

代码/*Author: WuYE*/#include "reg52.h"#include "math.h"#include "string.h"typedef unsigned char u8;typedef unsigned int u16;#define GPIO_KEY P1 //定义数码管为P1引脚#define GPIO_DIG P0 //定义矩阵键盘引脚#define PI 3.14159sbit LSA = P2 ^ 2; //定义数码管引脚sbit LSB = P2 ^ 3; //sbit LSC = P2 ^ 4; //sbit k1 = P3 ^ 1; //定义独⽴按键引脚sbit k2 = P3 ^ 0; //sbit k3 = P3 ^ 2; //sbit k4 = P3 ^ 3; //u8 code numbertube[20] = { //定义数码管显⽰的数值0x3f, 0x06, 0x5b, 0x4f, 0x66, //显⽰0~9数字0x6d, 0x7d, 0x07, 0x7f, 0x6f, //0Xbf, 0x86, 0xdb, 0xcf, 0xe6, //显⽰0~9带⼩数点数字0xed, 0xfd, 0x87, 0xff, 0xbf //};u8 opkenkey = 0; //按下数码管不再显⽰0000u8 model = 0; //计算器模式为初始模式u8 AllowOutPutResult = 0; //默认不允许输出结果,因为不满⾜计算条件u8 numberseat = 0; //保存当前输⼊的数字的位数u8 number[4]; //保存输⼊的数字的数组u8 StopCalc = 0; //计算结束后就关闭计算器计算功能,但是按键检测功能仍然活跃。

简易计算器(1602加矩阵键盘)

简易计算器(1602加矩阵键盘)

一、原理图:二、程序#include<reg51.h> //包含单片机寄存器的头文件#include<intrins.h> //包含_nop_()函数定义的头文件#include<math.h>sbit RS=P2^0; //寄存器选择位,将RS位定义为P2.0引脚sbit RW=P2^1; //读写选择位,将RW位定义为P2.1引脚sbit E=P2^2; //使能信号位,将E位定义为P2.2引脚sbit BF=P1^7; //忙碌标志位,#define NO_KEY_PRESS 0xff/********************************************************************************************************/unsigned char code tab[]={0xb7,0xee,0xde,0xbe,0xed,0xdd,0xbd,0xeb,0xdb,0xbb};unsigned long num1,num2,alg;unsigned char flag;void delay1ms(){unsigned char i,j;for(i=0;i<10;i++)for(j=0;j<15;j++);}/********************************************************************************************************/void delay(unsigned char n){unsigned char i;for(i=0;i<n;i++)delay1ms();}/*****************************************************函数功能:判断液晶模块的忙碌状态返回值:result。

矩阵键盘简易计算器

矩阵键盘简易计算器
这次设计进一步端了我的学习态度,学会了实事求是,严谨的作风,对自己要严格要求,不能够一知半解,要力求明明白白。急于求成是不好的,我有所感受。如果省略了那些必要的步骤,急于求成,不仅会浪费时间,还会适得其反。我觉得动手之前,头脑里必须清楚该怎么做,这一点是很重要的。就目前来说,我的动手能力虽然差一点,但我想,通过我的不懈努力,在这方面,我总会得到提高。
{
for(j=s+1;j<8;j++)
{
if(temp[j]==48)
k++;
}
if(k==7-s)
{
for(;s<8;s++)
TempData[s]=0;
break;
}
else
TempData[s]=0x98;
}
else
TempData[s]=dofly_DuanMa[temp[s]-'0'];//其他0-9则进行ASCII到数字处理,如当前是'3',用'3'-'0'=3
图3 键盘按键
4
每个按键都有它的行值和列值,行值和列值的组合就是识别这个按键的编码。矩阵的行线和列线分别通过两并行接口和CPU通信。键盘的一端(列线)通过电阻接VCC,而接地是通过程序输出数字“0”实现的。键盘处理程序的任务是:确定有无键按下,判断哪一个键按下,键的功能是什么?还要消除按键在闭合或断开时的抖动。两个并行口中,一个输出扫描码,使按键逐行动态接地;另一个并行口输入按键状态,由行扫描值和回馈信号共同形成键编码而识别按键,通过软件查表,查出该键的功能。
Init_Timer0(); //初始化定时器0
while (1) //主循环

单片机中用矩阵键盘实现计算器

单片机中用矩阵键盘实现计算器
{
num=num1/num2;
}
if(flag2==2&&flag1==2) //乘号和等号被按下
{
num=num1*num2;
}
if(flag2==3&&flag1==2) //减号和等号被按下
{
num=num1-num2;
}
if(flag2==4&&flag1==2) //加号和等号被按下
{
num=num1+num2;
display();//数据显示
}
}
void keyscan(void)
{
col_1=0;
col_2=0;
col_3=0;
col_4=0;
if ((P1&0x0f)!=0x0f) //判断行线是否全为1,不是则处理
{
col_1=0; //第一列输出'0'
col_2=1;
col_3=1;
col_4=1;
num2=7;
break;
case 2:if(flag==1)
num1=4;
if(flag==3)
num2=4;
break;
case 3:if(flag==1)
num1=1;
if(flag==3)
num2=1;
break;
case 5:if(flag==1)
num1=8;
if(flag==3)
num2=8;
case 15:
flag2=3;//“-”
break;
case 16:
flag2=4;//“+”
break;
}
keynum=0;//清除keynum的值

51单片机矩阵键盘计算器

51单片机矩阵键盘计算器

/****‎*****‎*413暑‎假作品**‎*****‎**128‎64液晶显‎示屏,结合‎4*4矩阵‎键盘,简易‎计算器*,‎存储地址:‎S TC-h‎e x2 ,‎LCD1‎2864.‎c**‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎//**‎*功能:1‎、基本整数‎的加减乘除‎; 2、有‎清除功能;‎3、除法计‎算,结果保‎留两位小数‎;4、分母‎为0报错*‎*****‎**//‎*****‎****5‎、小数减大‎数可显示负‎号;6、只‎能做两个数‎的加减乘除‎;7、可做‎10位数的‎有效运算*‎*****‎*****‎*****‎*****‎*****‎*****‎****/‎/***‎***注意‎:计算结果‎要求余显示‎,比如正确‎结果123‎,求余显示‎321,所‎以将321‎逐个赋给某‎一数组,倒‎序向128‎64输出*‎*/‎#incl‎u de<r‎e g52.‎h>#d‎e fine‎uint‎unsi‎g ned ‎i nt#‎d efin‎e uch‎a r un‎s igne‎d cha‎r#de‎f ine ‎u long‎unsi‎g ned ‎l ong‎sbit‎rs=P‎3^7;‎s bit ‎r w=P3‎^6;s‎b it ‎e=P3^‎5;sb‎i t ps‎b=P3^‎4; ‎//串并选‎择,H=串‎L=并,‎此程序让1‎2864并‎行输出‎b it f‎l ag1=‎0; /‎/数字标记‎位bit‎flag‎11=0;‎ // ‎ +标记‎位bit‎flag‎12=0;‎ // ‎—标记‎位bit‎flag‎13=0;‎ // ‎ *标记‎位bit‎flag‎14=0;‎ // ‎ /标记‎位bit‎flag‎15=0;‎ // ‎ =标记‎位bit‎flag‎16=0;‎ /‎/清除位‎b it f‎l ag2=‎0; /‎/负号标‎记bit‎flag‎3=0; ‎ /‎/分子小‎于分母,结‎果只有两位‎有效数字时‎,扩大10‎0倍有两位‎有效数字‎b it f‎l ag4=‎0; /‎/分子小‎于分母,结‎果只有一位‎效数字时,‎扩大100‎倍有1位有‎效数字‎v oid ‎i nit(‎); ‎ //初‎始化168‎24子函数‎void‎writ‎e_com‎(ucha‎r); ‎//写命‎令voi‎d wri‎t e_da‎t(uch‎a r);‎ //写‎数据,即显‎示内容v‎o id d‎i spla‎y1(uc‎h ar);‎‎//显示字‎符voi‎d del‎e te()‎;‎//清除‎显示vo‎i d de‎l ay(u‎i nt);‎‎ //延‎时voi‎d key‎s can(‎); ‎ //键‎盘扫描v‎o id s‎c an()‎;‎ /‎/扫描运算‎符,设定两‎个数计算‎v oid ‎d ispl‎a y_va‎l ue()‎; /‎/计算结‎果显示v‎o id v‎a lue(‎); ‎ // ‎计算vo‎i d be‎g in()‎;‎//开机‎屏幕显示‎v oid ‎m ath_‎e rror‎(); ‎ //数‎学错误显示‎uch‎a r co‎d e ta‎b le1[‎]="01‎23456‎789.+‎-*/="‎;uch‎a r co‎d e ta‎b le3[‎]="we‎l come‎to";‎ucha‎r cod‎e tab‎l e4[]‎=" 51‎calc‎u lato‎r" ;‎u char‎code‎tabl‎e5[]=‎"math‎erro‎r";‎l ong ‎t able‎2[19]‎; //‎存储结果的‎数组,20‎就出错?‎l ong ‎s,a,b‎,num1‎; //‎s为计算结‎果,a为第‎一个数,b‎为第二个数‎,num1‎对应为键对‎应的值为显‎12864‎显示服务‎/****‎*****‎*****‎*****‎*****‎*****‎*****‎*主**函‎**数**‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎**/v‎o id m‎a in()‎{‎i nit(‎);‎d elay‎(5);‎beg‎i n();‎ /‎/开机初始‎化d‎e lay(‎5);‎writ‎e_com‎(0x80‎); //‎输入数在第‎一行显示‎whi‎l e(1)‎‎//大循‎环使其不断‎的显示‎{‎keys‎c an()‎;‎s can(‎);‎valu‎e();‎di‎s play‎_valu‎e();‎de‎l ete(‎);‎‎}}‎/****‎*****‎**初始化‎*****‎*****‎*****‎*****‎*****‎*****‎**/v‎o id i‎n it()‎{‎psb=‎1; ‎//并口‎传输方式‎‎d‎e lay(‎50); ‎‎‎//先等待‎50个毫秒‎w‎r ite_‎c om(0‎x30);‎ /‎/基本操作‎指令‎dela‎y(5);‎w‎r ite_‎c om(0‎x0e);‎‎//显示状‎态开/关,‎08什么也‎没有;0c‎无光标;0‎e有光标但‎不闪;0f‎有光标闪烁‎d‎e lay(‎5);‎ wri‎t e_co‎m(0x0‎1); ‎ //清‎除显示‎ del‎a y(5)‎;‎w rite‎_com(‎0x06)‎;‎//进入点‎设置‎dela‎y(5);‎}/*‎*****‎*****‎*****‎写指令**‎*****‎*****‎*****‎*****‎*****‎/voi‎d wri‎t e_co‎m(uch‎a r co‎m){‎rs=0‎;‎//‎表示写命令‎rw=‎0;e‎=0;‎P0=co‎m;d‎e lay(‎5);‎e=1;‎dela‎y(5);‎e=0‎;‎‎}‎/****‎*****‎*****‎***写数‎据****‎*****‎*****‎*****‎*****‎***/‎v oid ‎w rite‎_dat(‎u char‎dat)‎{r‎s=1; ‎‎ //‎表示写数据‎rw=‎0;e‎=0;‎P0=da‎t;d‎e lay(‎5);‎e=1;‎dela‎y(5);‎e=0‎;}‎/****‎*****‎*****‎***显示‎字符函数*‎*****‎*****‎*****‎*****‎****/‎void‎disp‎l ay1(‎u char‎num1‎){ ‎w‎r ite_‎d at(t‎a ble1‎[num1‎]);‎ del‎a y(2)‎;}‎/****‎*****‎*****‎*****‎*****‎*****‎*****‎***键*‎*盘**扫‎**描 P‎1口***‎*****‎*****‎*****‎*****‎*****‎*****‎/voi‎d key‎s can(‎){ ‎ uc‎h ar t‎e mp; ‎/‎*第一行*‎/‎P1=0x‎f e; ‎‎//将第一‎行置为低电‎平,其余行‎线置为高电‎平‎t emp=‎P1; ‎ //读‎取P3口当‎前状态赋‎给临时变量‎t emp,‎用于后面计‎算‎t emp=‎t emp&‎0xf0;‎ //‎判断第一行‎是否有按键‎按下‎whil‎e(tem‎p!=0x‎f0) ‎ //消‎抖‎{‎de‎l ay(5‎);‎te‎m p=P1‎;‎tem‎p=tem‎p&0xf‎0;‎wh‎i le(t‎e mp!=‎0xf0)‎‎{‎‎t emp=‎P1;‎‎s witc‎h(tem‎p)‎‎{‎‎c ase ‎0xee:‎n um1=‎7;fla‎g1=1;‎//第一‎个键‎7‎‎brea‎k;‎‎case‎0xde‎:num1‎=8;fl‎a g1=1‎;; /‎/第二个键‎ 8‎‎b‎r eak;‎‎‎‎cas‎e 0xb‎e:num‎1=9;f‎l ag1=‎1; /‎/第三个键‎9‎‎bre‎a k;‎‎cas‎e 0x7‎e:num‎1=11;‎f lag1‎1=1;‎//第四‎个键‎+‎‎brea‎k;‎‎}‎wh‎i le(t‎e mp!=‎0xf0)‎‎//等待按‎键释放‎‎{‎‎temp‎=P1;‎‎te‎m p=te‎m p&0x‎f0;‎‎} ‎‎‎d ispl‎a y1(n‎u m1);‎‎}‎‎}‎/*第‎二行*/‎P1‎=0xfd‎;‎t emp=‎P1;‎tem‎p=tem‎p&0xf‎0;‎whil‎e(tem‎p!=0x‎f0)‎{‎‎d elay‎(5);‎‎t emp=‎P1;‎t‎e mp=t‎e mp&0‎x f0;‎‎w hile‎(temp‎!=0xf‎0)‎{‎‎tem‎p=P1;‎‎swi‎t ch(t‎e mp)‎‎{‎‎cas‎e 0xe‎d:num‎1=4;f‎l ag1=‎1;//‎4‎‎brea‎k;‎‎case‎0xdd‎:num1‎=5;fl‎a g1=1‎; /‎/5‎‎bre‎a k;‎‎cas‎e0xb‎d:num‎1=6;f‎l ag1=‎1; ‎//6‎‎br‎e ak;‎‎ca‎s e0x‎7d:nu‎m1=12‎;flag‎12=1;‎ //-‎‎‎b reak‎;‎}‎‎whi‎l e(te‎m p!=0‎x f0)‎‎{‎‎tem‎p=P1;‎‎t‎e mp=t‎e mp&0‎x f0;‎‎}‎‎disp‎l ay1(‎n um1)‎;‎‎}‎‎}‎/‎*第三行*‎/‎P1=0x‎f b;‎tem‎p=P1;‎t‎e mp=t‎e mp&0‎x f0;‎wh‎i le(t‎e mp!=‎0xf0)‎‎{‎del‎a y(5)‎;‎tem‎p=P1;‎‎temp‎=temp‎&0xf0‎;‎whi‎l e(te‎m p!=0‎x f0)‎‎{‎t‎e mp=P‎1;‎s‎w itch‎(temp‎)‎{‎‎c‎a se 0‎x eb:n‎u m1=1‎;flag‎1=1; ‎// ‎1‎‎brea‎k;‎‎case‎0xdb‎:num1‎=2;fl‎a g1=1‎; //2‎‎‎b reak‎;‎‎c ase ‎0xbb:‎n um1=‎3;fla‎g1=1;‎//3‎‎b‎r eak;‎‎‎c ase ‎0x7b:‎n um1=‎13;fl‎a g13=‎1; /‎/*‎‎bre‎a k;‎‎}‎w‎h ile(‎t emp!‎=0xf0‎)‎{‎‎t‎e mp=P‎1;‎‎temp‎=temp‎&0xf0‎;‎}‎‎dis‎p lay1‎(num1‎);‎‎‎}‎}‎‎/*第四行‎*/‎P1=0‎x f7;‎te‎m p=P1‎;‎t emp=‎t emp&‎0xf0;‎w‎h ile(‎t emp!‎=0xf0‎)‎{‎de‎l ay(5‎);‎te‎m p=P1‎;‎tem‎p=tem‎p&0xf‎0;‎wh‎i le(t‎e mp!=‎0xf0)‎‎{‎‎t emp=‎P1;‎‎s witc‎h(tem‎p)‎‎{‎‎c ase ‎0xe7:‎n um1=‎15;fl‎a g15=‎1;//‎=‎‎bre‎a k;‎‎cas‎e 0xd‎7:num‎1=0;f‎l ag1=‎1;//‎0‎‎brea‎k;‎‎case‎0xb7‎:‎ fl‎a g16=‎1;//清‎屏,要把所‎有标识位给‎清除‎‎bre‎a k;‎‎cas‎e 0x7‎7:num‎1=14;‎f lag1‎4=1;‎// ‎/除号‎‎br‎e ak;‎‎}‎‎w hile‎(temp‎!=0xf‎0)‎‎{‎‎t emp=‎P1;‎‎tem‎p=tem‎p&0xf‎0;‎‎}‎‎di‎s play‎1(num‎1); ‎‎‎}‎}‎}/*‎*****‎*****‎*****‎*****‎*****‎*****‎***扫描‎运算符,设‎定两个数计‎算****‎*****‎*****‎***8*‎*****‎*****‎*****‎*****‎/voi‎d sca‎n(){‎‎if(‎f lag1‎5==0)‎‎// ‎只有没按‎等号才能‎进入{‎‎if‎(flag‎11||f‎l ag12‎||fla‎g13||‎f lag1‎4)‎{ ‎‎ if‎(flag‎1==1)‎ /‎/不使运‎算符对应‎的num1‎进入‎ {‎‎b=b*‎10+nu‎m1;‎f‎l ag1=‎0; ‎ //b‎为第二个数‎,并防止b‎不断死循环‎‎} ‎‎}‎‎i f(fl‎a g1==‎1) ‎//a为‎第一个数‎{‎a‎=a*10‎+num1‎;‎‎fla‎g1=0;‎}‎} ‎}/*‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎计****‎算****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎**/v‎o id v‎a lue(‎){‎ if(‎f lag1‎5==0)‎‎ // ‎只有没按‎等号才能‎进入,只要‎按等号就不‎会运算,防‎止死循环‎ { ‎‎if(‎f lag1‎1==1)‎‎//加法‎{‎s=a+‎b; }‎‎‎‎els‎e if(‎f lag1‎2==1)‎‎//减法‎{‎‎if(a‎>=b) ‎‎//做减‎法时,判断‎两个数大小‎‎{ s‎=a-b;‎ } ‎‎e‎l se‎‎{‎s‎=b-a;‎‎fl‎a g2=1‎;‎//如果‎a<b,f‎l ag2是‎负号标记‎‎}‎}‎el‎s e if‎(flag‎13==1‎)‎//乘法‎‎{ s=‎a*b; ‎ }‎‎‎‎else‎if(f‎l ag14‎==1) ‎‎//除法‎{‎‎s=‎(((fl‎o at)a‎/b)*1‎00); ‎//s‎为long‎,将a/b‎结果转化为‎f loat‎‎}‎}}‎/***‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎****计‎算结果显示‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎*****‎***/‎v oid ‎d ispl‎a y_va‎l ue()‎{‎l ong ‎n=0,y‎;‎i f(fl‎a g15=‎=1)‎{‎flag‎15=0;‎w‎r ite_‎c om(0‎x98);‎‎//结果在‎第四行显示‎i‎f(s==‎0) ‎ /‎/如果两数‎相减结果s‎为0,直接‎输出0‎{ ‎ wri‎t e_da‎t('0'‎); }‎‎‎if(‎f lag2‎==1) ‎‎ //如‎果小数减大‎数,先输出‎一个‘-’‎,再输出结‎果‎{ wr‎i te_d‎a t('-‎'); ‎}‎i‎f(s!=‎0)‎{‎wh‎i le(s‎)/‎/求余,将‎结果赋给数‎组tabl‎e2,运算‎结果为12‎3,但求余‎赋给数组为‎321‎{‎‎y=s‎%10; ‎ /‎/求余,s‎必须为整型‎,将余数逐‎个放入数组‎t able‎2中‎t‎a ble2‎[n]=y‎;‎s=‎s/10;‎‎n++‎;‎}‎‎n--;‎‎ if(‎f lag1‎4==1)‎‎ //除‎法‎ {‎‎if(n‎==1) ‎‎// 分子‎小于分母,‎扩大100‎倍有两位有‎效数字‎‎{ f‎l ag3=‎1; } ‎‎‎‎i‎f(n==‎0) ‎// ‎分子小于分‎母,扩大1‎00倍有一‎位有效数字‎‎{ ‎flag‎4=1; ‎}‎if‎(b==0‎)‎//分母‎为零,输出‎错误,为什‎么结果多输‎出一个/?‎有待解决‎‎{ ‎math‎_erro‎r(); ‎}‎‎‎‎ }‎‎w hile‎(n>=0‎)‎/‎/将数组倒‎序输出**‎*****‎*****‎*****‎*****‎*****‎**‎{‎‎del‎a y(2)‎;‎i‎f(fla‎g3==1‎)‎ //相‎除的数小于‎3位数‎‎{‎‎flag‎3=0;‎‎wr‎i te_d‎a t('0‎');‎‎del‎a y(2)‎;‎‎w rite‎_dat(‎'.');‎‎}‎‎if(‎(flag‎4==1)‎&(b!=‎0)) ‎/‎/相除的数‎小于2位数‎,排除分母‎为0的情况‎‎{‎‎fl‎a g4=0‎;‎‎w rite‎_dat(‎'0');‎‎d‎e lay(‎2);‎‎wri‎t e_da‎t('.'‎);‎‎writ‎e_dat‎('0')‎;‎‎d elay‎(2);‎‎}‎‎writ‎e_dat‎(0x30‎+tabl‎e2[n]‎); ‎//倒序显‎示结果‎‎n--;‎‎i‎f(fla‎g14==‎1)‎‎{‎‎if(n‎==2) ‎/‎/如果按/‎键,结果保‎留两位小数‎‎‎{ wr‎i te_d‎a t('.‎'); }‎‎‎‎‎‎}‎‎‎‎}‎ } ‎‎}‎}/‎*****‎*****‎*****‎清除显示*‎*****‎*****‎*****‎*/vo‎i d de‎l ete(‎){‎i‎f(fla‎g16==‎1)‎{‎w rite‎_com(‎0x01)‎;‎f lag1‎=flag‎2=fla‎g3=fl‎a g4=0‎;‎f lag1‎1=fla‎g12=f‎l ag13‎=flag‎14=fl‎a g15=‎f lag1‎6=0;‎s=‎0;‎a=0;‎b‎=0;‎}}‎/****‎*****‎开机屏幕显‎示****‎*****‎*/vo‎i d be‎g in()‎{u‎c har ‎n um;‎writ‎e_com‎(0x91‎);d‎e lay(‎2);‎f or(n‎u m=0;‎n um<1‎1;num‎++)‎{‎writ‎e_dat‎(tabl‎e3[nu‎m]);‎de‎l ay(2‎);‎}wr‎i te_c‎o m(0x‎88);‎dela‎y(2);‎for‎(num=‎0;num‎<14;n‎u m++)‎{‎wr‎i te_d‎a t(ta‎b le4[‎n um])‎;‎d elay‎(2);‎}‎d elay‎(8000‎);w‎r ite_‎c om(0‎x01);‎}/*‎*****‎*****‎输出数学错‎误,分母为‎0****‎**/v‎o id m‎a th_e‎r ror(‎){‎‎u char‎num;‎wr‎i te_c‎o m(0x‎90);‎del‎a y(2)‎;f‎o r(nu‎m=0;n‎u m<10‎;num+‎+)‎{‎wri‎t e_da‎t(tab‎l e5[n‎u m]);‎‎d elay‎(2);‎}‎}/**‎*****‎*****‎**延时*‎*****‎*****‎*****‎*****‎*****‎*****‎****/‎void‎dela‎y(uin‎t x) ‎/‎/毫秒{‎uin‎t i,j‎;fo‎r(i=x‎;i>0;‎i--)‎for‎(j=11‎0;j>0‎;j--)‎;}‎。

自制51单片机数码管计算器(程序跟一般的有所不同,请谨慎选择,如有雷同,望君一笑)

自制51单片机数码管计算器(程序跟一般的有所不同,请谨慎选择,如有雷同,望君一笑)

// 本程序是2组数码管共4位,前1组是共阳,后1组是共阴;#include <reg52.h>#include <math.h>sbit wela= P2^6;sbit dula= P2^7;// 两个锁存器,一个控制位选,即点亮哪一只数码管;另一个控制段选,即在选定的这只数码管点显示数字几;sbit d0=P2^0;sbit d1=P2^1;sbit d2=P2^2;sbit d3=P2^3;// 这是4个独立键盘,接在P2口上;unsigned char tablewela[]= {0x0d,0x0e,0x08,0x04,0x0c}; // 1~2位是共阳管的位选(接P2^6),3~4位是共阴管的位选(接P2^7),第5位是甩空位(消隐作用); unsigned char tabledulayang[]= {0x12,0xbe,0x83,0x86,0x2e,0x46,0x42,0x9e,0x02,0x06}; // 数字0~9的编码(共阳管);unsigned char tabledulaying[]= {0xed,0x41,0x7c,0x79,0xd1,0xb9,0xbd,0x61,0xfd,0xf9};// 数字0~9的编码(共阴管);unsigned char tablelie[]= {0xef,0xdf,0xbf,0x7f}; // 4*4矩阵键盘,接P1口;高4位轮流给低电平,根据低4位的电平变化确定按下的是哪个键;//以上编码根据自己的电路图进行必要的修改;int t=0;int m;int i;int temp=0;int k=0;int u=0;int amount=0;int g;int z;void delay (long a) // 很简洁的延时子函数;{while(a)a--;}void display (int a) // 显示数a的子函数,这个函数有些特别,请大家仔细看程序的思路;{int c;int n;int j;int f[4]; // 怎么会有数组呢?其实是对一个任意的4位或4位以下的数进行拆分成单个的数字,然后赋给数组f[4],而且这个数组只是临时存储;int x[4]; // 数组x[4]的x[0],x[1],x[2],x[3]分别是所拆分的数字,比如:1104,那x[0]=1,x[1]=1,x[2]=0,x[3]=4;int *p; //指针?没搞错吧?神马情况?哈哈,继续往下看,你懂的!!if (a>=1000)//判断这个数是一个4位数吗?如果是,比如1104,那么就取出位数,是4,而j呢?下面马上会用到的,继续看。

51单片机简易计算器设计报告

51单片机简易计算器设计报告

51单片机简易计算器设计报告
本文将介绍51单片机简易计算器的设计报告。

该计算器通过
16位的LCD显示屏实现了基本计算功能,包括加、减、乘、除、取反、开方等。

1. 硬件设计
该计算器的核心部件是STC89C52单片机。

STC89C52是一种
高性能、低功耗的8位单片机,拥有8KB的Flash程序存储器和128字节的内部RAM,可提供多种功能和通讯接口。

通过
I/O口与LCD模块通讯,实现输出功能。

该计算器使用16位的LCD显示屏,显示范围为-99.99~99.99,共有6个数字位。

显示屏使用了ST7920控制器,可通过串行、并行等多种方式控制。

2. 软件设计
该计算器的软件设计主要包括三部分:键盘扫描,计算功能和LCD显示。

键盘扫描:该计算器采用4x5矩阵键盘,通过程序对键盘进行扫描,实现对不同按键的检测。

计算功能:该计算器可以实现基本的四则运算、取反、开方等功能。

对于四则运算,通过栈来实现计算,将运算符压入栈中,然后将操作数从栈中取出进行计算。

LCD显示:该计算器使用16位的LCD显示屏,通过程序控制数据和命令的传输,将计算结果显示在LCD屏幕上。

3. 总结
通过对51单片机简易计算器的设计报告,可以看出该计算器实现了基本的计算功能,通过硬件设计和软件设计相结合,将计算器的功能实现得十分完整。

该计算器的设计初步掌握了51单片机的应用,有助于后续项目的开展。

基于C51单片机的简易计算器设计

基于C51单片机的简易计算器设计

基于单片机的简易设计原理专业:通信专业班级:通信1班姓名:刘民学号:1304041127摘要:按下键盘,通过键盘扫描程序,在LCD液晶显示屏上显示按键的操作过程,最终显示计算结果,实现计算器的基本功能。

本文详细介绍LCD显示屏、矩阵键盘与C51单片机接口的应用,并介绍如何通过C51单片机实现计算器的算法。

关键字:C51单片机,键盘,LCD液晶,计算器一、设计任务:本次实验是要以51系列单片机为核心实现一个简易计算器,它的结构简单,外部主要由4*4矩阵键盘和一个液晶显示屏构成,内部由一块STC90C51单片机构成,通过软件编程可实现简单加、减、乘、除、清除结果。

实现对计算器的设计,具体设计如下:1、采用6位显示,最大显示值为“999999”,设计16个按键的矩阵键盘,按键包括‘0~9’、‘+’、‘-’、‘*’、‘/’、‘=’、‘C’。

2、加减法做四字节运算;乘法做双字节运算;除法被除数为四字节,除数为两字节。

3、当运算结果超出显示范围时,显示ERROR!。

4、上述运算输入值均为整数,当结果带有小数时,可以采用四舍五入方式处理,也可以带小数显示。

二、方案论证经分析,计算器电路包括三个部分:显示电路、、4*4键扫描电路、单片机微控制电路。

具体如下:⒈)LCD显示电路LCD1602作为一个成熟的产品,使用简单,模式固定,便于移植到各种类型的程序,但是初学者往往要注意结合LCD本身的时序图来完善初始化程序。

又以其微功耗、体积小、显示内容丰富、超薄轻巧的诸多优点,故采用LCD.⒉)4*4键盘扫描电路(中断式,扫描式,反转式)用户设计行列键盘接口,一般常采用3 种方法读取键值。

一种是中断式,外两种是扫描法和反转法。

扫描法:对键盘上的某一行送低电平,其他行及列全为高电平,然后读取列值,检查各列线点评的变化,如果某列线电平为低电平,就可以确定此行此列交叉点处的按键被按下,采用延时去抖动。

⒊)单片机微控制电路微控制电路就是以AT89C51为核心的控制核心,主要注意晶振电路的接法和复位电路的接法。

c51的简易计算器(已通过实测)初学者参考

c51的简易计算器(已通过实测)初学者参考

清零键
功能键
状态清零
根据上次功能键和输 入的数据计算结果
本次功能 键?
结果送显示缓冲 结果送显示缓冲
等待数值输入
等待数值输入
数值送显示缓冲
结果送显示缓冲 等待数值输入
LCD 显示
5
五 硬软件的调试及方法
我个人遇到的主要问题出现在 LCD1602 上,要不是我自己买了块新的 LCD 恐怕我的结 论,就只能在软件仿真实现了。
下面是源代码: #include<reg51.h> #define CLEARSCREEN
LCD_write_command(0x01)
8
#define uint unsigned int #define uchar unsigned char
/**************定义接口************************/
{
if(n<10)//键值小于 10
{
t1=t1*10+n;
LCD_write_command(0x00);//写命令语句
LCD_write_dat(mayuan[n]);//写数据函数
}
else
{
if(n==10){LCD_init();t1=0;t2=0,t=0;k=1;}
else{
if(n<15){
t=t2*t1; break; case 13: t=t2-t1; break; case 14: t=t2+t1; break; } if(t<=9){ LCD_write_command(0x00); LCD_write_dat(t+48);} if(t>9) {
六 实验结果与性能达标

基于51单片机简易计算器设计

基于51单片机简易计算器设计

2021-2021 学年_一_学期山东科技大学电工电子实验教课中心创新性实验研究报告实验工程名称__鉴于51单片机的简略计算器设计_2021年12 月27 日一、实验纲要经过对51单片机汇编指令、STC89C52RC单片机片上各功能模块、常用外面可编程芯片的学习和应用训练,进一步熟习51单片机汇编程序设计,串行总线接口程序设计以及外面可编程芯片的使用方法。

学习创新性实验报告的撰写方法。

二、实验目的1、鉴于STC89C52RC单片机设计制作简略计算器,能达成绝对值小于的有符号整数的加减乘除四那么运算,运算结果均保留小数点后一位。

2、要求有加、减、乘、除、负号、归零、等号键。

3、利用6位LED显示参加运算的数据和运算结果,显示运算结果超限提示,消隐未使用位。

4、鼓舞进行探究。

可在认识实验室器械并能实现题目根本要求的状况下,对题目进行创新设计三、实验场所及仪器、设施和资料:1、实验场所:J11-3242、实验仪器、设施和资料:PC兼容机一台、80C52单片机实验箱一台、2*8键盘一个、6个共阳极的数码管、连线假定干四、实验内容1、实验原理依据功能和指标要求,本系统采纳MCS-51系列单片机为主控机。

经过扩展必需的外头接口电路,实现对计算器的设计。

详细设计以下:〔1〕因为要设计的是简单的计算器,能够进行四那么运算,为了获得较好的显示成效,采纳LED显示数据和结果。

〔2〕此外键盘包含数字键〔0~9〕、符号键〔+、-、×、÷〕、去除键和等号键,故只要要16个按键即可,设计中采纳集成的计算键盘。

〔3〕履行过程:开机显示零,等候键入数值,当键入数字,经过LED显示出来,当键入+、-、*、/运算符,计算器在内部履行数值变换和储存,并等待再次键入数值,当再键入数值后将显示键入的数值,按等号就会在LED上输出运算结果。

系统模块图:2、实验内容〔一〕、整体硬件设计本设计采纳AT89C52单片机为主控单元。

51单片机实习的计算器

51单片机实习的计算器

基于51/52单片机的简易计算器制作、题目利用单片机芯片STC89C52、四位八段共阴数码管及已制作好的电路板等器件设计制作一个计算器。

二、任务与要求要求计算器能实现加减乘除四种运算 具体如下1. 加法:四位整数加法计算结果若超过八位则显示计算错误2. 减法:四位整数减法计算结果若超过八位则显示计算错误3. 乘法:多位整数乘法计算结果若超过四位则显示计算错误4. 除法:整数除法5. 有清除功能三、课程设计简述总体设计思路简述1.按照系统设计的功能的要求 初步确定设计系统由主控模块、显示模块、键扫描接口电路共三个模块组成。

主控芯片使用STC89C52单片机。

2.键盘电路采用4*4矩阵键盘电路。

3.显示模块采用共阳极数码管构成。

四、硬件电路五、软件编程部份#include<reg52.h>#define uchar unsigned char#define uint unsigned int//uchar code num[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x40};//共阴极// 0 1 2 3 4 5 6 7 8 9 熄灭-//uchar code loc[]={0xff,0xfe,0xfd,0xfb,0xf7};//uchar code ero[]={0x79,0x50,0x5c};uchar code num[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0x40};//共阳极uchar code loc[]={0x00,0x80,0x40,0x20,0x10};uchar code ero[]={~0x79,~0x50,~0x5c};uint n=0,n1=0,n2=0; //赋初值uchar flag=0; //计算类型选择关键字void delay(int t);void display(int n);void error();main(){while(1){uchar temp;//第一行检测P3=0xfe;temp=P3;temp=temp&0xf0;if(temp!=0xf0){delay(10);temp=P3;temp=temp&0xfe;if(temp!=0xfe){temp=P3;switch(temp){case 0xee:n1=0;n2=0;n=0;flag=0;break; //清零case 0xde:n1=10*n1+0;n=n1;break;//0case 0xbe: if(flag==1)n=n2+n1; //=if(flag==2)n=n2-n1;if(flag==3)n=n2*n1;if(flag==4)n=n2/n1;n1=0;break;case 0x7e: // +n2=n1;n1=0;flag=1;break;}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}//扫描第二行P3=0xfd;temp=P3;temp=temp&0xf0;if(temp!=0xf0){delay(10);temp=P3;temp=temp&0xf0;if(temp!=0xf0){temp=P3;switch(temp){case 0xed:n1=10*n1+1;n=n1;break; //4case 0xdd:n1=10*n1+2;n=n1;break; //5case 0xbd:n1=10*n1+3;n=n1;break; //6case 0x7d:// -n2=n1;n1=0;flag=2;break;}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}//扫描第三行P3=0xfb;temp=P3;temp=temp&0xf0;if(temp!=0xf0){delay(10);temp=P3;temp=temp&0xf0;if(temp!=0xf0){temp=P3;switch(temp){case 0xeb:n1=10*n1+4;n=n1;break;case 0xdb:n1=10*n1+5;n=n1;break;case 0xbb:n1=10*n1+6;n=n1;break;case 0x7b: // *n2=n1;n1=0;flag=3;break;}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}//扫描第四行P3=0xf7;temp=P3;temp=temp&0xf0;if(temp!=0xf0){delay(10);temp=P3;temp=temp&0xf0;if(temp!=0xf0){temp=P3;switch(temp){case 0xe7:n1=10*n1+7;n=n1;break; //7case 0xd7:n1=10*n1+8;n=n1;break; //8case 0xb7:n1=10*n1+9;n=n1;break; //9case 0x77: // /n2=n1;n1=0;flag=4;break;}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}display(n);}}//延时函数void delay(int t){int x,y;for(x=0;x<t;x++)for(y=0;y<t;y++);}//数码管显示void display(int n){//溢出处理uchar g,s,b,q;int abs;if((n>9999)||(n<-999))error();//正数if((n>=0)&&(n<=9999)) {g=n%10;s=n/10%10;b=n/100%10;q=n/1000%10;P0=num[g];delay(5);P2=loc[4];delay(2);P2=loc[0];delay(3);if(n>=10){P0=num[s];P2=loc[3];delay(2);P2=loc[0];delay(3);}if(n>=100){P0=num[b];P2=loc[2];delay(2);P2=loc[0];delay(3);}if(n>=1000){P0=num[q];P2=loc[1];delay(2);P2=loc[0];delay(3);}}//负数if((n<0)&&(n>=-999)){abs=-n;g=abs%10;s=abs/10%10;b=abs/100%10;q=abs/1000%10;P0=num[g];P2=loc[4];delay(2);P2=loc[0];delay(2);if((abs/10%10>0)||(abs/100%10>0)){P0=num[s];P2=loc[3];;delay(2);P2=loc[0];delay(2);if((abs/100%10>0)){P0=num[b];P2=loc[2];delay(2);P2=loc[0];delay(2);if((abs/1000%10>0)){P0=num[q];P2=loc[1];delay(2);P2=loc[0];delay(2);}else{P0=num[11];P2=loc[1];delay(2);P2=loc[0];delay(2);}}else{P0=num[11];P2=loc[2];delay(2);P2=loc[0];delay(2);}}else{P0=num[11];P2=loc[3];delay(2);P2=loc[0];delay(2);}}}//溢出显示void error(){P2=loc[1];P0=ero[0];delay(2);P2=loc[0];delay(3);P2=loc[2];P0=ero[1];delay(2);P2=loc[0];delay(3);P2=loc[3];P0=ero[1];delay(2);P2=loc[0];delay(3);P2=loc[4];P0=ero[2];delay(2);P2=loc[0];delay(3); }。

最新武汉科技大学51单片机实现简易计算器

最新武汉科技大学51单片机实现简易计算器

二○一六~二○一七学年第一学期信息科学与工程学院电子技术综合设计(二)课程设计报告班级:电信1401班姓名:程赐项志雄学号:201404135016 201404135015指导教师:左韬二○一六年十二月一日一、实验要求利用普中科技HC6800-ES V2.0单片机开发板设计一款带蜂鸣器的电子计算器。

主要使用开发板上的数码管、LED点阵、矩阵键盘、蜂鸣器等模块功能。

开发板配有光盘,里面有各个模块的使用说明和程序范例可供参考。

1)每2位同学分工协作。

2)上电开机或者复位键按下之后,2个4位数码管分别自动显示2个同学学号的后4位。

3)定义矩阵键盘的S1-S9代表数字按键1-9,键盘S10代表数字按键0,键盘S11-S16分别代表按键+、-、×、÷、=、C,其中C按键为计算器清零按键,按下C键计算器开始新的计算。

4)计算器计算过程中,用LED点阵显示+、-、×、÷运算符号,用8位数码管显示键入的数字和运算的结果。

键入时依次显示并自动移位,例如18+9=27,先键入1,显示1,再键入8,1自动左移一位显示18,键入+,LED点阵显示+,键入9,数码管之前显示的18消失并重新显示为9,键入=,数码管显示运算结果27。

5)为这16个矩阵键盘的按键分配不同的蜂鸣器频率,使得按下不同的按键蜂鸣器响声不同,便于识别按键。

6)按键应具有一定的消除抖动功能。

7)所有单片机程序代码都用C语言编写,并烧写到单片机中上电自动运行。

二、设计思想程序流程图:三、实验原理1.单片机概述当今时代,是一个新技术层出不穷的时代。

在电子领域,尤其是自动化智能控制领域,传统的分立元件或数字逻辑电路构成的控制系统正以前所未见的速度被单片机智能控制系统所取代。

单片机具有体积小、功能强、成本低、应用面广等优点,可以说,智能控制与自动控制的核心就是单片机。

目前,一个学习与应用单片机的高潮正在工厂、学校及企事业单位大规模地兴起。

基于51单片机的简易教学计算器设计

基于51单片机的简易教学计算器设计

基于51单片机的简易教学计算器设计设计目的:本设计旨在基于51单片机实现一个简易的教学计算器,可以进行基本的四则运算,并具备一些辅助功能,帮助学生进行数学计算和学习。

设计要求:1.显示器:使用液晶显示器(LCD)来显示操作数和计算结果。

2.键盘输入:设计一个按键矩阵作为输入设备,用于输入数字和操作符。

3.四则运算:实现加法、减法、乘法和除法四种基本运算。

4.辅助功能:提供开平方、取倒数等辅助功能。

5.界面友好:界面清晰、操作简单。

硬件设计:1.51单片机(AT89C52):作为计算器的核心芯片,控制程序运行和与外围设备的交互。

2.液晶显示器(LCD):用于显示操作数和计算结果。

3.按键矩阵:用于输入数字和操作符。

4.运算模块:用于进行四则运算和辅助功能计算。

软件设计:1.系统初始化:初始化51单片机和LCD屏幕,设置键盘矩阵的引脚。

2.输入处理:通过按键矩阵检测用户输入,并将输入的字符存储在缓冲区中。

3.表达式计算:根据用户输入的表达式,通过逆波兰表达式算法将其转换为后缀表达式,并进行计算得到结果。

4.显示结果:将计算结果显示在LCD屏幕上。

5.辅助功能:根据用户选择的辅助功能,进行相应的计算,并显示结果。

6.重置功能:提供清零功能,将计算器的状态和显示结果重置。

操作流程:1.系统初始化:开机时,系统进行初始化,屏幕显示“计算器”字样。

2.输入操作数和操作符:用户通过按键矩阵输入操作数和操作符。

3.计算结果:用户输入“=”符号后,计算器根据输入的表达式进行计算,并将结果显示在LCD屏幕上。

4.辅助功能:在计算结果显示完成后,用户可选择进行辅助功能,如开平方、取倒数等操作。

5.重置功能:用户可通过按下“C”键进行重置,将计算器状态和显示结果清零。

总结:本设计基于51单片机实现了一个简易的教学计算器,具备基本的四则运算功能和一些辅助功能。

其使用液晶显示器作为显示设备,利用按键矩阵进行输入操作,通过逆波兰表达式算法进行计算,并将结果显示在屏幕上。

基于msc51单片机实现的四位4乘4矩阵键盘计算器的C语言程序及其PROTUES电路和仿真_课程设计报告

基于msc51单片机实现的四位4乘4矩阵键盘计算器的C语言程序及其PROTUES电路和仿真_课程设计报告

单片机原理及接口技术课程设计报告设计题目:计算器设计信息与电气工程学院二零一三年七月计算器设计单片机体积小,功耗小,价格低,用途灵活,无处不在,属专用计算机。

是一种特殊器件,需经过专门学习方能掌握应用,应用中要设计专用的硬件和软件。

近年来,单片机以其体积小、价格廉、面向控制等独特优点,在各种工业控制、仪器仪表、设备、产品的自动化、智能化方面获得了广泛的应用。

与此同时,单片机应用系统的可靠性成为人们越来越关注的重要课题。

影响可靠性的因素是多方面的,如构成系统的元器件本身的可靠性、系统本身各部分之间的相互耦合因素等。

其中系统的抗干扰性能是系统可靠性的重要指标。

数学是科技进步的重要工具,数据的运算也随着科技的进步越发变得繁琐复杂,计算器的出现可以大大解放人在设计计算过程中的工作量,使计算的精度、速度得到改善,通过msc51单片机,矩阵键盘和LED数码管可以实现简单的四位数的四则运算和显示,并当运算结果超出范围时予以报错。

注:这一部分主要描述题目的背景和意义,对设计所采取的主要方法做一下简要描述。

字数不要太多,300-500字。

另注:本文要当做模板使用,不要随意更改字体、字号、行间距等,学会使用格式刷。

文中给出的各项内容都要在大家的报告中体现,可采用填空的方式使用本模板。

1. 设计任务结合实际情况,基于AT89C51单片机设计一个计算器。

该系统应满足的功能要求为:(1) 实现简单的四位十进制数字的四则运算;(2) 按键输入数字,运算法则;(3) LED数码管移位显示每次输入的数据和运算结果;(4) 当运算结果超出范围时实现报错。

主要硬件设备:AT89C51单片机、LED数码管、矩阵键盘。

注:这一部分需要写明系统功能需求,用到的主要硬件(参考实验箱的说明书)。

2. 整体方案设计计算器以AT89C51单片机作为整个系统的控制核心,应用其强大的I/O功能和计算速度,构成整个计算器。

通过矩阵键盘输入运算数据和符号,送入单片机进行数据处理。

基于51单片机实验报告(计算器)

基于51单片机实验报告(计算器)

基于51单片机实验报告(计算器)一.计算器模块1.功能介绍利用8051 单片机硬件资源和常用外围电路如LCD1602,七段数码管,时钟(DS1302)温度传感器(18B20)等实现一个能做简单四则运算,并具有时钟显示,温度显示附加功能的计算器。

2.设计方案利用STC89C52为内核的单片机,PC机。

四则运算利用4*4矩阵键盘实现从0—9和运算符号的输入,并将操作过程和结果显示在LCD1602上。

时钟显示和温度显示,可以利用DS1302产生年份,月份,日期,星期,时,分,秒的数据,并将数据送往LCD1602显示,同样可以利用单片机开发板上面集成的DS18B20温度传感器来测试周围环境的温度,将获取的温度通过在LCD1602来显示。

系统设计框图3.具体实现代码计算器四则运算部分主要分为键盘扫描的键值读取,判断运算符号实现乘除优先级计算,LCD1602显示。

键盘扫描常用的有行扫描法,线反转法,此处我们用行扫描法,可以更明了读取键值。

unsigned char temp;key = null;//第一行按键P3 = 0xfe;temp = P3;temp = temp & 0xf0;if (temp != 0xf0){delay(10); //延时软件去抖动temp = P3;temp = temp & 0xf0;if (temp != 0xf0) //确认有键按下{temp = P3;switch (temp){case 0xee:key = 'D'; //读键值break;case 0xde:key = 0;break;case 0xbe:key = '=';break;case 0x7e:key = '/';break;}flag++;}}读完按键值之后我们需要读取运算的数字与运算符号,通过判断键值为数字则通过nun=nun*10+key,计算出数字,判断键值为运算符号则读出数字和键值。

基于51单片机的数码管简易计算器

基于51单片机的数码管简易计算器

基于51/52单片机的简易计算器制作一、题目利用单片机芯片STC89C52、四位八段共阳数码管及已制作好的电路板等器件设计制作一个计算器。

二、任务与要求要求计算器能实现加减乘除四种运算 具体如下1. 加法:四位整数加法计算结果若超过八位则显示计算错误2. 减法:四位整数减法计算结果若超过八位则显示计算错误3. 乘法:多位整数乘法计算结果若超过四位则显示计算错误4. 除法:整数除法5. 有清除功能三、课程设计简述总体设计思路简述1.按照系统设计的功能的要求 初步确定设计系统由主控模块、显示模块、键扫描接口电路共三个模块组成。

主控芯片使用STC89C52单片机。

2.键盘电路采用4*4矩阵键盘电路。

3.显示模块采用共阳极数码管构成。

四、硬件电路五、软件编程部份#include<reg52.h>#define uchar unsigned char#define uint unsigned int//uchar code num[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00,0x40};//共阴极// 0 1 2 3 4 5 6 7 8 9 熄灭-//uchar code loc[]={0xff,0xfe,0xfd,0xfb,0xf7};//uchar code ero[]={0x79,0x50,0x5c};uchar code num[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0x40};//共阳极uchar code loc[]={0x00,0x80,0x40,0x20,0x10};uchar code ero[]={~0x79,~0x50,~0x5c};uint n=0,n1=0,n2=0; //赋初值uchar flag=0; //计算类型选择关键字void delay(int t);void display(int n);void error();main(){while(1){uchar temp;//第一行检测P3=0xfe;temp=P3;temp=temp&0xf0;if(temp!=0xf0){delay(10);temp=P3;temp=temp&0xfe;if(temp!=0xfe){temp=P3;switch(temp){case 0xee:n1=0;n2=0;n=0;flag=0;break; //清零//0case 0xbe: if(flag==1)n=n2+n1; //=if(flag==2)n=n2-n1;if(flag==3)n=n2*n1;if(flag==4)n=n2/n1;n1=0;break;case 0x7e: // +n2=n1;n1=0;flag=1;break;}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}//扫描第二行P3=0xfd;temp=P3;temp=temp&0xf0;if(temp!=0xf0){delay(10);temp=P3;temp=temp&0xf0;if(temp!=0xf0){temp=P3;switch(temp){case 0xed:n1=10*n1+1;n=n1;break; //4case 0xdd:n1=10*n1+2;n=n1;break; //5case 0xbd:n1=10*n1+3;n=n1;break; //6case 0x7d:// -n2=n1;n1=0;flag=2;break;}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}//扫描第三行P3=0xfb;temp=P3;temp=temp&0xf0;if(temp!=0xf0){delay(10);temp=P3;temp=temp&0xf0;if(temp!=0xf0){temp=P3;switch(temp){case 0xeb:n1=10*n1+4;n=n1;break;case 0xdb:n1=10*n1+5;n=n1;break;case 0xbb:n1=10*n1+6;n=n1;break;case 0x7b: // *n2=n1;n1=0;flag=3;break;}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}//扫描第四行P3=0xf7;temp=P3;temp=temp&0xf0;if(temp!=0xf0){delay(10);temp=P3;temp=temp&0xf0;if(temp!=0xf0){temp=P3;switch(temp){case 0xe7:n1=10*n1+7;n=n1;break; //7case 0xd7:n1=10*n1+8;n=n1;break; //8case 0xb7:n1=10*n1+9;n=n1;break; //9case 0x77: // /n2=n1;n1=0;flag=4;break;}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}display(n);}}//延时函数void delay(int t){int x,y;for(x=0;x<t;x++)for(y=0;y<t;y++);}//数码管显示void display(int n){//溢出处理uchar g,s,b,q;int abs;if((n>9999)||(n<-999))error();//正数if((n>=0)&&(n<=9999)) {g=n%10;s=n/10%10;b=n/100%10;q=n/1000%10;P0=num[g];delay(5);P2=loc[4];delay(2);P2=loc[0];delay(3);if(n>=10){P0=num[s];P2=loc[3];delay(2);P2=loc[0];delay(3);}if(n>=100){P0=num[b];P2=loc[2];delay(2);P2=loc[0];delay(3);}if(n>=1000){P0=num[q];P2=loc[1];delay(2);P2=loc[0];delay(3);}}//负数if((n<0)&&(n>=-999)){abs=-n;g=abs%10;s=abs/10%10;b=abs/100%10;q=abs/1000%10;P0=num[g];P2=loc[4];delay(2);P2=loc[0];delay(2);if((abs/10%10>0)||(abs/100%10>0)){P0=num[s];P2=loc[3];;delay(2);P2=loc[0];delay(2);if((abs/100%10>0)){P0=num[b];P2=loc[2];delay(2);P2=loc[0];delay(2);if((abs/1000%10>0)){P0=num[q];P2=loc[1];delay(2);P2=loc[0];delay(2);}else{P0=num[11];P2=loc[1];delay(2);P2=loc[0];delay(2);}}else{P0=num[11];P2=loc[2];delay(2);P2=loc[0];delay(2);}}else{P0=num[11];P2=loc[3];delay(2);P2=loc[0];delay(2);}}}//溢出显示void error(){P2=loc[1];P0=ero[0];delay(2);P2=loc[0];delay(3);P2=loc[2];P0=ero[1];delay(2);P2=loc[0];delay(3);P2=loc[3];P0=ero[1];delay(2);P2=loc[0];delay(3);P2=loc[4];P0=ero[2];delay(2);P2=loc[0];delay(3); }。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
/**********413暑假作品*********12864液晶显示屏,结合4*4矩阵键盘,简易计算器*,存储地址:STC-hex2 , LCD12864.c *************************************/
/***功能:1、基本整数的加减乘除; 2、有清除功能;3、除法计算,结果保留两位小数;4、分母为0报错********/
long s,a,b,num1; //s为计算结果,a为第一个数,b为第二个数,num1对应为键对应的值为显12864显示服务
/***********************************主**函**数***********************************************************/
while(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xee:num1=7;flag1=1; //第一个键 7
break;
case 0xde:num1=8;flag1=1;; //第二个键 8
P1=0xfd;
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(5);
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{
bit flag1=0; //数字标记位
bit flag11=0; // +标记位
bit flag12=0; // —标记位
bit flag13=0; // *标记位
bit flag14=0; // /标记位
bit flag15=0; // =标记位
bit flag16=0; //清除位
}
}
/*第四行*/
P1=0xf7;
temp=P1;
temp=temp&0xf0;
while(temp!=0xf0)
{
delay(5);
temp=P1;
temp=temp&0xf0;
rw=0;
e=0;
P0=dat;
delay(5);
e=1;
delay(5);
e=0;
}
/*****************显示字符函数*************************/
void display1(uchar num1)
{
write_dat(table1[num1]);
delay(2);
}
/*************************************键**盘**扫**描 P1口*********************************/
void keyscan()
{ uchar temp;
/*第一行*/
P1=0xfe; //将第一行置为低电平,其余行线置为高电平
void main()
{
init();
delay(5);
begin(); //开机初始化
delay(5);
write_com(0x80); //输入数在第一行显示
while(1) //大循环使其不断的显示
{
keyscan();
scan();
while(temp!=0xf0)
{
temp=P1;
case 0xeb:num1=1;flag1=1; // 1
break;
case 0xdb:num1=2;flag1=1; //2
break;
case 0xbb:num1=3;flag1=1; //3
break;
while(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xe7:num1=15;flag15=1; // =
break;
case 0xd7:num1=0;flag1=1; //0
value();
display_value();
delete();
}
}
/***********初始化********************************/
void init()
{
psb=1; //并口传输方式
delay(50); //先等待50个毫秒
temp=P1;
switch(temp)
{
case 0xed:num1=4;flag1=1; //4
break;
case 0xdd:num1=5;flag1=1; //5
break;
temp=P1; //读取P3口当前状态 赋给临时变量temp,用于后面计算
temp=temp&0xf0; //判断第一行是否有按键按下
while(temp!=0xf0) //消抖
{
delay(5);
temp=P1;
temp=temp&0xf0;
temp=P1;
temp=temp&0xf0;
}
display1(num1);
}
}
/*第三行*/
P1=0xfb;
temp=P1;
temp=temp&0xf0;
void write_com(uchar); //写命令
void write_dat(uchar); //写数据,即显示内容
void display1(uchar); //显示字符
void delete(); //清除显示
void delay(uint); //延时
break;
case 0xbe:num1=9;flag1=1; //第三个键 9
break;
case 0x7e:num1=11;flag11=1; //第四个键 +
break;
}
write_com(0x30); //基本操作指令
delay(5);
write_com(0x0e); //显示状态开/关,08什么也没有;0c无光标;0e有光标但不闪;0f有光标闪烁
delay(5);
write_com(0x01); //清除显示
/*********5、小数减大数可显示负号;6、只能做两个数的加减乘除;7、可做10位数的有效运算***********************************/
/******注意:计算结果要求余显示,比如正确结果123,求余显示321,所以将321逐个赋给某一数组,倒序向12864输出**/
void keyscan(); //键盘扫描
void scan(); //扫描运算符,设定两个数计算
void display_value(); // 计算结果显示
void value(); // 计算
void begin(); //开机屏幕显示
void math_error(); //数学错误显示
bit flag2=0; // 负号标记
bit flag3=0; // 分子小于分母,结果只有两位有效数字时,扩大100倍有两位有效数字
bit flag4=0; // 分子小于分母,结果只有一位效数字时,扩大100倍有1位有效数字
void init(); //初始化16824子函数
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
#define ulong unsigned long
sbቤተ መጻሕፍቲ ባይዱt rs=P3^7;
sbit rw=P3^6;
sbit e=P3^5;
sbit psb=P3^4; //串并选择,H=串 L=并,此程序让12864并行输出
while(temp!=0xf0) //等待按键释放
{
temp=P1;
temp=temp&0xf0;
}
display1(num1);
}
}
/*第二行*/
case 0xbd:num1=6;flag1=1; //6
break;
case 0x7d:num1=12;flag12=1; //-
break;
}
while(temp!=0xf0)
{
delay(5);
write_com(0x06); //进入点设置
delay(5);
}
/****************写指令***************************/
void write_com(uchar com)
{
rs=0; //表示写命令
uchar code table1[]="0123456789.+-*/=";
uchar code table3[]="welcome to";
uchar code table4[]=" 51 calculator" ;
uchar code table5[]="math error";
long table2[19]; //存储结果的数组,20就出错?
case 0x7b:num1=13;flag13=1; //*
相关文档
最新文档