C51编写的计算器小程序

合集下载

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

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

基于51单片机的简易计算器51单片机是一种广泛应用于嵌入式系统中的常用微控制器。

我们可以利用51单片机的强大功能和丰富的外设资源,设计一个简易计算器。

这个计算器可以进行基本的加减乘除运算,并且具备显示结果的功能。

首先,我们需要准备一块51单片机开发板,一块1602液晶显示屏模块,以及一些按键开关和电阻。

我们可以将运算器主要分为以下几个模块:数码管显示模块、键盘输入模块、运算模块和存储模块。

数码管显示模块:我们使用1602液晶显示屏模块来显示计算器的结果。

我们可以通过51单片机的IO口,将计算结果发送给液晶显示屏模块,实现结果的显示。

键盘输入模块:我们可以使用几个按键开关来实现数字和运算符的输入。

通过对按键的检测,我们可以将用户输入的数字和运算符转化为字符形式,并保存到内存中。

运算模块:我们需要根据用户输入的数字和运算符,进行相应的运算。

我们可以使用栈来实现这个功能。

栈是一种常用的数据结构,具有"先进后出"的特点。

我们可以将用户输入的数字和运算符按照一定的规则入栈,然后按照相应的顺序进行出栈和运算。

最后将结果保存到内存中。

存储模块:我们可以使用内部RAM来保存运算结果。

51单片机的内部RAM具有一定的存储能力,可以满足我们的基本需求。

在编写程序时,我们可以使用汇编语言或者C语言。

通过合理的编程,我们可以实现计算器的各项功能。

总结一下,基于51单片机的简易计算器主要包括数码管显示模块、键盘输入模块、运算模块和存储模块。

我们可以通过合理的编程,将这些模块相互配合,实现一个功能完善的计算器。

这个计算器不仅可以进行基本的加减乘除运算,还可以显示结果,方便用户进行计算。

简易计算器C51源程序

简易计算器C51源程序
{if(x>1000 && x<10000)
{buf[0]=(x%1000%100)%10;buf[1]=(x%1000%100)/10;buf[2]=(x%1000)/100;buf[3]=x/1000;buf[4]=16;buf[5]=16;buf[6]=16;buf[7]=16;}
disp();
}
void key1 (void) //判断按键是否按下
{P1=0Xf0; //4行全部送0
if(P1!=0Xf0) {disp();
{if(P1!=0Xf0) {key_flag=1;}
else {key_flag=0;}
}
}
else {key_flag=0;}
if(x>100 && x<1000)
{buf[0]=(x%100)%10;buf[1]=(x%100)/10;buf[2]=x/100;buf[3]=16;buf[4]=16;buf[5]=16;buf[6]=16;buf[7]=16;}
if(x>10 && x<100)
}
void key2 (void) //判断按键的键值
{if(key_flag==1) {P1=0xfe;
if(P1==0xee) key_value=0;
else if(P1==0xde) key_value=1;
else if(P1==0xbe) key_value=2;
else if(P1==0x7e) key_value=3;

基于51单片机的简易计算器c程序

基于51单片机的简易计算器c程序

/*...............菜鸟一枚,不好勿喷→_→............................【简易计算器的功能简介】【时间紧,先做个简易的吧,复杂的算法太难,没那么多时间写【现在也不太会→_→】,以后再研究→_→】此程序是完全基于开发板的,可在板子上直接测试【程序跑飞的概率比较大,还不太明白是哪的问题】可实现总数小于等于九位【long int】的数字的加减乘除运算【每次只能进行一项】,可清楚修改输入的数据,由于键盘等因素显示【4X4】,没有小数点键,故无法直接进行小数运算,进行除法运算时,小数点后最多可保留6位,第7位进行四舍五入。

显示器采用1602,输入或修改时开光标并闪烁,输入数据超出9位,有警告提示,加上运算符总的输入不超过15位【超过10输入逻辑已经错误】。

显示结果时关光标【重复按下时结果不变】,显示结果后,也可对输入端进行修改,按下等于键再次显示结果。

2015/1 qq:1036894850 */#include"reg52.h"#include"stdio.h"#define uchar unsigned charsbit rs=P2^4;//lcd的控制线口sbit rw=P2^5;sbit ep=P2^6;uchar ip[15];//存输入的数据,15位【理论上10位就够了】'$'记运算符'*'记为负号uchar sign;//存运算符int k=0,equ=0,sk=0,ksk=0,sg=0;void write_data(uchar dat); //给1602写数据void write_com(uchar com);void lcdinit();void delay(int z);void warn();void key_deal(uchar key);void sdeal(uchar i);void key_sub_deal();void key_equ_deal();void key_del_deal();uchar scankey();void main(){uchar key=0xff;lcdinit(); //1602初始化,结果输出位显示0,数据输入位光标闪烁。

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

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

期末课程设计学院:软件学院_____ 专业:软件工程_____ 年级:2009级____ 课程:_单片机应用技术_____ 老师:_林丽玉_____姓名:_苏志彬_ _____ 学号:_************ ______二〇一二年六月基于C51单片机的简易计算器学号:123012009186摘要:按下键盘,通过键盘扫描程序,在LCD液晶显示屏上显示按键的操作过程,最终显示计算结果,实现计算器的基本功能。

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

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

在现实生活中我们用到计算器的频率很高,且并不陌生,计算器电路包括三个部分:LCD显示电路、键盘扫描电路、单片机微控制电路。

2.LCD显示1、LCD显示器介绍LCD显示器,它是利用液晶经过处理后能改变光线的传输方向的特性实现信息的显示。

液晶显示器具有体积小、重量轻、功耗低、显示内容丰富灯特点,在单片机的应用系统中得到广泛的应用,液晶显示器按功能可分为三类:笔段式液晶显示器、字符型液晶显示器和图像点阵式液晶显示器。

前两种可显示数字、字符和符号等,而图形点阵式液晶显示器还可以显示汉字和任意图行,达到图文并茂的效果,本次实验是采用LCD1602字符型液晶显示器,LCD1602能够同时显示16x2即32个字符。

1602液晶也叫1602字符型液晶它是一种专门用来显示字母、数字、符号等的点阵型液晶模块它有若干个5X7或者5X11等点阵字符位组成,每个点阵字符位都可以显示一个字符。

每位之间有一个点距的间隔每行之间也有间隔起到了字符间距和行间距的作用。

基于C51单片机的简易电子计算器制作

基于C51单片机的简易电子计算器制作

摘要近几年单片机技术的发展很快,其中,电子产品的更新速度迅猛。

计算器是日常生活中比较常见的电子产品之一。

如何才能使计算器技术更加的成熟,充分利用已有的硬件和软件条件,设计出更出色的计算器。

本设计是以STC89C52单片机为核心的计算器模拟系统设计,输入采用4*4矩阵键盘,可以进行加、减、乘、除带符号数字运算(六位整数、两位小数),并在液晶显示屏LCD1602上静态显示操作过程及结果。

对字符液晶显示模块的工作原理,如初始化、清屏、显示、调用及外特性有较清楚的认识,并会使用LCD (液晶显示模块)实现计算结果的显示;掌握液晶显示模块的驱动和编程,设计LCD和单片机的接口电路,以及利用单片机对液晶显示模块的驱动和操作;在充分分析内部逻辑的概念,进行软件和调试,学会使用,并能够以其为平台设计出具有四则运算能力简易计算器的硬件电路和软件程序。

关键词:单片机;液晶显示屏;计算器;矩阵键盘引言现如今,人们的日常生活中已经离不开计算器了,社会的各个角落都有它的身影,比如商店、办公室、学校……因此设计一款简单实用的计算器会有很大的实际意义。

本设计旨在进一步掌握单片机理论知识,理解单片机系统的硬软件设计,加强对实际应用系统设计的能力。

通过本设计的学习,使我掌握单片机程序设计的基本方法,并能综合运用本科阶段所学软、硬件知识分析实际问题,提高解决毕业设计实际问题的能力,为单片机应用和开发打下良好的基础。

一、项目总体设计框架1、芯片STC89C52单片机是单片微型机的简称,故又称为微控制器MCU(Micro Control Unit)。

通常由单块集成电路芯片组成,内部包含有计算机的基本功能部件:中央处理器CPU,存储器和I/O接口电路等。

因此,单片机只要和适当的软件及外部设备相结合,便可成为一个单片机控制系统。

单片机广泛应用于智能产品,智能仪表,测控技术,智能接口等,具有操作简单、实用方便、价格便宜等优点。

而其中STC89C52是一种带8K字节闪烁可编程可擦除只读存储器(FPEROM-Flash Programable and Erasable Read Only Memory)的低电压,高性能COMOS8的微处理器。

用c语言编写简易计算器

用c语言编写简易计算器

在c51中用c语言编写简易计算器#include<reg52.h>#define BYTE unsigned charint jh;int a;int b;int c; /*c是符号*//*按键的值*/sbit P11=P1^3;sbit P12=P1^2;sbit P13=P1^1;sbit P14=P1^0;BYTE disply[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};void delay(int ms) //延时函数{while(ms--){ int h;for( h=0;h<=250;h++){;}}}void get_jianzhi() //获取键盘值的函数{BYTE disi;BYTE gaosi;gaosi=P2;P2=0x0f;delay(10 );disi=P2;gaosi=gaosi+disi;switch(gaosi){case 0xee:{jh=0;break;}case 0xde:{jh=1;break;}case 0xbe:{jh=2;break;}case 0x7e:{jh=3;break;}case 0xed:{jh=4;break;}case 0xdd:{jh=5;break;}case 0xbd:{jh=6;break;}case 0x7d:{jh=7;break;}case 0xeb:{jh=8;break;}case 0xdb:{jh=9;break;}case 0xbb:{jh=10;break;}case 0x7b:{jh=11;break;}case 0xe7:{jh=12;break;}case 0xd7:{jh=13;break;}case 0xb7:{jh=14;break;}case 0x77:{jh=15;break;}}do{P2=0xf0;}while(P2!=0xf0);}void show() /*显示函数*/{BYTE m; /*千位*/BYTE h; /*百位*/BYTE j; /*十位*/BYTE i; /*个位*/P3=0xff;if(c==14){b=0;}else{ }while(P2==0xf0) /*有键按下则跳出循环函数*/{j=0;i=0;h=0;m=0;if(b!=0) /*b不为0则显示b并判断它有几位数*/{if(b>99) {h=b/100;j=(b-h*100)/10;i=b%10;}else{if(b>9){j=b/10;i=b%10;}else{i=b;}}}else{if(a>999){ m=a/1000;h=(a-m*1000)/100;j=(a-m*1000-h*100)/10;i=a%10;}else{if(a>99){h=a/100;j=(a-h*100)/10;i=a%10;}else{if(a>9){j=a/10;i=a%10;}else{i=a;}}}}if(m!=0){ P11=0; P0=disply[i]; delay(5);P0=0x00;P11=1;P12=0;P0=disply[j];delay(5);P0=0x00;P12=1;P13=0;P0=disply[h];delay(5);P0=0x00;P13=1;P14=0;P0=disply[m]; delay(5);P14=1;P0=0x00;}else { if(h!=0){P11=0; P0=disply[i]; delay(5);P0=0x00;P11=1;P12=0;P0=disply[j]; /*判断要显示的数字是几位数*/delay(5);P0=0x00;P12=1;P13=0;P0=disply[h]; delay(5);P0=0x00;P13=1;}else{if(j!=0){P11=0;P0=disply[i];delay(5);P0=0x00;P11=1;P12=0;P0=disply[j]; delay(5);P0=0x00;P12=1;}else{P11=0;P0= P0=disply[i];}}}}}void main(){BYTE k=0; /*用来判断是给a还是b赋值*/P2=0xf0;a=0; /*第一次按键值的初始化*/b=0; /*第二次按键值的初始化*/bat:show();delay(10 );get_jianzhi() ;P2=0xf0;if(jh==15) /*按了清除键的话,全部清零*/ {a=0;b=0;c=0;}else{if(jh>=0&&jh<=9) /*按了数字键*/{if(k==0) /*判断是给a还是b赋值*/{a=a*10+jh;}else{b=b*10+jh;}goto bat;}else{if(a==0&&b==0) /*在开始时只按功能键的话,返回*/{goto bat;}else{k=1;if(b==0){c=jh;}else{switch(c) /*运算法则*/{case 10: { a=a+b;break;}case 11: {a=a-b;break;}case 12: {a=a*b;break;}case 13: {a=a/b;break;}case 15:{ break; } /*按'='的话,不运算*/}c=jh;}goto bat;}}goto bat;}}。

C51计算器程序

C51计算器程序

#include <reg51.h>#include <intrins.h>#include <stdio.h>#include <stdlib.h>unsigned char code Error[]={"error"};unsigned char code Systemerror[]={"system error"};unsigned char code Lcd[]={"lcd calculate"};char str[16];sbit RS=P2^0;sbit RW=P2^1;sbit E=P2^2;sbit BF=P0^7;/***********************函数功能:延时1ms***********************/void delay1ms(){unsigned char i,j;for (i=0;i<10;i++)for (j=0;j<33;j++);}/************************函数功能:延时n毫秒入口参数:n************************/void delaynms(unsigned char n){unsigned char i;for (i=0;i<n;i++)delay1ms();}/************************************函数功能:判断液晶模块的忙碌状态返回值:result。

result=1,忙碌;result=0,不忙。

************************************/bit BusyTest(void){bit result;RS=0; //根据规定,RS为低电平、RW为高电平时,可以读状态RW=1;E=1; //E=1,才允许读/写_nop_();_nop_();_nop_();_nop_();result=BF; //将忙碌标志电平赋给resultE=0;return result;}/*************************************函数功能:将模式设置指令或显示地址写入液晶模块入口参数:dictate**************************************/void WriteInstruction(unsigned char dictate){while(BusyTest()==1); //如果忙就等待RS=0; //根据规定,RS和R/W同为低电平时,可以写入指令RW=0;E=0;_nop_();_nop_();P0=dictate; //将数据送入P0口,即写入指令或地址_nop_();_nop_();_nop_();_nop_();E=1; //E置高电平_nop_();_nop_();_nop_();_nop_();E=0;}/*****************************************函数功能:指定字符显示的实际地址入口参数:x,y*****************************************/void WriteAddress(unsigned char x,unsigned char y){unsigned char temp;if(x==0){switch(y){case 0:temp=0x00; break;case 1:temp=0x01; break;case 2:temp=0x02;break;case 3:temp=0x03;break;case 4:temp=0x04;break;case 5:temp=0x05;break;case 6:temp=0x06;break;case 7:temp=0x07;break;case 8:temp=0x08;break;case 9:temp=0x09;break;case 10:temp=0x0a;break;case 11:temp=0x0b;break;case 12:temp=0x0c;break;case 13:temp=0x0d;break;case 14:temp=0x0e;break;case 15:temp=0x0f;break;}}if(x==1){switch(y){case 0:temp=0x40;break;case 1:temp=0x41;break;case 2:temp=0x42;break;case 3:temp=0x43;break;case 4:temp=0x44;break;case 5:temp=0x45;break;case 6:temp=0x46;break;case 7:temp=0x47;break;case 8:temp=0x48;break;case 9:temp=0x49;break;case 10:temp=0x4a;break;case 11:temp=0x4b;break;case 12:temp=0x4c;break;case 13:temp=0x4d;break;case 14:temp=0x4e;break;case 15:temp=0x4f;break;}}WriteInstruction(temp|0x80); //显示位置的确定方法规定为“80H+地址码x”}/*****************************************函数功能:将数据(字符的标准ASCII码)写入液晶模块入口参数:y*****************************************/void WriteData (unsigned char y){while(BusyTest()==1);RS=1; //RS为高电平,RW为低电平时,可以写入数据RW=0;E=0;P0=y; //将数据送入P0口,即将数据写入液晶模块_nop_();_nop_();_nop_();_nop_();E=1;_nop_();_nop_();_nop_();_nop_();E=0; //当E由高电平跳变成低电平时,液晶模块开始执行指令}/*****************************************函数功能:对LCD的显示模式进行初始化设置*****************************************/void LcdInitiate(void){delaynms(15); //延时15ms,首次写指令时应给LCD一段较长的反应时间WriteInstruction(0x38); //显示模式设置delaynms(5);WriteInstruction(0x38);delaynms(5);WriteInstruction(0x38);delaynms(5);WriteInstruction(0x0c); //显示模式设置:显示开,无光标,光标不闪烁delaynms(5);WriteInstruction(0x06); //显示模式设置:光标右移,字符不移delaynms(5);WriteInstruction(0x01); //清屏幕指令,将以前的显示内容清除delaynms(5);}/***************************************函数功能:显示字符串***************************************/void display_error(){unsigned char i;WriteAddress(0,0);i=0;while(Error[i]!='\0'){WriteData(Error[i]);i++;delaynms(100);}}void display_systemerror(){unsigned char i;WriteAddress(0,0);i=0;while(Systemerror[i]!='\0'){WriteData(Systemerror[i]);i++;delaynms(100);}}void display_lcd(){unsigned char i;WriteAddress(0,0);i=0;while(Lcd[i]!='\0'){WriteData(Lcd[i]);i++;delaynms(100);}}/*************************** 函数功能:按键判断**************************/bit judge(){unsigned char keycode;P1=0x0f;keycode=P1;if(keycode==0x0f)return(0);elsereturn(1);}/*****************************函数功能:键盘扫描*****************************/ unsigned char scan(){unsigned char keycode,keyscan;keyscan=0xef;while(keyscan!=0xff){P1=keyscan;keycode=P1;if((keycode&0x0f)!=0x0f)break;keyscan=(keycode<<1)|0x0f;}keycode=~keycode;return(keycode);}/*******************************函数功能:扫描键盘返回值******************************/ unsigned char Key_Num(){unsigned char keycode;unsigned char yong;if(judge()){delaynms(20);if(judge()){keycode=scan();while(judge());switch(keycode){case 0x11:yong='7';break;case 0x12:yong='4';break;case 0x14:yong='1';break;case 0x18:yong=0;break;case 0x21:yong='8';break;case 0x22:yong='5';break;case 0x24:yong='2';break;case 0x28:yong='0';break;case 0x41:yong='9';break;case 0x42:yong='6';break;case 0x44:yong='3';break;case 0x48:yong='=';break;case 0x81:yong='/';break;case 0x82:yong='*';break;case 0x84:yong='-';break;case 0x88:yong='+';break;default:display_systemerror() ;}return(yong);}}elsereturn(0xff);}/************************************** itoa函数定义*********************************/ unsigned char itoa(long int num){unsigned char i,j,L;unsigned char temp[16];for(i=0;num!=0;i++){temp[i]=num%10+48;num=num/10;}L=i;if(i>16){display_systemerror();}for(j=0;j<=L;j++){str[j]=temp[i];i--;}return(L);}/*****************************************函数功能:主函数****************************************/void main(){long int a;long int b;unsigned char flag;unsigned char sign;unsigned char i,j,s,x;unsigned char num;unsigned char fgh;unsigned char temp[16];LcdInitiate();display_lcd();delaynms(20);WriteInstruction(0x01);flag=1;while(1){num=Key_Num();if(num!=0xff){if(fgh==1){WriteInstruction(0x01);fgh=0;}if((num!='+')&&(num!='-')&&(num!='*')&&(num!='/')&&(num!='.')&&(num!='=')){if(flag==1){a=a*10+num-48;}else{b=num-48+b*10;}}if(num==0){i=0;flag=1;a=0;b=0;WriteInstruction(0x01);}if((num=='+')||(num=='-')||(num=='*')||(num=='/')){flag=0;switch(sign){case '+':a=a+b;break;case '-':a=a-b;break;case '*':a=a*b;break;case '/': {if(b!=0){ a=a/b;break; }else{WriteInstruction(0x01);flag=1;WriteAddress(0,1);display_error();delaynms(40);WriteInstruction(0x01);break;}}default:break;}sign=num;b=0;}if(num=='='){flag=1;switch(sign){case '+':a=a+b;break;case '-':a=a-b;break;case '*':a=a*b;break;case '/':a=a/b;break;default:break;}temp[i]=num;WriteAddress(0,i);WriteData(num);for(s=0;s<16;s++)temp[s]=0;s=0;//WriteAddress(1,8);//WriteData(a+48);x=itoa(a); //函数转换WriteAddress(1,1);while(s<=x){WriteData(str[s]);s++;delaynms(100);}sign=0;a=b=0;j=0;for(s=0;s<16;s++)str[s]=0;s=0;fgh=1;i=0;}if(i<16){if(num!='='){if((i==1)&& (temp[0]=='0') )//如果第一个字符是0,判读第二个字符{temp[0]=num; //如果是1-9数字,说明0没有用,则直接替换第一位0WriteAddress(0,0);//输出数据WriteData(num);}else{temp[i]=num;WriteAddress(0,i);//输出数据WriteData(num);i++; //输入数值累加}}}else{i=0;WriteInstruction(0x01);}}}}。

基于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单片机

C51单片机-整数加减乘除计算器本程序是基于技能大赛设备,所使用的模块为显示模块、主机模块和指令模块。

此计算器适合10位以内的加减乘除运算,除法没有小数位,只取整数位。

此程序仅供参考,可以相互学习使用。

/* ---简易整数计算器--- */#include<reg52.h> //包含AT89s52头文件#define uchar unsigned char#define uint unsigned int#define ulong unsigned long/* ---1602液晶控制引脚--- */sbit rs=P2^0;sbit rw=P2^1;sbit e=P2^2;#define port P0 //1602数据端口#define port3 P3 //矩阵键盘uchar code tab[]="0123456789+-*/=c";ulong a1,a2,aa; //没有小数点的长整型变量uchar jsf; //运算符/* ---微秒延时--- */void delay(uint i){while(i--);}/* ---1602液晶各子函数--- */ void busy1602(){port=0xff;rs=0;rw=1;e=1;e=1;while(port&0x80);e=0;}void writecom(uchar com){busy1602();rs=0;rw=0;port=com;e=1;e=0;}void writedat(uchar dat){busy1602();rs=1;rw=0;port=dat;e=1;e=0;}void showstr(bit row,uchar col,uchar *s) //显示字符串{uchar i;writecom(0x80+row*0x40+col);for(i=0;s[i]!=0;i++){writedat(s[i]);}}void shownum(bit row,uchar col,ulong num) //显示数字{writecom(0x04);writecom(0x80+row*0x40+col);if(num>=0)writedat(num%10+'0');if(num>9)writedat(num/10%10+'0');if(num>99)writedat(num/100%10+'0');if(num>999)writedat(num/1000%10+'0');if(num>9999)writedat(num/10000%10+'0');if(num>99999)writedat(num/100000%10+'0');if(num>999999)writedat(num/1000000%10+'0');if(num>9999999)writedat(num/10000000%10+'0');if(num>99999999)writedat(num/100000000%10+'0');if(num>999999999)writedat(num/1000000000%10+'0');if(num>4294967294)showstr(0,4,"rorrE");}void init1602() //1602 初始化{writecom(0x38);writecom(0x0c);writecom(0x06);writecom(0x01);/* ---按键扫描程序--- */uchar keyscan(){uchar key=16,i;for(i=0;i<4;i++){port3=0xfe<<i|0xfe>>(8-i); //循环左移switch(port3&0xf0){case 0xe0:key=4*i;break;case 0xd0:key=4*i+1;break;case 0xb0:key=4*i+2;break;case 0x70:key=4*i+3;break;}}return key;}/* ---运算--- */void js()switch(jsf){case '+':aa=a1+a2;break;case '-':if(a1>=a2)aa=a1-a2;else if(a1<a2)aa=a2-a1;break;case '*':aa=a1*a2;break;case '/':if(a2==0)aa=' ';else aa=a1/a2; break;}}void main(){uchar k;bit b=0,a;init1602();showstr(0,3,"jisuanqi");while(1){if(keyscan()!=16&&b==0){delay(200);if(keyscan()!=16){b=1;k=keyscan();if(k==0||k==1||k==2||k==3||k==4||k==5||k==6||k==7||k==8||k= =9) //数字键{if(a==0){a1=a1*10+k;writecom(0x01);shownum(1,15,a1);}else{a2=a2*10+k;writecom(0x01);shownum(1,15,a2);}}else if(k==10||k==11||k==12||k==13) //+-*/键{a=1;writecom(0x01);switch(k){case 10:jsf='+';showstr(1,15,"+");break;case 11:jsf='-';showstr(1,15,"-");break;case 12:jsf='*';showstr(1,15,"*");break;case 13:jsf='/';showstr(1,15,"/");break;}}else if(k==14) //等号键{a=0;js();writecom(0x01);if(aa==' ')showstr(0,0,"Error"); //被除数为零不显示,第一行显示错误else shownum(1,15,aa);if(jsf=='-'&&a1<a2)showstr(1,0,"-"); // aa是负数,前边添加负号else showstr(1,0," ");}else if(k==15) //清零键{a=0;a1=a2=aa=0;jsf=0;writecom(0x01);shownum(1,15,0);}}}else if(keyscan()==16)b=0;}}。

计算器小程序

计算器小程序

计算器51单片机简易计算器程序:#include <reg51.h>#include <math.h>#define uchar unsigned char#define uint unsigned int//---------定义引脚-------------------- bit clr=0;bit ok=0;bit xiaoshu=0;bit jiego=0;bit first_1=1;bit first_2=1;sbit dout = P3^2;sbit load = P2^0;sbit din = P2^1;sbit dclk = P2^2;sbit beer=P0^1;sbit LCD1602_RS=P2^3;sbit LCD1602_RW=P2^4;sbit LCD1602_E=P2^5;//---------定义变量--------------------uchar ch451_key=0xff;uchar yun_sign;uchar xiabiao=0;uchar tab[32];uchar tab1[]={"welcome to use!"};uchar tab2[]={" make by JunRu!"};uchar tab3[]={"ERR0R"};float opr_1=0,opr_temp=0,end=0,a;//---------声明函数--------------------void ch451_init(void); //CH451初始化void ch451_write(uint command);//写命令或数据到ch451uchar ch451_read(void); //读按键值uchar get_char(void);void LCD_init(void);//初始化;void delay(unsigned int k);//延时程序void LCD_inter_command(unsigned char command);//写入控制字void LCD_inter_dat(unsigned char dat);//写入要显示的数据void set_xy(unsigned char x,unsigned char y);//找地址void write(unsigned char date);//写入字符void lcdbusy();//查忙时void display(void);void spec(void);void get_end(void);void hun_he(uchar n);//-------- 主函数----------------------void main(){uchar i;LCD_init();//LCD初始化;ch451_init();//CH451初始化EA = 1;//打开中断LCD_inter_command(0x01);//清屏for(i=0;i<=14;i++){LCD_inter_dat(tab1[i]);beer=0;delay(4000);//延时beer=1;}LCD_inter_command(0xc0);//从第二行开始显示for(i=0;i<=14;i++){LCD_inter_dat(tab2[i]);beer=0;delay(4000);//延时beer=1;}delay(0xffff);delay(0xffff);LCD_inter_command(0x01);while(1){if(ok){display();ok=0;clr=1;}}}//----------子函数--------------------void hun_he(uchar n){int j;switch(n){case '+':opr_temp=opr_temp+opr_1;break;case '-':opr_temp=opr_temp-opr_1;break;case '*':opr_temp=opr_temp*opr_1;break; case '/':{if(a==0)//减数为零显错{ LCD_inter_command(0xc0);for(j=0;j<=4;j++){LCD_inter_dat(tab3[j]);beer=0;delay(4000);//延时beer=1;}}else{opr_temp=opr_temp/opr_1;}break;}default:break;}}void ch451_init(void)//CH451初始化{EX0 = 1;din = 1;ch451_write(0x403); //开显示ch451_write(0x580); //BCD译码方式}void ch451_write(uint command)//写命令或数据到ch451 { uchar i;EX0 = 0;load = 0;for(i=0;i<12;i++){din = command&1;dclk = 0;command>>=1;dclk = 1;}load = 1;EX0 = 1;}uchar ch451_read(void)//读按键值{ uchar key=0x07;uchar i;load = 0;for(i=0;i<4;i++) //将0111读入{din = key &1;dclk = 0;key>>=1;dclk =1;}load = 1;key = 0;for(i=0;i<7;i++) //从CH451读出按键值 {key<<=1;key|= dout;dclk =0;dclk =1;}EX0 =1;return key;}void EX0_ISR(void)interrupt 0 //中断程序{uchar temp;ch451_key=ch451_read(); //将读出的按键值赋给变量spec();if(clr) {LCD_inter_command(0x01);clr=0;}temp=get_char();if(temp){tab[xiabiao++]=temp; LCD_inter_dat(temp);}if(xiabiao>=16)LCD_inter_command(0xc0);//若大于16,则从第2行开始显示if(ok) get_end();beer=0;delay(3000);beer=1;}uchar get_char(void){uchar dis=0;uint temp=0,temp1=0;switch(ch451_key){case 0x40:dis='1';break;case 0x41:dis='2';break;case 0x42:dis='3';break;case 0x48:dis='4';break;case 0x49:dis='5';break;case 0x4A:dis='6';break;case 0x50:dis='7';break;case 0x51:dis='8';break;case 0x52:dis='9';break;case 0x58:dis='0';break;case 0x43:dis='+';break;case 0x4B:dis='-';break;case 0x53:dis='x';break;case 0x5B:dis='/';break;case 0x44:dis='!';break;case 0x5A:dis='=';ok=1; //遇到“=”,开始运算 break;case 0x59:dis='.';break; //小数点case 0x5C: //删除键LCD_inter_command(0x01);xiabiao=0;break;default: break;}return dis;}void spec(void) //特殊功能键{switch(ch451_key){case 0x4C:LCD_inter_command(0x10);{if(xiabiao>0)xiabiao-=1;}break; //左移case 0x54:LCD_inter_command(0x14);{xiabiao+=1;}break; //右移default:break;}}void delay(unsigned int k)//延时程序{while (k--);}void LCD_inter_command(unsigned char command)//写入控制字{delay(5000);LCD1602_RS=0;LCD1602_RW=0;LCD1602_E=1;P1=command;LCD1602_E=0;lcdbusy();}void LCD_init(void)//初始化;{delay(5000);LCD_inter_command(0x01);//清屏delay(5000);LCD_inter_command(0x38);//设置为8位的数据接口,两行显示,5、7点字符delay(5000);LCD_inter_command(0x0E);//显示打开,光标开并闪烁delay(5000);}void LCD_inter_dat(unsigned char dat)//写入要显示的数据{delay(5000);LCD1602_RS=1;LCD1602_RW=0;LCD1602_E=1;P1=dat;LCD1602_E=0;lcdbusy();}void lcdbusy()//查忙{P1=0xFF;LCD1602_RS=0;LCD1602_RW=1;LCD1602_E=1;while((P1&0x80)==1);}void display(void) //转化在LCD上显示计算结果{int temp=end; //浮点数int i;uint xiao_temp;uint xx; //浮点数的整数部分if (end>-32769&&end<32768){xx=fabs(end);xiao_temp=(fabs(end)-xx)*1000;//取出浮点数的小数部分 LCD_inter_command(0xc0);if(end<0) LCD_inter_dat('-');beer=0;delay(4000); beer=1;//判断是否为负数,若是则显示负号if(xx>9999) LCD_inter_dat((xx/10000)%10+'0'); beer=0;delay(4000);beer=1;if(xx>999) LCD_inter_dat((xx/1000)%10+'0');beer=0;delay(4000);beer=1; //在LCD上显示千位的数if(xx>99)LCD_inter_dat((xx/100)%10+'0'); beer=0;delay(4000);beer=1;//百位if(xx>9)LCD_inter_dat((xx/10)%10+'0');beer=0;delay(4000); beer=1;//十位LCD_inter_dat(xx%10+'0');beer=0;delay(4000); beer=1;//个位if(xiao_temp!=0) //显示小数部分{LCD_inter_dat('.');beer=0;delay(4000);beer=1;LCD_inter_dat((xiao_temp/100)%10+'0');beer=0;delay(4000);beer=1;LCD_inter_dat((xiao_temp/10)%10+'0');beer=0;delay(4000);beer=1;LCD_inter_dat(xiao_temp%10+'0');beer=0;delay(4000);beer=1;}}else {LCD_inter_command(0xc0);//从第二行开始显示for(i=0;i<=4;i++){ LCD_inter_dat(tab3[i]);beer=0;delay(4000);//延时beer=1;}}}void get_end(void)//计算子程序{ float xiaoshu=1;uchar fu_flag=0;uchar xiao_flag=0;uchar lianji_sign;uchar i=0;uchar j;uchar n;//正负标记符while(i<=xiabiao){while(tab[i]<=0x39&&tab[i]>=0x30){n=0;opr_1*=10;opr_1+=tab[i++]-0x30;n='+';}switch(tab[i]){case '.': xiao_flag=1;break;//遇到小数点跳到“if(xiao_flag)”里case '!': fu_flag=1;break;case '+': xiaoshu=1;yun_sign='+';if(opr_temp==0){end=opr_temp=opr_1;}el se hun_he(lianji_sign);opr_1=0;lianji_sign='+'; break;case '-': xiaoshu=1;yun_sign='-';if(opr_temp==0){end=opr_temp=opr_1;}else hun_he(lianji_sign);opr_1=0;lian ji_sign='-'; break;case 'x': xiaoshu=1;yun_sign='x';if(opr_temp==0){end=opr_temp=opr_1;}els e hun_he(lianji_sign);opr_1=0;lianji_sign='*';break;case '/': xiaoshu=1;yun_sign='/';if(opr_temp==0){end=opr_temp=opr_1;}els e hun_he(lianji_sign);a=opr_1;opr_1=0;lianji_sign='/';break;case '=':switch(yun_sign)//进行运算{case '+':end=opr_temp+opr_1;break;case '-':end=opr_temp-opr_1;break;case 'x':end=opr_temp*opr_1;break;case '/':{if(a==0)//减数为零显错{ LCD_inter_command(0xc0);for(j=0;j<=4;j++){LCD_inter_dat(tab3[j]);beer=0;delay(4000);//延时beer=1;}}else{end=opr_temp/opr_1;}break;}default:break;}ok=1;//开始进行显示,标志位置1 xiabiao=0;//小数的标志位清零break;default:break;}i++;if(xiao_flag)//表示小数{while(tab[i]<=0x39&&tab[i]>=0x30) {xiaoshu*=0.1;switch(n){case '+': opr_1=opr_1+(tab[i++]-0x30)*xiaoshu;break; case '-': opr_1=opr_1-(tab[i++]-0x30)*xiaoshu; break ; default:break; }xiao_flag=0;}}if(fu_flag){while(tab[i]<=0x39&&tab[i]>=0x30){n=0;opr_1=-opr_1*10;opr_1=-(opr_1+(tab[i++]-0x30));n='-';fu_flag=0;}}}opr_1=0;opr_temp=0;xiabiao=0;xiaoshu=1; }。

做一个计算器_用51单片机做一个简单的计算器小程序

做一个计算器_用51单片机做一个简单的计算器小程序

做⼀个计算器_⽤51单⽚机做⼀个简单的计算器⼩程序⼀:硬件仿真图分别为8位数码管和4位数码管注意:本仿真案例有偿提供,请点击⽂章最下⽅的阅读原⽂,查看仿真图和程序下载地址。

本仿真仅供参考,如有需要修改电路和程序,请联系管理员有偿修改。

当然,如果你动⼿能⼒强,完全可以按照本⽂提供的电路图和程序源码⾃⾏搭建。

硬件部分⽐较简单,当键盘按键按下时它的那⼀⾏、那⼀列的端⼝为低电平。

因此,只要扫描⾏、列端⼝是否都为低电平就可以确定是哪个键被按下。

本计算器是以80C51单⽚机为核⼼构成的简易计算器系统。

该系统通过单⽚机控制,实现对4*4键盘扫描进⾏实时的按键检测,并把检测数据和计算结果存储下来,显⽰在LED数码管上,并可实现清零。

整个系统主要可分为四个主要功能模块:功能模块⼀:实时键盘扫描;功能模块四:清零整个计算器系统的⼯作过程为:⾸先初始化参数,送LED低位显⽰“0”,功能键位不显⽰。

然后扫描键盘看是否有键输⼊,若有,读取键码。

判断键码是数字键、清零键还是“+” 、“—” 、“*” “/” ,是数值键则送LED显⽰并保存数值,是清零键则做清零处理,是功能键则⼜判断是“=”、清零、还是运算键,若是“=”则计算最后结果并送LED显⽰,若是运算键则保存相对运算程序的⾸地址,若是清零键则跳转回初始化阶段使所有值清零。

⼆、主程序流程图程序的主要思想是:将按键抽象为字符,然后就是对字符的处理。

将操作数分别转化为字符串存储,操作符存储为字符形式。

然后调⽤compute()函数进⾏计算并返回结果。

具体程序及看注释还有流程图。

三:键盘扫描程序流程图四:显⽰程序流程图五:程序源码#include#include /* isdigit()函数 */#include /* atoi()函数 */#define uchar unsigned char#define uint unsigned intuchar operand1[9], operand2[9]; /* 操作数 */uchar operator; /* 操作符 */void delay(uint);uchar keyscan();void disp(void);void buf(uint value);uint compute(uint va1,uint va2,uchar optor);uchar code table[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff}; /* 字符码表 */uchar dbuf[8] = {10,10,10,10,10,10,10,10}; /* 显⽰缓存 */ /* 延时函数 */void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}/*******************************************键盘扫描程序将按键转化为字符并作为输出'$','#'分别表⽰清零键和没有键按下*******************************************/uchar keyscan(){uchar skey; /* 按键值标记变量 *//***********************扫描键盘第1⾏while((P1 & 0xf0) != 0xf0) /* 有按键按下 */ {delay(3); /* 去抖动延时 */while((P1 & 0xf0) != 0xf0) /* 仍有键按下 */{switch(P1) /* 识别按键并赋值 */{case 0xee: skey = '7'; break;case 0xde: skey = '8'; break;case 0xbe: skey = '9'; break;case 0x7e: skey = '/'; break;default: skey = '#';}while((P1 & 0xf0) != 0xf0) /* 等待按键松开 */;}}/***********************扫描键盘第2⾏************************/P1 = 0xfd;while((P1 & 0xf0) != 0xf0){delay(3);while((P1 & 0xf0) != 0xf0){switch(P1){case 0xed: skey = '4'; break;case 0xdd: skey = '5'; break;case 0xbd: skey = '6'; break;case 0x7d: skey = '*'; break;while((P1 & 0xf0) != 0xf0) ;}}/***********************扫描键盘第3⾏************************/P1 = 0xfb;while((P1 & 0xf0) != 0xf0) {delay(3);while((P1 & 0xf0) != 0xf0) {switch(P1){case 0xeb: skey = '1'; break; case 0xdb: skey = '2'; break; case 0xbb: skey = '3'; break; case 0x7b: skey = '-'; break; default: skey = '#';}while((P1 & 0xf0) != 0xf0) ;}}/***********************扫描键盘第4⾏************************/P1 = 0xf7;while((P1 & 0xf0) != 0xf0) {delay(3);{case 0xe7: skey = '$'; break;case 0xd7: skey = '0'; break;case 0xb7: skey = '='; break;case 0x77: skey = '+'; break;default: skey = '#';}while((P1 & 0xf0) != 0xf0);}}return skey;}void main(){uint value1, value2, value; /* 数值1,数值2,结果 */uchar ckey, cut1 = 0, cut2 = 0; /* ckey键盘输⼊字符 */ uchar operator; /* 运算符 */uchar i, bool = 0;init: /* goto语句定位标签 */buf(0); /* 初始化 */disp();value = 0;cut1 = cut2 = 0;bool = 0;for(i = 0;i < 9;i++){operand1[i] = '\0';operand2[i] = '\0';} /* 初始化 */while(1){ /* isdigit函数,字符是阿拉伯数字返回⾮0值,否则返回0 */if(isdigit(ckey)){switch(bool){case 0:operand1[cut1] = ckey;operand1[cut1+1] = '\0';value1 = atoi(operand1); /* atoi函数,将字符串转化为,int整数 */ cut1++;buf(value1);disp();break;case 1:operand2[cut2] = ckey;operand2[cut2+1] = '\0';value2 = atoi(operand2);cut2++;buf(value2);disp();break;default: break;}}else if(ckey=='+'||ckey=='-'||ckey=='*'||ckey=='/'){bool = 1;operator = ckey;buf(0);dbuf[7] = 10;disp();{value = compute(value1,value2,operator);buf(value);disp();while(1) /* 计算结束等待清零键按下 */ {ckey = keyscan();if(ckey == '$') /* 如果有清零键按下跳转到开始 */ goto init;else{buf(value);disp();}}}else if(ckey == '$'){ goto init;}}disp();}}/******************************************运算函数输⼊:操作数和操作符输出:计算结果*******************************************/uint compute(uint va1,uint va2,uchar optor){uint value;switch(optor){case '*' : value = va1*va2; break; case '/' : value = va1/va2; break; default : break;}return value;}/******************************************* 更新显⽰缓存输⼊:⽆符号整数输出:将输⼊送⼊显⽰缓存*******************************************/ void buf(uint val){uchar i;if(val == 0){dbuf[7] = 0;i = 6;}elsefor(i = 7; val > 0; i--){dbuf[i] = val % 10;val /= 10;}for( ; i > 0; i--)dbuf[i] = 10;}/******************************************* 显⽰函数*******************************************/ void disp(void)bsel=0x01;for(n=0;n<8;n++) {P2=bsel;P0=table[dbuf[n]]; bsel=_crol_(bsel,1); delay(3);P0=0xff;}}。

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

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

赣南师范大学基于C51单片机的简易计算器学院:物理与电子信息学院专业: 电子信息工程班级:学名:学号:指导教师:日期:目录1. 绪论 (3)2。

系统软件设计方案 (4)2。

1设计目标和实现方法 (4)2.2整体方案论证 (4)3. 系统硬件的设计与介绍 (5)3.1复位电路的设计与运用 (5)3。

2时钟振荡器电路的设计与运用 (6)3.3输入电路的设计 (6)3.4输出电路的设计 (8)4。

系统程序的设计与介绍 (11)4。

1 LED显示程序流程图设计 (11)4.2读键输入程序流程图设计 (13)4。

3主程序流程图设计 (14)4.4仿真与调试 (15)5. 结论 .................................................... . (17)元件清单 (18)附录1简易计算器源程序 (19)1.绪论中国古代最早采用的一种计算工具叫筹策,又被叫做算筹。

这种算筹多是用竹子制成,也有用木头,兽骨充当材料的。

大约二百七十枚一束,放在布袋里可以随身携带。

直到今天仍在使用的珠算盘,是中国古代计算工具领域中的另一项发明,明代时期的珠算盘已经与现代的珠算盘几乎没有差别.17世纪初,西方国家的计算工具已经有了较大的发展,英国数学家纳皮尔发明的”纳皮尔算筹”,英国牧师奥却德发明了圆柱型对数计算尺,这种计算尺不仅能做加减乘除、乘方、开方运算,甚至可以计算三角函数,指数函数和对数函数,这些计算工具不仅带动了计算器的快速发展,也为实现现代计算器发展奠定了良好的基础,成为现代社会应用广泛的计算工具.1642年,年仅19岁的法国伟大科学家帕斯卡引用算盘的原理,发明了世界上第一部机械式计算器,在他的计算器中有一些互相联锁的齿轮,一个转过十位的齿轮会使另一个齿轮转过一位,人们可以像拨电话号码盘那样,把数字拨进去,计算结果就会出现在另外一个窗口中,但是只能做加减计算。

1694年,莱布尼兹在德国将其改进成可以进行乘除的计算.此后,一直要到20世纪50年代末才有了电子计算器的出现。

整数加减乘除计算器-C51单片机

整数加减乘除计算器-C51单片机

整数加减乘除计算器-C51单片机C51单片机-整数加减乘除计算器本程序是基于技能大赛设备,所使用的模块为显示模块、主机模块和指令模块。

此计算器适合10位以内的加减乘除运算,除法没有小数位,只取整数位。

此程序仅供参考,可以相互学习使用。

/* ---简易整数计算器--- */#include //包含AT89s52头文件#define uchar unsigned char#define uint unsigned int#define ulong unsigned long/* ---1602液晶控制引脚--- */sbit rs=P2^0;sbit rw=P2^1;sbit e=P2^2;#define port P0 //1602数据端口#define port3 P3 //矩阵键盘uchar code tab[]="0123456789+-*/=c";ulong a1,a2,aa; //没有小数点的长整型变量uchar jsf; //运算符/* ---微秒延时--- */void delay(uint i){while(i--);}/* ---1602液晶各子函数--- */ void busy1602(){port=0xff;rs=0;rw=1;e=1;e=1;while(port&0x80);e=0;}void writecom(uchar com){busy1602();rs=0;rw=0;port=com;e=1;e=0;}void writedat(uchar dat){busy1602();rs=1;rw=0;port=dat;e=1;e=0;}void showstr(bit row,uchar col,uchar *s) //显示字符串{ uchar i;writecom(0x80+row*0x40+col);for(i=0;s[i]!=0;i++){writedat(s[i]);}}void shownum(bit row,uchar col,ulong num) //显示数字{ writecom(0x04);writecom(0x80+row*0x40+col);if(num>=0)writedat(num%10+'0');if(num>9)writedat(num/10%10+'0');if(num>99)writedat(num/100%10+'0');if(num>999)writedat(num/1000%10+'0');if(num>9999)writedat(num/10000%10+'0');if(num>99999)writedat(num/100000%10+'0');if(num>999999)writedat(num/1000000%10+'0');if(num>9999999)writedat(num/10000000%10+'0');if(num>99999999)writedat(num/100000000%10+'0'); if(num>999999999)writedat(num/1000000000%10+'0'); if(num>4294967294)showstr(0,4,"rorrE");}void init1602() //1602 初始化{writecom(0x38);writecom(0x0c);writecom(0x06);writecom(0x01);/* ---按键扫描程序--- */uchar keyscan(){uchar key=16,i;for(i=0;i<4;i++){port3=0xfe<>(8-i); //循环左移switch(port3&0xf0){case 0xe0:key=4*i;break;case 0xd0:key=4*i+1;break; case 0xb0:key=4*i+2;break; case 0x70:key=4*i+3;break; }}return key;}/* ---运算--- */void js()switch(jsf){case '+':aa=a1+a2;break; case '-':if(a1>=a2)aa=a1-a2; else if(a1< p="">break;case '*':aa=a1*a2;break; case '/':if(a2==0)aa=' '; else aa=a1/a2; break;}}void main(){uchar k;bit b=0,a;init1602();showstr(0,3,"jisuanqi"); while(1){if(keyscan()!=16&&b==0) {delay(200);if(keyscan()!=16){b=1;k=keyscan();if(k==0||k==1||k==2||k==3||k==4||k==5||k==6||k==7||k== 8||k= =9) //数字键{if(a==0){a1=a1*10+k;writecom(0x01);shownum(1,15,a1);}else{a2=a2*10+k;writecom(0x01);shownum(1,15,a2);}}else if(k==10||k==11||k==12||k==13) //+-*/键{a=1;writecom(0x01);switch(k){case 10:jsf='+';showstr(1,15,"+");break;case 11:jsf='-';showstr(1,15,"-");break;case 12:jsf='*';showstr(1,15,"*");break;case 13:jsf='/';showstr(1,15,"/");break;}}else if(k==14) //等号键{a=0;js();writecom(0x01);if(aa==' ')showstr(0,0,"Error"); //被除数为零不显示,第一行显示错误else shownum(1,15,aa);if(jsf=='-'&&a1<="" p="">else showstr(1,0," ");}else if(k==15) //清零键{a=0;a1=a2=aa=0;jsf=0;writecom(0x01);shownum(1,15,0);}}}else if(keyscan()==16)b=0;}}<>。

51单片机实现计算器程序

51单片机实现计算器程序

#include <reg52.h>#include <intrins.h>#include <math.h>#define uchar unsigned char#define uint unsigned intsbit LCD_RS=P2^2;//数据和命令端sbit LCD_EN=P2^0;//使能端sbit LCD_RW=P2^1;sbit CS1=P2^4;sbit CS2=P2^3;uint keytime,keyno[10];uint result,date1,date2,w_date1,w_date2;uint KeyNO1,opercha;uint date10n;uint date10n_d[16];uchar code hz[]={/*-- 文字: 数--*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x10,0x92,0x54,0x38,0xFF,0x38,0x54,0x52,0x80,0xF0,0x1F,0x12,0x10,0xF0,0x10,0x00,0x42,0x42,0x2A,0x2E,0x13,0x1A,0x26,0x02,0x40,0x20,0x13,0x0C,0x33,0x60,0x20,0x00,/*-- 文字: 据--*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x08,0x08,0x08,0xFF,0x88,0x40,0xFE,0x92,0x92,0x92,0xF2,0x92,0x92,0x9E,0x80,0x00,0x02,0x42,0x81,0x7F,0x40,0x30,0x0F,0xFC,0x44,0x44,0x47,0x44,0x44,0xFC,0x00,0x00,/*-- 文字: 结--*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x20,0x30,0xAC,0x63,0x10,0x00,0x08,0x48,0x48,0x48,0x7F,0x48,0x48,0x48,0x08,0x00,0x22,0x23,0x22,0x12,0x12,0x00,0x00,0x7E,0x22,0x22,0x22,0x22,0x22,0x7E,0x00,0x00,/*-- 文字: 果--*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x00,0x00,0x00,0x3E,0x2A,0x2A,0x2A,0xFE,0x2A,0x2A,0x2A,0x3E,0x00,0x00,0x00,0x00,0x21,0x21,0x11,0x11,0x09,0x05,0x03,0xFF,0x03,0x05,0x09,0x09,0x11,0x31,0x11,0x00};uchar code sz[]={0x00,0x00,0xF0,0xF8,0x08,0x68,0xF8,0xF0,0x00,0x00,0x07,0x0F,0x0B,0x08,0x0F,0x07, //0 0x00,0x20,0x20,0x30,0xF8,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00, //1 0x00,0x30,0x38,0x08,0x88,0xF8,0x70,0x00,0x00,0x0C,0x0E,0x0B,0x09,0x08,0x08,0x00, //2 0x00,0x30,0x38,0x88,0x88,0xF8,0x70,0x00,0x00,0x06,0x0E,0x08,0x08,0x0F,0x07,0x00, //3 0x00,0x00,0xF8,0xF8,0x00,0xE0,0xE0,0x00,0x00,0x03,0x03,0x02,0x02,0x0F,0x0F,0x02, //4 0x00,0xF8,0xF8,0x88,0x88,0x88,0x08,0x00,0x00,0x08,0x08,0x08,0x0C,0x07,0x03,0x00, //5 0x00,0xC0,0xE0,0x78,0x58,0xC8,0x80,0x00,0x00,0x07,0x0F,0x08,0x08,0x0F,0x07,0x00, //6 0x00,0x08,0x08,0x88,0xE8,0x78,0x18,0x00,0x00,0x00,0x0E,0x0F,0x01,0x00,0x00,0x00, //7 0x00,0x70,0xF8,0xC8,0x88,0xF8,0x70,0x00,0x00,0x07,0x0F,0x08,0x09,0x0F,0x07,0x00, //8 0x00,0xF0,0xF8,0x08,0x08,0xF8,0xF0,0x00,0x00,0x00,0x09,0x0D,0x0F,0x03,0x01,0x00, //90x00,0x00,0x00,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x0C,0x0C,0x0C,0x00,0x00, //: 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x0C,0x0C,0x00,0x00//.};/*******************************名称:delay()输入:延时数输出: 无功能:延时********************************/void delay(uint x){int y,z;for(y=x;y>0;y--)for (z=120;z>0;z--);}void write_c(uchar c) //写指令端{LCD_RW=0;LCD_RS=0;LCD_EN=1;P0=c;LCD_EN=0;delay(1);LCD_EN=1;}void write_d(uchar d)//写数据{LCD_RW=0;LCD_RS=1;LCD_EN=1;P0=d;LCD_EN=0;delay(1);LCD_EN=1;}void pianxuan(screen) //片选{switch(screen){case 0:CS1=0;CS2=0;break;case 1:CS1=1;CS2=0;break;case 2:CS1=0;CS2=1;break;case 3:CS1=1;CS2=1;break;}}void qinping(screen)//清屏,从第一行第一列开始{uint x,y; //页的设置位pianxuan(screen);//选择哪个清屏for(x=0xb8;x<0xc0;x++){write_c(x);//页初始值为0XB8到0xc0共八页write_c(0x40);//列的初始地址为0x40,共64列for(y=0;y<64;y++){write_d(0x00);//选择全部清屏}}}/*LCD显示汉字字库函数*/void lcd_display_hanzi(uchar screen,uchar page,uchar lie,uint mun) //screen:选择屏幕参数,page:选择页参数0-3,lie列参数0-3,mun:显示第几个汉字的参数{int i; //page页其实就是行,是行计数器页指针共九位计数器,高三位为X,低六位为Ymun=mun*32;pianxuan(screen) ; //片选看哪个段write_c(0x40+(lie*16)); //一个汉字占用两个字节write_c(0xb8+(page*2)); //一个字节显示for ( i=0;i<16;i++){write_d(hz[mun++]);}write_c(0x40+(lie*16));write_c(0xb8+(page*2)+1);for (i=0;i<16;i++){write_d(hz[mun++]);}}void lcd_display_shuzi(uchar screen,uchar page,uchar lie,uint mun) //screen:选择屏幕参数,page:选择页参数0-3,lie列参数0-3,mun:显示第几个汉字的参数{int i; //page页其实就是行,是行计数器页指针共九位计数器,高三位为X,低六位为Ymun=mun*16;pianxuan(screen) ; //片选看哪个段write_c(0x40+(lie*8)); //一个汉字占用两个字节write_c(0xb8+(page*2)); //一个字节显示for ( i=0;i<8;i++){write_d(sz[mun++]);}write_c(0x40+(lie*8));write_c(0xb8+(page*2)+1);for (i=0;i<8;i++){write_d(sz[mun++]);}}void LCD_init(){write_c(0x3f);// 显示开启write_c(0xc0); //显示起始行,从第一位开始,从0到63 write_c(0xb8);// 设置页得地址从0到7write_c(0x40); //设置列的地址,从第一位开始,从0到63 }/*******************************名称:GET_key()输入:无输出: 按键的相应数目功能:扫描按键********************************/uchar GET_key(){uchar Tmp,KeyNO;P1 = 0xf0;delay(1);Tmp = P1;switch(Tmp){case 0xe0: KeyNO = 3; break;case 0xd0: KeyNO = 2; break;case 0xb0: KeyNO = 1; break;case 0x70: KeyNO = 0;}P1 = 0x0f;delay(1);Tmp = P1;switch(Tmp){case 0x0e: KeyNO+= 12; break;case 0x0d: KeyNO+= 8; break;case 0x0b: KeyNO+= 4; break;case 0x07: KeyNO+= 0; break;default: break;}return(KeyNO);}void write_key(){uchar i,j,m,n;m = 7;n = 7;KeyNO1 = GET_key();if (KeyNO1>=0 && KeyNO1<=9){keytime++;}if (KeyNO1>=10 && KeyNO1<=13){/* keytime= keytime-1;for (j=keytime; j>=0;j--){if ((keytime-j) == 0)w_date1=keyno[keytime];else{for (k=0; k<keytime-j; k++){w_date1=keyno[keytime--]*10;}}date1=date1+w_date1;}*/keytime = 0;opercha = KeyNO1;}if (!(opercha>=10 && opercha<=13)){date1=0;if ((keytime-1) < 10 ){keyno[keytime-1] = KeyNO1;if (keytime-1>=0 && keytime-1 <= 7){for (i=keytime; i>0; i--){lcd_display_shuzi(1,0,m,keyno[i-1]);m--;if ((keytime-i) == 0){w_date1=keyno[i-1];}else{for (j=0; j<keytime-i; j++){w_date1=keyno[i-1]*10;}}date1=date1+w_date1;}}else{for (i=keytime-8; i>0; i--){lcd_display_shuzi(2,0,n,keyno[i-1]);n--;for (j=0; j<keytime-i; j++){w_date1=keyno[i-1]*10;}date1=date1+w_date1;}m=7;for (i=keytime; i>keytime-8; i--){lcd_display_shuzi(1,0,m,keyno[i-1]);m--;if ((keytime-i) == 0)w_date1=keyno[i-1];else{for (j=0; j<keytime-i; j++){w_date1=keyno[i-1]*10;}}date1=date1+w_date1;}}}}if ( (opercha>=10 && opercha<=13) && (KeyNO1 != 14) ) {date2=0;if ((keytime-1)<10 && (keytime-1)>=0){keyno[keytime-1] = KeyNO1;if (keytime-1 <= 7){for (i=keytime; i>0; i--){lcd_display_shuzi(1,1,m,keyno[i-1]);m--;if ((keytime-i) == 0)w_date2=keyno[i-1];else{for (j=0; j<keytime-i; j++){w_date2=keyno[i-1]*10;}}date2=date2+w_date2;}}else{for (i=keytime-8; i>0; i--){lcd_display_shuzi(2,1,n,keyno[i-1]);n--;for (j=0; j<keytime-i; j++){w_date1=keyno[i-1]*10;}date2=date2+w_date2;}m=7;for (i=keytime; i>keytime-8; i--){lcd_display_shuzi(1,1,m,keyno[i-1]);m--;if ((keytime-i) == 0)w_date2=keyno[i-1];else{for (j=0; j<keytime-i; j++){w_date2=keyno[i-1]*10;}}date2=date2+w_date2;}}}}/*if (KeyNO1 == 15){keytime= keytime-1;for (j=keytime; j>=0;j--){if ((keytime-j) == 0)w_date2=keyno[keytime];else{for (i=0; i<keytime-j; i++){w_date2=keyno[keytime--]*10;}}date2=date2+w_date2;}} */if (opercha>=10 && opercha<=13){m=7;if (KeyNO1 == 14){switch(opercha){case 10:result=date1+date2;break;case 11:result=date1-date2;break;case 12:result=date1*date2;break;case 13:result=date1/date2;break;default:break;}for (i=1; ;i++){date10n=1;for (j=0; j<i-1; j++){date10n=date10n*10;}date10n_d[i-1]=(result / date10n) % 10;if (date10n*10>result){j=i;break;}}P3=result / date10n;for (i=0;i<j;i++){lcd_display_shuzi(1,2,m,date10n_d[i]);m--;}/* lcd_display_shuzi(1,2,7,result);P3 =opercha; */}}}void main(){keytime=0;date1=0;date2=0;w_date1=0;w_date2=0;result=0;opercha=0;KeyNO1=16;date10n=1;LCD_init();qinping(0);lcd_display_hanzi(2,0,0,0); //LCD显示汉字"数" //screen:选择屏幕参数,page:选择页参数0-3,lie列参数0-3,mun:显示第几个汉字的参数lcd_display_hanzi(2,0,1,1); //LCD显示汉字"据"lcd_display_shuzi(2,0,4,1); //LCD显示数字"1"lcd_display_shuzi(2,0,5,10);//LCD显示符号":"lcd_display_hanzi(2,1,0,0); //LCD显示汉字"数"lcd_display_hanzi(2,1,1,1); //LCD显示汉字"据"lcd_display_shuzi(2,1,4,2); //LCD显示数字"2"lcd_display_shuzi(2,1,5,10);//LCD显示符号":"lcd_display_hanzi(2,2,0,2); //LCD显示汉字"结"lcd_display_hanzi(2,2,1,3); //LCD显示汉字"果"lcd_display_shuzi(2,2,4,10);//LCD显示符号":"while(1){P1 = 0x0f;if (P1 != 0x0f){delay(1);if (P1 != 0x0f){write_key();while (P1 != 0x0f);}}}}。

16键计算器c51实现

16键计算器c51实现

16键计算器 c51实现1、定时显示开辟一显示缓冲区,显示中断程序定时读取缓冲区显示各灯位,每灯位显示2.5ms,显示4只灯需要10ms,也就是显示的刷新频率是100Hz,亮度为25%。

这样既保证亮度又不闪烁,同时CPU还有足够时间做其他事情。

2、键盘中断扫描利用键盘中断扫描程序,读出按键的键码,存入键盘缓冲区,供主程序读区。

3、计算器的主程序读取键盘缓冲区的键码,驱动计算器的运行,计算器的运行过程要清晰明了;4、计算中需要十进制与十六进制(或二进制)转化。

#define LED_seg XBYTE[0x6000] //段码地址#define LED_light XBYTE[0x8000] //灯位地址#include &quot;reg51.h&quot;#include &quot;absacc.h&quot;unsigned char read_key(unsigned char);unsigned char display(unsigned char,unsigned char); void delay(unsigned int);unsigned char light[4]={0xfe,0xfd,0xfb,0xf7}; //扫描值灯位码unsigned charseg[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //段码unsigned char disp_buffer[5]={1,0,0,0,0}; //当前灯位、显示区unsigned char key_buffer[2]={0,0xff}; //缓冲区满标志、键码void main(){Unsigned char temp[5];unsigned char i;unsigned char operator=0;unsigned int tempa,tempb;bit first=1;TMOD=0x01; //置T0为方式1TL0=0x0; //延时2.5mS的定时器初始值TH0=0xf7; //赋初值PT0=1; //定时中断0优先设置TR0=1; //启动定时ET0=1; //允许定时IT1=0; //电平触发低电平有效EX1=1; //允许外中断PX1=1; // 外部中断1优先级设定EA=1; //中断总允许while(1){P1=0xf0; //扫描if (key_buffer[0]){switch(key_buffer[1]) //缓冲区满 {case 0:case 1:case 2:case 3:case 4:case 5:case 6:case 7:case 8:case 9: if (first) for(i=1;i;键码 {case 0x77:return(0x7);case 0xb7:return(0x8);case 0xd7:return(0x9);case 0xe7:return(0xd);case 0x7b:return(0x4);case 0xbb:return(0x5);case 0xdb:return(0x6);case 0xeb:return(0xc);case 0x7d:return(0x1);case 0xbd:return(0x2);case 0xdd:return(0x3);case 0xed:return(0xb);case 0x7e:return(0xf);case 0xbe:return(0x0);case 0xde:return(0xe);case 0xee:return(0xa);default: return(0xff);}}unsigned char display(unsigned chardisp_key,unsigned char n) //disp_key 显示字符,n 灯位{if ((n;=1)) LED_light=light[n-1];else LED_light=0xff;if ((disp_key>;=0)&&(disp_key。

51单片机简易计算器-(可算小数)

51单片机简易计算器-(可算小数)

51单片机简易计算器#include<reg51.h>#include<math.h>#define uchar unsigned char #define uint unsigned int sbit beep=P2^3;sbit dula=P2^6;sbit wela=P2^7;sbit rw=P1^1;sbit rs=P1^0;sbit lcden=P2^5;void yunsuan();void keyinput(char s);void write_data(char ddata);void write_com(char command);void display(long a);void init();void dealerror();void dataoverflow();void welcome();char code table1[]={0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d,0xeb,0xdb,0xbb,0x7b,0xe7,0xd7,0xb7,0x77};char code table2[]="789/456*123-.0=+";char j,k,temp,temp1,temp2,key,mchar,m,flag2=0,flag3=0; long x,y,num;int operators,input,iny;char error[5]="error";char overflow[8]="overflow";char welcome_[16]="welcome to use !";void delay(uint x)//延时{uint a,b;for(a=x;a>0;a--)for(b=10;b>0;b--);}void delay_ms(uint x)//延时{uint a,b;for(a=x;a>0;a--)for(b=110;b>0;b--);}void write_com(uchar com)//写命令{P0=com;rs=0;lcden=0;delay(10);lcden=1;delay(10);lcden=0;}void write_data(uchar date)//写数据{P0=date;rs=1;lcden=0;delay(10);lcden=1;delay(10);lcden=0;}long ming(int x){long m;switch(x){case 9:m=1000000000;return m;break; case 8:m=100000000;return m;break; case 7:m=10000000;return m;break; case 6:m=1000000;return m;break; case 5:m=100000;return m;break; case 4:m=10000;return m;break; case 3:m=1000;return m;break;case 2:m=100;return m;break;case 1:m=10;return m;break; case 0:m=1;return m;break; }}void display(long a){long d;int i,flag1=0,temp,c=-1;init();if(a<0){a=a*c;write_data('-');}for(i=9;i>=0;i--){d=ming(i);temp=a/d;a=a%d;if((temp==0)&&(flag1==0)) ;else{write_data(0x30+temp);flag1=1;}if(i==2){write_data('.');flag1=1;}}}void init()//LCD初始化{rw=0;dula=0;wela=0;write_com(0x38); //显示模式设置:16×2显示,5×7点阵,8位数据接口delay(20);write_com(0x0e); //显示模式设置delay(20);write_com(0x06); //显示模式设置:光标右移,字符不移delay(20);write_com(0x01); //清屏幕指令,将以前的显示内容清除delay(20);}void yunsuan() // 运算{if (iny){switch(operators){case 1:x=x+y;num=x;if(num<10000000000&&num>-10000000000){display(num);}elsedataoverflow();break;case 2:x=x-y;num=x;if(num<10000000000&&num>-10000000000) {display(num);}elsedataoverflow();break;case 3:x=x*y;num=x/100;if(num<10000000000&&num>-10000000000) {display(num);}elsedataoverflow();break;case 4:if (y==0)dealerror();else{if(y<100){x=x*100;y=y*100;}y=y/100;x=x/y;num=x;if(num<10000000000&&num>-10000000000) {display(num);}elsedataoverflow();}break;}y=0;}}void dealerror()//除数为0{int i=0;write_com(0x01);for(i=0;i<5;i++)write_data(error[i]);}void dataoverflow()//数值溢出{int i=0;write_com(0x01);for(i=0;i<8;i++)write_data(overflow[i]);}void welcome()//欢迎界面{int i=0;write_com(0x01);for(i=0;i<16;i++)write_data(welcome_[i]);}void keyinput(char s) //键盘输入{if(s<='9'&&s>='0') //判断按下的键是否为数值{if(flag3==0)num=num*10+100*(s-'0');elsenum=num*10+10*(s-'0');if(flag2==1){num=num/10;flag3=1;}if (operators>0){y=num;iny=1;}elsex=num;if(num<10000000000&&num>-10000000000) //当前数值是否超出限定范围display(num);elsedataoverflow();}elseswitch(s){case '.':/*iny=0;operators=0;*/flag2=1;break;case '=':write_data(table2[14]); delay(10);yunsuan();iny=0;operators=0;num=0;flag2=0;flag3=0;break;case '+':if (operators) yunsuan();operators=1;write_data(table2[15]); num=0;flag2=0;flag3=0;break;case '-':if (operators) yunsuan(); operators=2;write_data(table2[11]); num=0;flag2=0;flag3=0;break;case '*':if (operators) yunsuan(); operators=3;write_data(table2[7]); num=0;flag2=0;flag3=0;break;case '/':if (operators) yunsuan(); operators=4;write_data(table2[3]); num=0;flag2=0;flag3=0;break;}}void main() //主函数{char i;char flag0=1;init();welcome();for(i=0;i<10;i++) delay_ms(100);init();while(1){P3=0xf0;temp1=P3;P3=0x0f;temp2=P3;temp=temp1|temp2; while(P3!=0x0f) {beep=0;}beep=1;for(i=0;i<16;i++) {if(temp==table1[i]) {m=table2[i];flag0=0;}}if(flag0==0) {keyinput(m); flag0=1;}}}。

51单片机计算器程序设计报告

51单片机计算器程序设计报告

一、课题任务及要求要求:1、掌握数码管移位动态扫描显示的编程方法2、掌握矩阵扫描的编程方法3、掌握数据在内部运算的编程方法任务:1、实现最大6位正整数加、减、乘、除2、具备清零、等于功能3、16个按键功能依次为:数字0、数字1、数字2、数字3、数字4、数字5、数字6、数字7、数字8、数字9、清零、等于、加、减、乘、除二、硬件设计1.原理图2.原理分析该设计通过89C51芯片控制6个一位数码管显示,并实时检测按键按下情况来实现计算器功能,16个按键有10个为数字按键其他6个分别为加、减、乘、除、复位、等于电路接上电源后数码管显示个位显示数字0 ,芯片对按键进行实时扫描,通过矩阵键盘进行计算,特别注意的是,当结果为负数时,数码管显现EORR。

(一)、硬件部分1、数码管为一位共阴数码管,共6个;故在段码输出口外加NPN型三极管作驱动2、51芯片P1口接键盘端(矩阵按键)、P3口接段码、P2口的P2_0—P2_5接位码3、按键为四乘四矩阵,共16个键(二)、软件部分1、数码管移位显示的实现是通过标志位wei2的数值变化控制dispiay函数显示位来实现的2、程序的重要算法是通过类型为unsigned int 的数temp和数组str[]实现整体加减乘除、各位显示的只要弄懂这一算法,此程序就可轻易掌握3.PCB图略。

4.元件清单及造价预算按键 20个单价 0.2 元总计 4元万用板 2块单价 4 元总计 8元一位共阴数码管 6个单价 2 元总计 2元三极管 7个单价 0.2 元总计 1.4元1K电阻 20个单价 0.01 元总计 2毛排插及排线 5对单价 1元总计 5元电容 3个单价 0.2元总计 6毛晶振 1个单价 1元总计 1元8051芯片 1 个单价 6元总计 6元费用总计 26.2元5.实物照片三、程序设计头程序str[6]=str[5]=str[4]=str[3]=str[2]=str[1]=10;str1[6]=str1[5]=str1[4]=str1[3]=str1[2]=str[1];#include<reg51.h> //51单片机基本定义头文件#include<intrins.h> //循环位移头文件#define uchar unsigned char //宏定义#define uint unsigned intsbit P1_4=P1^4; //IO端口定义(矩阵扫描后4位端口)sbit P1_5=P1^5;sbit P1_6=P1^6;sbit P1_7=P1^7;uchar i,num,s; //全局变量定义uchar wei,wei2,ss,ss1,ss2,str1[]={0,0,0,0,0,0,0};long temp,temp1,str[]={10,10,10,10,10,10,10};uchar code dutable[]={ //段位编码0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};uchar code wetable[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};void init(); //函数声明void panduan();void display();void delay(uint z);void shaomiao();void main() //主函数{init(); //调用变量初始化函数while(1) //大循环{shaomiao(); //调用矩阵扫描加处理函数display(); //调用显示函数}}void init() //变量初始化函数{ss2=0;wei2=1;temp1=0;ss=0;ss1=0;temp=0;wei=0;num=0;}void delay(uint z)//延时函数(单位ms){uchar i;uint j;for(j=z;j>0;j--)for(i=114;i>0;i--);}void shaomiao() //扫描加处理函数{for(i=0,s=0xfe;i<4;i++) //低四位端口依次赋值1 {P1=s; //对P1口赋值panduan(); //调用判断处理函数s=_crol_(s,1); //s循环位左移s=s|0xf0; //进行位或运算} (使高4位复原)}void panduan(){uchar n;if(P1_4==0||P1_5==0||P1_6==0||P1_7==0){delay(10);P1=s|0xf0;if(P1_4==0||P1_5==0||P1_6==0||P1_7==0){if(P1_4==0){ n=1;num=i*4+n-1;}else if(P1_5==0){ n=2;num=i*4+n-1;}else if(P1_6==0){ n=3;num=i*4+n-1;}else if(P1_7==0){ n=4;num=i*4+n-1;}if(num<10&&wei!=7){wei++;if(ss1==1){temp=0;str[6]=str[5]=str[4]=str[3]=str[2]=str[1]=10;str1[6]=str1[5]=str1[4]=str1[3]=str1[2]=str1[1]=0;ss1=0;}str[wei]=num;if(str[1]!=10) temp=str[1];if(str[2]!=10) temp=str[1]*10+str[2];if(str[3]!=10) temp=str[1]*100+str[2]*10+str[3];if(str[4]!=10) temp=str[1]*1000+str[2]*100+str[3]*10+str[4];if(str[5]!=10) temp=str[1]*10000+str[2]*1000+str[3]*100+str[4]*10+str[5]; if(str[6]!=10)temp=str[1]*100000+str[2]*10000+str[3]*1000+str[4]*100+str[5]*10+str[6];}if(num>=10){wei=0;if(num==10){temp=0;1[1]=0;wei=0;temp1=0;ss=0;wei2=1;}if(ss1==0&&num==11||(ss1==0&&ss2!=0&&num>11&&num<16)){if(num==11)ss2=0;switch(ss){case 0: break;case 1: temp=temp+temp1;break;case 2: temp=temp1-temp;break;case 3: temp=temp*temp1;break;case 4: temp=temp1/temp;break;}if(temp>999999)temp=0;ss1=1;}if(num==12){temp1=temp;ss=1;ss1=1;ss2=1;}if(num==13){temp1=temp;ss=2;ss1=1;ss2=1;}if(num==14){temp1=temp;ss=3;ss1=1;ss2=1;}if(num==15){temp1=temp;ss=4;ss1=1;ss2=1;}}}str1[6]=temp/100000;str1[5]=temp%100000/10000;str1[4]=temp%10000/1000;str1[3]=temp%1000/100;str1[2]=temp%100/10;str1[1]=temp%10/1;if(str1[1]!=0)wei2=1;if(str1[2]!=0)wei2=2;if(str1[3]!=0)wei2=3;if(str1[4]!=0)wei2=4;if(str1[5]!=0)wei2=5;if(str1[6]!=0)wei2=6;}while(P1_4==0||P1_5==0||P1_6==0||P1_7==0); }void display(){char i1;for(i1=1;i1<wei2+1;i1++){if(num==0&&ss==4||temp<0){P2=wetable[0];P3=dutable[14];}else{P2=wetable[i1-1];P3=dutable[str1[i1]];delay(10);P3=0xff;}}}四、调试结果1、硬件调试a. 把电路板焊好后,先通过检查电路板表面检查是否有漏焊、错焊、接触不良等b. 编写检测程序逐个点亮数码管,检查数码显示部分是否有硬件问题c.编写检测程序检测矩阵扫描是否有硬件问题2、程序调试重点就是这个部分,很多程序就是在调试过程中慢慢完善,先前所完成的程序部分只能算一个基本框架,当然,这一切是建立在硬件没用问题的基础上程序在进行调试时,可以像硬件一样使用分模块调试,这样可以最迅捷的找出问题所在,不受其他模块的影响我们在硬件调试时,一开始时51芯片不工作,经过反复检查后发现原来51芯片的31脚(/EA/VPP)必须接入高电平才能使单片机在读取程序时优先访问内部程序存储器,否则只访问外部程序存储器,而我们的程序是在内部的,故芯片不工作,我们随即在31脚外接VCC和限流电阻,在解决了这个后,硬件OK了。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
}
//按键扫描函数
uchar keyscan()
{
uchar temp,scan1,scan2,num;
P1=0xf0;
scan1=P1;
if((scan1&amp;0xf0)!=0xf0)
{
delay(20);
scan1=P1;
if((scan1&amp;0xf0)!=0xf0)
figure=figure/10;//缩进
}
//显示
for(i=0;i&lt;seat;i++)
{
P2=wey[i];
if(i==2)
P0=leddot[load[i]];//第三位带小数点
else
P0=leddp[load[i]];
delay(2);
P2=0xff;
}
}
if(keynum==15)//输入等号
{
switch(mark)
{
case 11:figure1=figure2+figure1;break;
case 12:figure1=figure2-figure1;break;
case 13:figure1=figure2*figure1;break;
case 14:figure1=figure2/figure1;break;
}
decimal=0;
}
if(keynum==16)
{
decimal=1;//小数位
}
display();
}
}
}
//主函数
void main()
{
uchar decimal,count,mark=0;
figure1=figure2=keynum=decimal=count=0;
while(1)
{
keynum=keyscan();
if((keynum&gt;=0)&amp;&amp;(keynum&lt;=9))//输入的是数字
{0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};//未带小数点的数码管显示代码
uchar code leddot[]=
{0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};//带小数点的数码显示代码
case 0x7b:num=13;break;//乘号
case 0xe7:num=16;break;//小数点
case 0xd7:num=0;break;
case 0xb7:num=15;break;//等号
case 0x77:num=14;break;//除号
}
while(1)//等待按键释放
uchar code wey[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//八位显示码
uchar load[]={0,0,0,0,0,0,0,0};//八位装值数组
double figure1,figure2;//参加运算的两个数字
uchar keynum;
figure=figure1;
//确定显示数位
if(figure&gt;99999)
seat=8;
else if(figure&gt;9999)
seat=7;
else if(figure&gt;999)
seat=6;
else if(figure&gt;99)
seat=5;
else if(figure&gt;9)
{
P1=0xf0;
if((P1&amp;0xf0)==0xf0)
break;
else display();
}
return num;
}
}
return 55;//表示无信号
}
//数码管显示函数
void display()
{
double figure;
uchar seat,i;
}
}
}
if((keynum&gt;=11)&amp;&amp;(keynum&lt;=14))
{
mark=keynum;//符号
figure2=figure1;
figure1=0;
decimal=
0;
{
P1=0x0f;
scan2=P1;
temp=scan1|scan2;
switch(temp)
{
case 0xee:num=1;break;
case 0xde:num=2;break;
case 0xbe:num=3;break;
case 0x7e:num=11;break;//加号
{
if(decimal==0)//整数部分
figure1=keynum+figure1*10;
if(decimal==1)//小数部分
{
count&case 1:figure1=figure1+keynum*0.1;break;
case 2:{figure1=figure1+keynum*0.01;count=0;decimal=0;};break;
case 0xed:num=4;break;
case 0xdd:num=5;break;
case 0xbd:num=6;break;
case 0x7d:num=12;break;//减号
case 0xeb:num=7;break;
case 0xdb:num=8;break;
case 0xbb:num=9;break;
void display();
/*************************************
延时1ms基准
**************************************/
void delay(uint i)
{
uchar j;
while(i--)
for (j=0;j&lt;115;j++);//延时1毫秒程序
seat=4;
else
seat=3;
//把数装到数组中
load[0]=(long)(figure*100)%10;//两位浮点型数的注入
load[1]=(long)(figure*10)%10;
for(i=2;i&lt;seat;i++)
{
load[i]=(long)figure%10;//取最低位
#include&lt;reg52.h&gt;
#define uchar unsigned char
#define uint unsigned int
unsigned char code leddp[]=
相关文档
最新文档