基于单片机的计算器设计(1602完整版)
简易计算器(1602加矩阵键盘)
![简易计算器(1602加矩阵键盘)](https://img.taocdn.com/s3/m/c904b430b14e852459fb57bf.png)
一、原理图:二、程序#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。
51单片机控制lcd1602实现计算器
![51单片机控制lcd1602实现计算器](https://img.taocdn.com/s3/m/c3f0764fb52acfc789ebc982.png)
//利用51单片机控制LCD1602,实现加减乘除运算#include<reg52.h>#define uint unsigned int#define uchar unsigned char#define DATE_IO P0//P0口并行传输数据(LCD1602的数据端接P0口)sbit RS=P1^0;//LCD1602寄存器选择端sbit E=P1^2; //使能信号端sbit RW=P1^1;//读写控制端sbit deng=P1^3;//结果sbit shuzi11=P3^2;//前面的数字加1(因为我的按键是与P3口相连的)sbit shuzi22=P3^7; //后面的数字加1sbit jia=P3^3;//加号sbit jian=P3^4;//减号sbit cheng=P3^5;//乘号sbit chu=P3^6;//除号uint countqian=0,counthou=0;//数值uchar qian,bai,shi,ge,a=0;uchar code table1[]="0123456789";uchar code table2[]="+-*/";//**********************延时函数***************************************** void delay_us(unsigned int n){if(n==0)return ;while(--n);}void delay_ms(uint i){unsigned char a,b;for (a=1;a<i;a++)for(b=1;b;b++);}void delay(uint z){uint x,y;for(x=110;x>0;x--)for(y=z;y>0;y--);}//***********************************************************************//*********************控制LCD1602的函数*******************************void write_command(uchar come)//写指令函数{RS=0;//选择指令寄存器E=1;//由高电平跳变成低电平时,液晶执行命令DATE_IO=come;delay_us(5);E=0;RS=1;}void write_date(uchar date)//写数据函数{RS=1;//选择数据寄存器E=1;//由高电平跳变成低电平时,液晶执行命令DATE_IO=date;delay_us(5);E=0;RS=0;}//***************************************************************************** ***//**************************液晶初始化函数(基本上就是这个模式)*******************void init()//液晶初始化函数{RW=0;//低电平时进行写操作(高电平时进行读操作)E=0;write_command(0x38);//设置LCD两行显示,一个数据由5*7点阵表示,数据由8跟线传输delay_ms(5);write_command(0x01);//清除屏幕显示delay_ms(5);write_command(0x06);//设定输入方式,增量不移位delay_ms(5);write_command(0x0c);//开整体显示,关光标,不闪烁delay_ms(5);}//***************************************************************************** *****void jiayiqian()//前边数字加1计数函数{if(shuzi11==0)//如果前面加1的按键按下{delay(50);//消除抖动countqian=countqian+1;}if(countqian==999)//记到999归0countqian=0;}void jiayihou()//后边数字加1计数函数{if(shuzi22==0)//如果后面加1的按键按下{delay(50);//消除抖动counthou=counthou+1;}if(counthou==999)//记到999归0counthou=0;}void fuhao()//+,-,*,/运算号{if(jia==0)//如果加号按下{while(!jia);//等待按键的释放write_date(table2[0]);//显示'+'a=1;//加号按下的标志}if(jian==0)//如果减号按下{while(!jian);//等待按键的释放write_date(table2[1]);//显示'-'a=2;//减号按下的标志}if(cheng==0)//如果乘号按下{while(!cheng);//等待按键的释放write_date(table2[2]);//显示'*'a=3; //乘号按下的标志}if(chu==0)////如果除号按下{while(!chu);//等待按键的释放write_date(table2[3]);//显示'/'a=4;//除号按下的标志}}void chaiqian()//将前边各位数字拆开函数{bai=countqian/100;//求百位数字shi=countqian%100/10;//求十位数字ge=countqian%10;//求各位数字}void chaihou()//将后边各位数字拆开函数{bai=counthou/100;//求百位数字shi=counthou%100/10;//求十位数字ge=counthou%10;//求各位数字}void chaijiejia()//将相加结果各位数字拆开函数{qian=(countqian+counthou)/1000;//求千位数字bai=(countqian+counthou)%1000/100;//求百位数字shi=(countqian+counthou)%100/10;//求十位数字ge=(countqian+counthou)%10;//求各位数字}void chaijiejian()//将相减结果各位数字拆开函数{qian=(countqian-counthou)/1000;//求千位数字bai=(countqian-counthou)%1000/100;//求百位数字shi=(countqian-counthou)%100/10;//求十位数字ge=(countqian-counthou)%10;//求各位数字}void chaijiecheng()//将相乘结果各位数字拆开函数{qian=(countqian*counthou)/1000;//求千位数字bai=(countqian*counthou)%1000/100;//求百位数字shi=(countqian*counthou)%100/10;//求十位数字ge=(countqian*counthou)%10;//求各位数字}void chaijiechu()//将相除结果各位数字拆开函数(只取了模值){qian=(countqian/counthou)/1000;//求千位数字bai=(countqian/counthou)%1000/100;//求百位数字shi=(countqian/counthou)%100/10;//求十位数字ge=(countqian/counthou)%10;//求各位数字}void xianshiqian()//显示前边数字{write_command(0x80);//设置显示地址为LCD第一行,一旦首地址确定,显示完第一个数字后,光标会自动加1右移write_date(table1[bai]);//第一位显示百位write_date(table1[shi]); //第二位显示十位write_date(table1[ge]); //第三位显示个位fuhao();//显示运算号delay(50);//改变数值可以修改数字滚动的速度}void xianshihou()//显示后边数字{write_command(0x80+4);//设置显示地址为LCD第一行,一旦首地址确定,显示完第一个数字后,光标会自动加1右移write_date(table1[bai]);//第一位显示百位write_date(table1[shi]); //第二位显示十位write_date(table1[ge]); //第三位显示个位//delay(50);//改变数值可以修改数字滚动的速度}void xianshijie()//显示结果{write_command(0xc0);//设置显示地址为LCD第二行,一旦首地址确定,显示完第一个数字后,光标会自动加1右移write_date(table1[qian]);//第一位显示千位write_date(table1[bai]);//第二位显示百位write_date(table1[shi]); //第三位显示十位write_date(table1[ge]); //第四位显示个位//delay(50);//改变数值可以修改数字滚动的速度}void main()//主函数{init();//调用液晶初始化函数while(1){jiayiqian();//调用前边数字加1计数函数chaiqian();//调用将前边数字各位数字拆开函数xianshiqian();//显示前边数字jiayihou();//调用后边数字加1计数函数chaihou();//调用将后边数字各位数字拆开函数xianshihou();//显示后边数字if(deng==0)//控制显示结果的按键按下{if(a==1)//计算的是加法{chaijiejia();//将结果的各位数字拆分开xianshijie(); //显示结果}if(a==2)//计算的是减法{chaijiejian(); //将结果的各位数字拆分开xianshijie();//显示结果}if(a==3)//计算的是乘法{chaijiecheng();//将结果的各位数字拆分开xianshijie(); //显示结果}if(a==4) //计算的是除法{chaijiechu();//将结果的各位数字拆分开xianshijie(); //显示结果}}}}。
51单片机的1602计算器
![51单片机的1602计算器](https://img.taocdn.com/s3/m/ade561dae43a580216fc700abb68a98270feac05.png)
51单片机的1602计算器一、51 单片机和 1602 液晶显示屏简介51 单片机是指英特尔公司生产的 8051 系列单片机,它具有丰富的资源,包括 I/O 端口、定时器、中断等。
通过编程,可以让 51 单片机完成各种复杂的任务。
1602 液晶显示屏是一种字符型液晶显示模块,它能够显示两行,每行 16 个字符。
1602 液晶显示屏的控制方式相对简单,通过发送特定的指令和数据,就可以实现字符的显示。
二、硬件设计要实现 51 单片机的 1602 计算器,首先需要进行硬件设计。
硬件部分主要包括 51 单片机最小系统、1602 液晶显示屏、按键等。
51 单片机最小系统通常包括单片机芯片、晶振电路和复位电路。
晶振电路为单片机提供时钟信号,复位电路则保证单片机能够正常启动。
1602 液晶显示屏与51 单片机的连接需要用到一些数据线和控制线。
数据线用于传输要显示的数据,控制线用于控制显示屏的工作状态。
按键用于输入数字和运算符,常见的按键有数字键 0 9 、运算符+、、、/以及等于号=等。
三、软件编程软件编程是实现 51 单片机 1602 计算器的关键。
在编程过程中,需要实现以下几个主要功能:1、初始化 1602 液晶显示屏在程序开始时,需要对 1602 液晶显示屏进行初始化,设置显示模式、光标显示等。
2、按键扫描通过不断扫描按键状态,获取用户输入的数字和运算符。
3、数据处理根据用户输入的数字和运算符,进行相应的计算,并将结果存储起来。
4、显示结果将计算结果显示在 1602 液晶显示屏上。
```cinclude <reg52h> //包含 51 单片机的头文件//定义 1602 液晶显示屏的控制引脚sbit RS = P2^0;sbit RW = P2^1;sbit EN = P2^2;//定义 1602 液晶显示屏的数据引脚sbit D0 = P0^0;sbit D1 = P0^1;sbit D2 = P0^2;sbit D3 = P0^3;sbit D4 = P0^4;sbit D5 = P0^5;sbit D6 = P0^6;sbit D7 = P0^7;//定义按键引脚sbit key0 = P1^0;sbit key1 = P1^1;sbit key2 = P1^2;sbit key3 = P1^3;sbit key4 = P1^4;sbit key5 = P1^5;sbit key6 = P1^6;sbit key7 = P1^7;sbit key8 = P3^0;sbit key9 = P3^1;sbit key_add = P3^2;sbit key_sub = P3^3;sbit key_mul = P3^4;sbit key_div = P3^5;sbit key_eq = P3^6;//定义变量unsigned char num1, num2, op, result;unsigned char flag = 0; //标志位,用于判断输入状态//写指令函数void write_command(unsigned char command){RS = 0;RW = 0;EN = 0;P0 = command;EN = 1;EN = 0;}//写数据函数void write_data(unsigned char data){RS = 1;RW = 0;EN = 0;P0 = data;EN = 1;EN = 0;}//初始化 1602 液晶显示屏函数void init_1602(){write_command(0x38);// 8 位数据,2 行显示,5x7 点阵write_command(0x0c);//显示开,光标关,闪烁关write_command(0x06);//字符右移,地址指针加 1 write_command(0x01);//清屏}//按键扫描函数void key_scan(){if (key0 == 0){delay_ms(10);//消抖if (key0 == 0){if (flag == 0){num1 = num1 10 + 0;write_data('0');}else{num2 = num2 10 + 0;write_data('0');}}while (!key0);//等待按键松开}//其他按键扫描类似}//计算函数void calculate(){switch (op){case '+':result = num1 + num2;break;case '':result = num1 num2;break;case '':result = num1 num2;break;case '/':if (num2!= 0)result = num1 / num2;elsewrite_data('E');//除数为 0 ,显示错误break;}}//主函数void main(){init_1602();while (1){key_scan();if (key_add == 0 || key_sub == 0 || key_mul == 0 ||key_div == 0){delay_ms(10);//消抖if (key_add == 0){op ='+';flag = 1;write_data('+');}//其他运算符处理类似}if (key_eq == 0){delay_ms(10);//消抖if (key_eq == 0){calculate();write_data(result);num1 = 0;num2 = 0;flag = 0;}}}}```上述代码只是一个简单的示例,实际应用中还需要进行更多的优化和完善,比如处理输入错误、添加更多的功能等。
基于51单片机1602液晶显示简易计算器设计..
![基于51单片机1602液晶显示简易计算器设计..](https://img.taocdn.com/s3/m/2de369bde45c3b3566ec8b81.png)
#include<reg52.h>#include<math.h>#define uint unsigned int#define uchar unsigned char#define PI 3.141592sbit RS = P2^0;sbit RW = P2^1;sbit EN = P2^2;sbit led=P2^4;sbit speek=P3^7;uchar table0[]={"Welcome to use"};uchar table1[]={"made by Ms. Li"};uchar table2[]={"error"};uchar count;void main(void){uchar error=0,i,first=0,dot1,dot2,dot1_num,dot2_num,minus1,minus2;//错误标志、第一次清屏标记、小数点标记以及小数点个数负号标记、负号个数uchar Sin,Cos,Tan,ln;uchar Key_num,last_key_num; //键号uchar flag=0,equal_flag;double num1=0,num2=0,num=0,result=0,save_result; //运算符、等于符//第一个数、第二个数、计算结果uchar first_num=0,Ans=0,second_num=0; InitLcd();EA=1;ET0=1;TMOD=0X01;TH0=(65536-500)/256;TL0=(65536-500)%256;write_com(0x80+0x40+15);write_Dat('0');write_com(0x80);while(1){while(key_scan()==0xff);TR0=1;if(first==0){first=1;write_com(0x01);}Key_num=key_scan();switch(key_scan()){case 1:if(last_key_num!=Key_num){write_Dat('l');write_Dat('n');ln=1;}break;case 2:if(last_key_num!=Key_num){write_Dat('s');write_Dat('i');write_Dat('n');Sin=1;}break;case 3:if(last_key_num!=Key_num){write_Dat('c');write_Dat('o');write_Dat('s');Cos=1;}break;case 4:if(last_key_num!=Key_num){write_Dat('t');write_Dat('a');write_Dat('n');Tan=1;}break;case 5:if(last_key_num!=Key_num){write_Dat('^');flag=5;}break;case 6:write_Dat('7');num=7;break; case 7:write_Dat('8');num=8;break; case 8:write_Dat('9');num=9;break; case 9:if(last_key_num!=Key_num){write_Dat('+');flag=1;}break;case 10:if(last_key_num!=Key_num){write_Dat('T');flag=6;}break;case 11:write_Dat('4');num=4;break; case 12:write_Dat('5');num=5;break; case 13:write_Dat('6');num=6;break; case 14:if(last_key_num!=Key_num){write_Dat('-');flag=2;}break;case 15:if(last_key_num!=Key_num){if(equal_flag==1){write_com(0x01);write_com(0x80);write_Dat('A');write_Dat('n');write_Dat('s');write_Dat('=');save_result=result;}else{if(Key_num!=1&&Key_num!=2&&Key_num!=3&&Key_num!=4&&Key_num!=22&&Key_num!=23 &&Key_num!=25){write_Dat('A');write_Dat('n');write_Dat('s');if(flag==0){num1=save_result;first_num=1;}else{num2=save_result;second_num=1;}}}}break;case 16:write_Dat('1');num=1;break;case 17:write_Dat('2');num=2;break;case 18:write_Dat('3');num=3;break;case 19:if(last_key_num!=Key_num){write_Dat('*');flag=3;}break;case 21:write_Dat('0');num=0;break;case 22:if(last_key_num!=Key_num){if(flag==0){minus1++;if(minus1==1){write_Dat('-');}}else{minus2++;if(minus2==1){write_Dat('-');}}} break;case 23:if(last_key_num!=Key_num){if(flag==0){dot1++;if(dot1==1){write_Dat('.');}}else{dot2++;if(dot2==1){write_Dat('.');}}} break;case 24:if(last_key_num!=Key_num){write_Dat('/');flag=4;}break;case 25:if(last_key_num!=Key_num){write_Dat('=');equal_flag=1;}break;}if(Key_num!=1&&Key_num!=2&&Key_num!=3&&Key_num!=4&&Key_num!=15&&Key_num!=22 &&Key_num!=23&&Key_num!=25)// 第一个数{if(flag==0){num1=num1*10+num;num=0;if(dot1!=0){dot1_num++;}first_num=1;}if(flag!=0){num2=num2*10+num;num=0;if(dot2!=0){dot2_num++;}second_num=1;}}if(equal_flag==1&&first_num==1){if(dot1!=0){num1=num1/pow(10,dot1_num);dot1=0;}if(dot2!=0){num2=num2/pow(10,dot2_num);dot2=0;}if(minus1!=0){num1=num1*(-1);}if(minus2!=0){num2=num2*(-1);}if(second_num!=0){switch(flag){case 1:result=num1+num2;break;case 2:result=num1-num2;break;case 3:result=num1*num2;break;case 4:if(num2!=0){result=num1/num2;}else{write_com(0x80+0x40+10);for(i=0;i<5;i++){write_Dat(table2[i]);}error=1;} break;case 5: result=pow(num1,num2);break;case 6: result=pow(num1,1/num2);break;}}else if(second_num==0&&Sin==0&&Cos==0&&Tan==0&&ln==0) result=num1;else if(second_num==0&&(Sin==1||Cos==1||Tan==1||ln==1)) {if(Sin==1)result=sin(num1/180*PI)+0.005;if(Cos==1)result=cos(num1/180*PI)+0.005;if(Tan==1)result=tan(num1/180*PI)+0.005;if(ln==1){if(num1>0)result=log(num1)+0.005;else{write_com(0x80+0x40+10);for(i=0;i<5;i++){write_Dat(table2[i]);}error=1;}}}if(error!=1)display(result);}// 清零if(Key_num==20){num1=num2=result=0;flag=equal_flag=0;error=0;first=0;dot1_num=dot2_num=0;minus1=0;minus2=0;first_num=0,second_num=0;Sin=Cos=Tan=ln=0;write_com(0x01);write_com(0x80+0x40+15);write_Dat('0');}last_key_num=Key_num;while(key_scan()!=0xff);}}void time0() interrupt 1{TH0=(65536-600)/256;TL0=(65536-600)%256;count++;speek=!speek;if(count>50){TR0=0;count=0;}}void delay(uint x){uchar y;while(x--)for(y=0;y<120;y++);}void write_com(unsigned char c) {RS=0;RW=0;EN=1;delay(5);P0=c;EN=0;}void write_Dat(unsigned char c) {RS=1;RW=0;EN=1;delay(5);P0=c;EN=0;}void InitLcd(){write_com(0x38); //display modewrite_com(0x06); // write_com(0x0c); // write_com(0x01); // } 显示光标挪动地点显示开及光标设置显示清屏uchar key_scan(){uchar key_num=0xff;uint temp;P3=0x03;P1=0xe0;temp=(P3<<8)|P1;if((temp&0x03e0)!=0x03e0){delay(10);if((temp&0x03e0)!=0x03e0){// 第一行P3=0x03;P1=0xfe;temp=(P3<<8)|P1;switch(temp){case 0x03de:key_num=1; break;case 0x03be:key_num=2; break;case 0x037e:key_num=3; break;case 0x02fe:key_num=4; break;case 0x01fe:key_num=5; break;}//第二行P3=0x03;P1=0xfd;temp=(P3<<8)|P1;switch(temp){case 0x03dd:key_num=6; break;case 0x03bd:key_num=7; break;case 0x037d:key_num=8; break;case 0x02fd:key_num=9; break;case 0x01fd:key_num=10; break;}//第三行P3=0x03;P1=0xfb;temp=(P3<<8)|P1;switch(temp){case 0x03db:key_num=11; break;case 0x03bb:key_num=12; break;case 0x037b:key_num=13; break;case 0x02fb:key_num=14; break;case 0x01fb:key_num=15; break;}//第四行P3=0x03;P1=0xf7;temp=(P3<<8)|P1;switch(temp){case 0x03d7:key_num=16; break;case 0x03b7:key_num=17; break;case 0x0377:key_num=18; break;case 0x02f7:key_num=19; break;case 0x01f7:key_num=20; break;}P3=0x03;//第五行P1=0xef;temp=(P3<<8)|P1;switch(temp){case 0x03cf:key_num=21; break;case 0x03af:key_num=22; break;case 0x036f:key_num=23; break;case 0x02ef:key_num=24; break;case 0x01ef:key_num=25; break;}}}return key_num;}void display(double Data){uchar xs=0,fs=0,i;if(Data<0){fs=1;Data=Data*(-1);}if(Data>(long)Data){xs=1;}if(Data<10)//0~9{if(xs==1){Data=Data*100;write_com(0x80+0x40+11);if(fs==1)write_Dat('-');elsewrite_Dat(' ');write_Dat((long)Data/100+'0');write_Dat('.');write_Dat((long)Data/10%10+'0');write_Dat((long)Data%10+'0');}else if(xs==0){write_com(0x80+0x40+14);if(fs==1)write_Dat('-');elsewrite_Dat(' ');write_Dat((long)Data+'0');}}else if(Data<100)//10~99{if(xs==1){Data=Data*100;write_com(0x80+0x40+10);if(fs==1)write_Dat('-');elsewrite_Dat(' ');write_Dat((long)Data/1000+'0');write_Dat((long)Data/100%10+'0');write_Dat('.');write_Dat((long)Data/10%10+'0');write_Dat((long)Data%10+'0');}else if(xs==0){write_com(0x80+0x40+13);if(fs==1)write_Dat('-');elsewrite_Dat(' ');write_Dat((long)Data/10+'0');write_Dat((long)Data%10+'0');}}else if(Data<1000)//100~999 {if(xs==1){Data=Data*100;write_com(0x80+0x40+9);if(fs==1)write_Dat('-');elsewrite_Dat(' ');write_Dat((long)Data/10000+'0');write_Dat((long)Data/1000%10 +'0');write_Dat((long)Data/100%10+'0');write_Dat('.');write_Dat((long)Data/10%10+'0');write_Dat((long)Data%10+'0');}else if(xs==0){write_com(0x80+0x40+12);if(fs==1)write_Dat('-');elsewrite_Dat(' ');write_Dat((long)Data/100+'0');write_Dat((long)Data/10%10+'0');write_Dat((long)Data%10+'0');}}else if(Data<10000)//1000~9999 {if(xs==1){Data=Data*100;write_com(0x80+0x40+8);if(fs==1)write_Dat('-');elsewrite_Dat(' ');write_Dat((long)Data/100000+'0');write_Dat((long)Data/10000%10+'0');write_Dat((long)Data/1000%10 +'0');write_Dat((long)Data/100%10+'0');write_Dat('.');write_Dat((long)Data/10%10+'0');write_Dat((long)Data%10+'0');}else if(xs==0){write_com(0x80+0x40+11);if(fs==1)write_Dat('-');elsewrite_Dat(' ');write_Dat((long)Data/1000+'0');write_Dat((long)Data/100%10+'0');write_Dat((long)Data/10%10+'0');write_Dat((long)Data%10+'0');}}else if(Data<100000)//10000~99999 {if(xs==1){Data=Data*100;write_com(0x80+0x40+7);if(fs==1)write_Dat('-');elsewrite_Dat(' ');write_Dat((long)Data/1000000+'0');write_Dat((long)Data/100000%10+'0');write_Dat((long)Data/10000%10+'0');write_Dat((long)Data/1000%10 +'0');write_Dat((long)Data/100%10+'0');write_Dat('.');write_Dat((long)Data/10%10+'0');write_Dat((long)Data%10+'0');}else if(xs==0){write_com(0x80+0x40+10);if(fs==1)write_Dat('-');elsewrite_Dat(' ');write_Dat((long)Data/10000+'0');write_Dat((long)Data/1000%10+'0');write_Dat((long)Data/100%10+'0');write_Dat((long)Data/10%10+'0');write_Dat((long)Data%10+'0');}}else if(Data<1000000) //100000~999999{if(xs==1){Data=Data*100;write_com(0x80+0x40+7);if(fs==1)write_Dat('-');elsewrite_Dat(' ');write_Dat((long)Data/10000000+'0');write_Dat((long)Data/1000000%10+'0');write_Dat((long)Data/100000%10+'0');write_Dat((long)Data/10000%10+'0');write_Dat((long)Data/1000%10 +'0');write_Dat((long)Data/100%10+'0');write_Dat('.');write_Dat((long)Data/100000%10+'0');write_Dat((long)Data/100000%10+'0');write_Dat((long)Data/10000%10+'0');write_Dat((long)Data/1000%10 +'0');write_Dat((long)Data/100%10+'0');}else if(xs==0){write_com(0x80+0x40+9);if(fs==1)write_Dat('-');elsewrite_Dat(' ');write_Dat((long)Data/100000+'0');write_Dat((long)Data/10000%10+'0');write_Dat((long)Data/1000%10+'0');write_Dat((long)Data/100%10+'0');write_Dat((long)Data/10%10+'0');write_Dat((long)Data%10+'0');}}else{write_com(0x80+0x40+10);for(i=0;i<5;i++){write_Dat(table2[i]);}}}。
基于单片机的简易计算器的设计
![基于单片机的简易计算器的设计](https://img.taocdn.com/s3/m/e49842146bd97f192279e9a5.png)
基于单片机的简易计算器的设计
摘 要 单片机是采用超大规模集成电路技术,把一台计算机的主要部件集成在一个芯片上所构成的一种集成电路芯片,因此单片机被称为单片微型计算机。由于单片机体积小、价格低、可靠性高、适用面宽以及有其本身的指令系统等诸多优势,在各个领域、各个行业都得到了广泛应用。很多大专、本科院校都开设了关于单片机原理与应用方面的课程。
I
关键词: 单片机,计算器,运算,扩展
ABSTRACT
SCM is a integrated circuit chips that integrated the main cmponents of a
computer in a chip by using the large scale integrated circuit technology.So theቤተ መጻሕፍቲ ባይዱSCM is called the single chip computer. In various fields, SCM has been widely used for its small size, low price, high reliability, and wide application etc. Many college and universities opened the courses about the principle and application of SCM.
本设计就是依据单片机的原理来进行简易计算器的设计的,设计采用了STC89C52RC单片机作为计算器的主控制器,TC1602液晶作为显示器,4×4矩阵键盘作为输入按键,通过软硬件相结合,来实现整数的“加”、“减”、“乘”、“除”运算。并在计算器顺利完成的基础上,对系统进行了简单的扩展,增加了电子表功能,使系统完善化和多功能化。
51单片机计算器1602显示程序
![51单片机计算器1602显示程序](https://img.taocdn.com/s3/m/6f2de8c05fbfc77da269b1cf.png)
delay_jsq(5);
if(P2!=0xfb)
{
if(P2!=0xfb)
{
temp=P2&0xf0;
switch(temp)
{
case 0xe0:num=8;
break;
case 0xd0:num=9;
break;
case 0xb0:num=10;
break;
case 0x70:num=11;
case 0x70:num=7;
break;
}
}
while(P2!=0xfd);
if(j!=0)
{
write_lcd1602(0x01,0);
delay(1);
j=0;
}
if(num==4||num==5||num==6&&num!=7)//如果按下的是'4','5'或'6'
{
if(flag1==0)//没有按过符号键
break;
}
}
}
}
void main()
{
ini_lcd1602();
while(1)
{
keyscan_4_4();
}
}
write_lcd1602(0x06,0);
delay(1);
write_lcd1602(0x01,0);
delay(1);
num_1=0;
i=0;
j=0;
a=0; //第一个参与运算的数
b=0; //第二个参与运算的数
c=0;
flag1=0; //flag1表示是否有符号键按下,
fuhao=0; // fuhao表征按下的是哪个符号
PS2和1602制作简易计算器
![PS2和1602制作简易计算器](https://img.taocdn.com/s3/m/02d896797fd5360cba1adb84.png)
//#include<1602.h>#include<reg52.h>sbit rs=P2^2;sbit rw=P2^4;sbit e=P2^3;void delay_50us(unsigned int t); void write_data(unsigned char dat); void write_com(unsigned char com); void init(void);#include<1602.h>void delay_50us(unsigned int t) {unsigned char j;for(;t>0;t--)for(j=19;j>0;j--);}void write_com(unsigned char com) {e=0;rs=0;rw=0;P0=com;delay_50us(10);e=1;delay_50us(20);e=0;}void write_data(unsigned char dat) {e=0;rs=1;rw=0;P0=dat;delay_50us(10);e=1;delay_50us(20);e=0;}void init(void){delay_50us(300);write_com(0x38);delay_50us(100);write_com(0x38);delay_50us(100);write_com(0x38);write_com(0x38);write_com(0x08);write_com(0x01);write_com(0x06);write_com(0x0c);}#include <1602.h>#include<math.h>#include <stdlib.h>#include<string.h>#include <reg52.h>#define uchar unsigned char/**************io口定义************************************/sbit ps2_clk=P3^2;sbit ps2_data=P3^4;/************全局变量定义区****************************/uchar datbuf[3];//存储PS2键盘发过来的按键码uchar into_num; //中断中断次数,uchar key_num; //按键玛的个数uchar receive_data ;//接受按键码的缓存区code uchar key_code[17][2]={ // 该数组储存的通码对应的数据{0x70,'0'},{0x69,'1'},{0x72,'2'},{0x7a,'3'},//相当于一个查询表{0x6b,'4'},{0x73,'5'},{0x74,'6'},{0x6c,'7'},{0x75,'8'},{0x7d,'9'},//0,1,2,3,4,5,6,7,8,9{0x79,'+'},{0x7b,'-'},{0x7c,'*'},{0x5d,'/'},//+,-,*,/.{0x55,'='}// =//{0x29,'p'}};/***************************外部中断0初始化***************************/void init_into(){IT0=1;EX0=1;EA=1;}/***************************************************** *函数功能:返回通码对应的数据*参数:dat代表键盘发送过来的通码*返回值:通码对应数据*******************************************************/ uchar deal_data(uchar dat){ char i;for(i=0;i<17;i++)if(dat==key_code[i][0]){return key_code[i][1];}return 0;}/***************************************************** *函数功能:取出计算结果的每一位并且显示*参数:result1代表最后的计算结果*返回值:无*******************************************************/void result(long int result1){char shiwang=0, wang=0,qian=0,bai=0,shi=0,ge=0;shiwang=result1/100000;wang=(result1%100000/10000);qian=(result1%100000%10000/1000);bai=(result1%100000%10000%1000/100);shi=(result1%100000%10000%1000%100/10);ge=result1%10;if(shiwang!=0){write_data('0'+shiwang);write_data('0'+wang);write_data('0'+qian);write_data('0'+bai);write_data('0'+shi);write_data('0'+ge);}else if(wang!=0){ write_data('0'+wang);write_data('0'+qian);write_data('0'+bai);write_data('0'+shi);write_data('0'+ge);}else if(qian!=0){ write_data('0'+qian);write_data('0'+bai);write_data('0'+shi);write_data('0'+ge);}else if(bai!=0){write_data('0'+bai);write_data('0'+shi);write_data('0'+ge);}else if(shi!=0){write_data('0'+shi);write_data('0'+ge);}else write_data('0'+ge);}/******************************************************函数功能:把字符串转换成为整数*参数:str代表要转换的字符串,ge代表个位在字符串str中所在的位置*返回值:value最后转换结果* 补充:程序在运行时总是个位精度不够,通过指针ge是为了在主函数中修正它 ******************************************************/long int str_into_digital(char *str,char*ge){double a1=0.0,value1=0.0;long int value=0;char i=0;char j=0;int aa=0;while(str[i]!=0)i++;*ge=i-1;while(*str!=0){a1=(double)(*str-0x30)*pow(10,i-1);str++;value1+=a1;i--;}value=(long int)value1;return value;}void main(){ uchar str1[10]; //第一个加数uchar str2[10];//第二个加数uchar str[20]; //储存从键盘接受经过匹配的数据 xdata uchar i=0,j=0;xdata uchar key_data;uchar flat=0;uchar wei_i=0;uchar wei_j=12;uchar ge_wei=0;uchar bb=0;xdata long int a1=0,a2=0; //进行运算的两个数init_into();init();write_com(0x80);while(1)if(key_num==3){ key_num=0;if( (key_data=deal_data(datbuf[0]))!=0)if(key_data!='=')/********************把所有的数据都装入str************************/ { str[i]=key_data;i++;wei_j=i; //wei_j表示总数据个数从1开始计数write_data(key_data);}else{ write_com(0x80+40);/********************从str中找出运算符的位置wei_i同时确定是何种运算符************************/for(j=0;;j++){ if(str[j]=='+'){ flat=1;wei_i=j;break; }if(str[j]=='-'){ flat=2;wei_i=j;break; }if(str[j]=='*'){ flat=3;wei_i=j;break; }if(str[j]=='/'){ flat=4;wei_i=j;break; }}/********************把第一个加数装进str1************************/ for(j=0;;j++){ if(j==wei_i){ str1[j]='\0';break;}str1[j]=str[j];}/*******************把第二个加数装入str2************************/ for(j=wei_i+1,i=0;;j++,i++){ if(j==wei_j){str2[i]='\0';i=0;break;}str2[i]=str[j];}a1=str_into_digital(str1,&ge_wei);/*******************修正a1个位的误差************************/ a1=a1-a1%10;bb=str1[ge_wei]-0x30;a1=a1+bb;ge_wei=0;a2=str_into_digital(str2,&ge_wei);/*******************修正a2个位的误差************************/ a2=a2-a2%10;bb=str2[ge_wei]-0x30;a2=a2+bb;ge_wei=0;switch(flat){ case 1:{a1+=a2;break;}case 2:{a1-=a2;break;}case 3:{ a1*=a2;break;}case 4:{ a1/=a2;break;}default:break;}flat=0;result(a1);//计算结果} //大else}//大if} //主函数/*------------------------------------------------------- 中断服务函数功能:处理接受PS2的数据------------------------------------------------------- */ //void receive_int() interrupt 0{if((into_num>0)&&(into_num<9)){ receive_data>>=1;if(ps2_data)receive_data|=0x80;}into_num++;if(into_num==11){ datbuf[key_num]=receive_data;receive_data=0;into_num=0;key_num++;}}。
基于单片机的lcd1602的多功能计算器
![基于单片机的lcd1602的多功能计算器](https://img.taocdn.com/s3/m/ff7f8e58e518964bcf847cb6.png)
单片机原理与应用技术课程设计基于51单片机的多功能计算器院系:机电工程学院专业(班级):电子信息工程1班姓名:学号: 20134081006指导教师:邵海龙职称:讲师完成日期:2015 年9月22日评定成绩:关键词:单片机;液晶显示;计算器;目录引言 (3)1 单片机及其应用……………………………………………………………………...3.1.1单片机介绍 (3)1.2单片机的应用 (4)1.3 STC89C52单片机 (4)2 液晶屏LCD1602原理及应用 (5)2.1液晶屏LCD1602介绍及工作原理 (5)2.2 液晶屏LCD1602的功能及应用 (5)3 设计思路、仿真及调试 (7)3.1设计方法 (7)3.2硬件设计............................................................................... . (7)3.2.1复位电路 (7)3.2.2 液晶屏LCD1602显示电路 (8)3.2.3 4*4键盘的设计 (9)3.2.5 多功能计算器的总电路 (10)3.3软件设计 (10)3.4软件仿真 (17)3.5硬件调试 (18)4 结束语.............................................................. .. (18)谢辞 (18)参考文献 (19)1 单片机及其应用1.1单片机介绍单片机(Microcontrollers)是一种集成电路芯片,是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU、随机存储器RAM、只读存储器ROM、多种I/O口和中断系统、定时器/计数器等功能1.2单片机的应用STC89C52 是STC公司推出的一款超强抗干扰,加密性强,在线可编程,高速,低功耗CMOS 8位单片机。
片内含 8k bytes 的可反复擦写Flash只读程序存储器和256 bytes 的随机数据存储器(RAM),器件采用STC公司的高密度、非易失性存储技术生产,与标准MCS-51指令系统及8052产品引脚兼容,片内置通用8位中央处理器(CPU)和Flash 存储单元,功能强大的STC89C52单片机适合于许多较为复杂控制应用场合。
1602液晶显示计算器00.
![1602液晶显示计算器00.](https://img.taocdn.com/s3/m/bc08abb4b9d528ea81c77976.png)
1602液晶显示计算器院系:机械工程学院班级:测控1003姓名:金飞完成时间:2012年11月18日摘要本设计由51单片机作为核心,4*4矩阵键盘作为输入,将数据输入到单片机内部处理,并通过1602液晶显示出来运算及其结果。
本设计具有成本低廉,操作简单。
可作为日常简单计算使用。
关键词:51单片机、矩阵键盘、1602液晶。
一、外观介绍:二、电路仿真:P0.0~P0.7引脚接lcd的D0-D7,P3口接矩阵键盘。
单片机的P2.4、P2.0、P2.3脚分别接到LCD的RS、R/W、E管。
三、显示电路,LCD1602A的引脚详细介绍:采用LCD1602A来显示,要求能显示两行。
它的D—7D引脚分别接到单片机的P0.0~P0.7引脚;RS、R/W、E管脚分别接到单片机的P2.4、P2.0、P2.3 。
具体连接见后面的电路图。
以下是1602的16进制ASCII码表三、矩阵键盘扫描电路P3口的P3.0,P3.1,P3.2和P3.3四根线作为按键的行输出线,用P3.4,P3.5,P3.6和P3.7作为按键的列输入线。
依次给某一行低电平,再判断哪一列是低电平。
于是就判断出哪行和哪列导通。
对于不同的组合可以确定所有按键位置,将位置赋值到一个变量中,以供使用。
具体来说:假如按下的是数字5键(编号6——位于第二行第二列),首先置第一行为低电平其他7位为高电平P0=0xfe,再检测高四位的电平(P0=P&0xf0 ),因为列没有一条与第一行相导通,所以P0的高位还是高电平的。
然后再换第二行P0=0xfd,同理检测高四位(P0=P&0xf0 )得出P0=0xd0,则5键所在位置为第二行第二列,然后num赋值为6。
四、程序分析可知共分为七个模块:键盘扫描部分,定义各个位置上的键值部分,延迟部分,存贮部分,液晶显示部分,运算部分,动态显示部分。
主程序流程图如下:否判断是否有键按下五、程序#include<reg51.h>#define uint unsigned int#define uchar unsigned charsbit lcden=P2^3;sbit rs=P2^4;sbit rw=P2^0;sbit busy=P0^7;char i,j,temp,num,num_1;long a,b,c;float a_c,b_c;uchar flag,fuhao;uchar code table[]={7,8,9,0,4,5,6,0,1,2,3,0,0,0,0,0};uchar code table1[]={7,8,9,0x2f-0x30,4,5,6,0x2a-0x30,1,2,3,0x2d-0x30,0x01-0x30,0,0x3d-0x30,0x2b-0x30}; void delay(uchar z){uchar y;for(z;z>0;z--)for(y=0;y<110;y++);}void check(){do{P0=0xFF;rs=0;rw=1;lcden=0;delay(1);lcden=1;}while(busy==1);}void write_com(uchar com){P0=com;rs=0;rw=0;lcden=0;check();lcden=1;}void write_date(uchar date) {P0=date;rs=1;rw=0;lcden=0;check();lcden=1;}void init(){num=-1;lcden=1;write_com(0x01);write_com(0x38);write_com(0x0c);write_com(0x06);write_com(0x80);write_com(0x01);num_1=0;i=0;j=0;a=0;b=0;c=0;flag=0;fuhao=0;}void keyscan(){P3=0xfe;if(P3!=0xfe){delay(20);if(P3!=0xfe){temp=P3&0xf0;{case 0xe0:num=0;break;case 0xd0:num=1;break;case 0xb0:num=2;break;case 0x70:num=3;break;}}while(P3!=0xfe);if(num==0||num==1||num==2){if(j!=0){write_com(0x01);j=0;}if(flag==0){a=a*10+table[num];}Else{b=b*10+table[num];}}else{flag=1;fuhao=4;}i=table1[num];write_date(0x30+i);}P3=0xfd;if(P3!=0xfd){delay(5);if(P3!=0xfd){temp=P3&0xf0;{case 0xe0:num=4;break;case 0xd0:num=5;break;case 0xb0:num=6;break;case 0x70:num=7;break;}}while(P3!=0xfd);if(num==4||num==5||num==6&&num!=7) {if(j!=0){write_com(0x01);j=0;}if(flag==0){a=a*10+table[num];}else{b=b*10+table[num];}}Else{flag=1;fuhao=3;}i=table1[num];write_date(0x30+i);}P3=0xfb;if(P3!=0xfb){delay(5);if(P3!=0xfb){temp=P3&0xf0;{case 0xe0:num=8;break;case 0xd0:num=9;break;case 0xb0:num=10;break;case 0x70:num=11;break;}}while(P3!=0xfb);if(num==8||num==9||num==10) {if(j!=0){write_com(0x01);j=0;}if(flag==0){a=a*10+table[num];}Else{b=b*10+table[num];}}else if(num==11){flag=1;fuhao=2;}i=table1[num];write_date(0x30+i);}P3=0xf7;if(P3!=0xf7){delay(5);if(P3!=0xf7){switch(temp){case 0xe0:num=12;break;case 0xd0:num=13;break;case 0xb0:num=14;break;case 0x70:num=15;break;}}while(P3!=0xf7);switch(num){case 12:{write_com(0x01);a=0;b=0;flag=0;fuhao=0;} break;case 13:{if(flag==0){a=a*10;write_date(0x30);P1=0;}else if(flag==1){b=b*10;write_date(0x30);}}break;case 14:{j=1;if(fuhao==1){write_com(0x80+0x4f);write_com(0x04);c=a+b;while(c!=0){write_date(0x30+c%10);c=c/10;}write_date(0x3d);a=0;b=0;flag=0;fuhao=0;}else if(fuhao==2){write_com(0x80+0x4f);write_com(0x04);if(a-b>0)c=a-b;elsec=b-a;while(c!=0){write_date(0x30+c%10);c=c/10;}if(a-b<0)write_date(0x2d);write_date(0x3d);a=0;b=0;flag=0;fuhao=0;}else if(fuhao==3){write_com(0x80+0x4f);write_com(0x04);c=a*b;while(c!=0){write_date(0x30+c%10);c=c/10;}write_date(0x3d);a=0;b=0;flag=0;fuhao=0;}else if(fuhao==4){write_com(0x80+0x4f);write_com(0x04);i=0;c=(long)(((float)a/b)*1000);while(c!=0){write_date(0x30+c%10);c=c/10;i++;if(i==3)write_date(0x2e);}if(a/b<=0)write_date(0x30);write_date(0x3d);a=0;b=0;flag=0;fuhao=0;}}break;case 15:{write_date(0x30+table1[num]);flag=1;fuhao=1;}break;}}}main(){init();while(1){keyscan();}}以下程序才对#include<reg52.h> //头文件#define uint unsigned int //#define uchar unsigned charsbit lcden=P2^5; //定义引脚sbit rs=P2^4;sbit rw=P2^0;sbit busy=P0^7;char chufa=0;char chenfa=0;char jiafa=0;char jianfa=0;/***sbit dula=P2^6;sbit wela=P2^7;***/uchar code table2[]="overflow";char i,j,temp,num,num_1;long a,b,c; //a,第一个数b,第二个数c,得数long a_c,b_c; //floatuchar flag,fuhao;//flag表示是否有符号键按下,fuhao表征按下的是哪个符号uchar code table[]={7,8,9,0,4,5,6,0,1,2,3,0,0,0,0,0};uchar code table1[]={7,8,9,0x2f-0x30,4,5,6,0x2a-0x30,1,2,3,0x2d-0x30,0x01-0x30,0,0x3d-0x30,0x2b-0x30};void delay(uchar z) // 延迟函数{uchar y;for(z;z>0;z--)for(y=0;y<110;y++);}void check() // 判断忙或空闲{do{P0=0xFF;rs=0; //指令rw=1; //读lcden=0; //禁止读写delay(1); //等待,液晶显示器处理数据lcden=1; //允许读写}while(busy==1); //判断是否为空闲,1为忙,0为空闲}void write_com(uchar com) // 写指令函数{P0=com; //com指令付给P0口rs=0;rw=0;lcden=0;check();lcden=1;}void write_date(uchar date) // 写数据函数{P0=date;rs=1;rw=0;lcden=0;check();lcden=1;}void init() //初始化{num=-1;/***dula=0;wela=0;***/lcden=1; //使能信号为高电平write_com(0x38); //8位,2行write_com(0x0c); //显示开,光标关,不闪烁*/write_com(0x06); //增量方式不移位write_com(0x80); //检测忙信号write_com(0x01); //显示开,光标关,不闪烁num_1=0;i=0;j=0;a=0; //第一个参与运算的数b=0; //第二个参与运算的数c=0;flag=0; //flag表示是否有符号键按下,fuhao=0; // fuhao表征按下的是哪个符号}void keyscan() // 键盘扫描程序{P3=0xfe;if(P3!=0xfe){delay(20); //延迟20msif(P3!=0xfe){temp=P3&0xf0;switch(temp){case 0xe0:num=0;break;case 0xd0:num=1;break;case 0xb0:num=2;break;case 0x70:num=3;break;}}while(P3!=0xfe);if(num==0||num==1||num==2)//如果按下的是'7','8'或'9if(j!=0){write_com(0x01);j=0;}if(flag==0)//没有按过符号键{a=a*10+table[num];}else//如果按过符号键{b=b*10+table[num];}}else//如果按下的是'/'{flag=1;fuhao=4;//4表示除号已按chufa++;if (chufa == 2){write_com(0x80);for(num=0;num<8;num++){write_date(table2[num]);delay(5);}//write_date(0x21);chufa = 0;}/*** chenfa++;if(chenfa==1){write_date(0x21);chenfa=0;}***/}i=table1[num];write_date(0x30+i);}if(P3!=0xfd){delay(5);if(P3!=0xfd){temp=P3&0xf0;switch(temp){case 0xe0:num=4;break;case 0xd0:num=5;break;case 0xb0:num=6;break;case 0x70:num=7;break;}}while(P3!=0xfd);if(num==4||num==5||num==6)//如果按下的是'4','5'或'6' {if(j!=0){write_com(0x01);j=0;}if(flag==0)//没有按过符号键{a=a*10+table[num];}else//如果按过符号键{b=b*10+table[num];}}else//如果按下的是'/'{flag=1;fuhao=3;//3表示乘号已按chenfa++;if (chenfa == 2){write_com(0x80);for(num=0;num<8;num++){write_date(table2[num]);delay(5);}//write_date(0x21);chenfa = 0;}}i=table1[num];write_date(0x30+i);}P3=0xfb;if(P3!=0xfb){delay(5);if(P3!=0xfb){temp=P3&0xf0;switch(temp){case 0xe0:num=8;break;case 0xd0:num=9;break;case 0xb0:num=10;break;case 0x70:num=11;break;}}while(P3!=0xfb);if(num==8||num==9||num==10)//如果按下的是'1','2'或'3' {if(j!=0){write_com(0x01);j=0;}if(flag==0)//没有按过符号键{a=a*10+table[num];}else//如果按过符号键{b=b*10+table[num];}}else if(num==11)//如果按下的是'-' {flag=1;fuhao=2;//2表示减号已按jianfa++;if (jianfa == 2){write_com(0x80);for(num=0;num<8;num++){write_date(table2[num]);delay(5);}//write_date(0x21);jianfa = 0;}}i=table1[num];write_date(0x30+i);}P3=0xf7;if(P3!=0xf7){delay(5);if(P3!=0xf7){temp=P3&0xf0;switch(temp){case 0xe0:num=12;break;case 0xd0:num=13;case 0xb0:num=14;break;case 0x70:num=15;break;}}while(P3!=0xf7);switch(num){case 12:{write_com(0x01);a=0;b=0;flag=0;fuhao=0;}//按下的是"清零"break;case 13:{ //按下的是"0"if(flag==0)//没有按过符号键{a=a*10;write_date(0x30);P1=0;}else if(flag==1)//如果按过符号键{b=b*10;write_date(0x30);}}break;case 14:{j=1;rw=0;rs=0;if(fuhao==1){write_com(0x0f);//按下等于键,光标前进至第二行最后一个显示处0x80+0x4fwrite_com(0x04); //设置从后住前写数据,每写完一个数据,光标后退一格c=a+b;delay(10);while(c!=0){write_date(0x30+c%10);//c=c/10;write_date(0x3d); //再写"="a=0;b=0;flag=0;fuhao=0;}else if(fuhao==2){write_com(0x0f);//光标前进至第二行最后一个显示处0x80+0x4fwrite_com(0x04); //设置从后住前写数据,每写完一个数据,光标后退一格if(a-b>0)c=a-b;elsec=b-a;while(c!=0){write_date(0x30+c%10);c=c/10;}if(a-b<0)write_date(0x2d);write_date(0x3d); //再写"="a=0;b=0;flag=0;fuhao=0;}else if(fuhao==3){write_com(0x0f); //0x80+0x4fwrite_com(0x04);c=a*b;while(c!=0){write_date(0x30+c%10);c=c/10;}write_date(0x3d);//write_date(0x30);a=0;b=0;flag=0;fuhao=0;}else if(fuhao==4){write_com(0x40+0x4f); //0x80+0x4fwrite_com(0x04);i=0;c=(long)(((float)a/b)*1000);while(c!=0){write_date(0x30+c%10);c=c/10;if(i==3)write_date(0x2e);}if(a/b<=0)write_date(0x30);write_date(0x3d);a=0;b=0;flag=0;fuhao=0;}}break;case 15:{write_date(0x30+table1[num]);flag=1;fuhao=1;jiafa++;if (jiafa == 2){write_com(0x80);for(num=0;num<8;num++){write_date(table2[num]);delay(5);}//write_date(0x21);jiafa = 0;}}break;}}}/*void key(){P3=0xfe;if(P3!=0xfe){delay(5);if(P3!=oxfe){temp=P3&0xf0;}}}*/main(){init();while(1) {keyscan(); }}。
基于单片机的LCD1602科学计算器设计
![基于单片机的LCD1602科学计算器设计](https://img.taocdn.com/s3/m/426cfd06f78a6529647d53a1.png)
作者: 学号:系:电子工程与光电技术系专业: 电子信息工程题目: 基于单片机的液晶计算器设计南京理工大学毕业设计(论文)评语学生姓名:班级、学号:题目:基于单片机的液晶计算器设计综合成绩:毕业设计(论文)评语毕业设计说明书(论文)中文摘要毕业设计说明书(论文)外文摘要本科毕业设计说明书(论文)第Ⅰ页共Ⅱ页目次1 绪论 (1)1.1 计算器的简介 (1)1.2 单片机的简介与发展趋势 (1)1.3 设计的目的与意义 (2)2 简易计算器的设计实现 (3)2.1 计算器系统模块 (3)2.2 核心控制器选择 (3)2.3 显示电路的设计选择 (3)2.4 键盘设计方案选择 (4)2.4.1 按键消抖方案选择 (4)2.5 本章小结 (4)3 硬件电路设计 (6)3.1 单片机介绍 (6)3.1.1 AT89C52管脚说明 (6)3.2 单片机最小系统 (7)3.2.1 复位电路 (8)3.2.2 时钟电路 (9)3.3 显示模块设计 (9)3.4 按键模块设计 (11)3.5 本章小结 (12)4 软件设计 (13)4.1 系统总设计流程 (13)4.2 按键程序流程设计 (14)4.3 LCD1602显示流程设计 (15)4.4 本章小结 (17)5 功能仿真及其结果 (18)5.1 软件简介 (18)5.1.1 KEIL软件简介 (18)5.1.2 PPOTUES ISIS简介 (18)5.2 仿真结果与操作说明 (18)5.2.1 系统总体仿真 (18)5.2.2 系统的操作说明 (19)5.3 加减乘除四则运算显示结果 (20)5.4 计算器扩展功能的实现 (22)5.4.1 三角函数的实现 (23)5.4.2 对数和指数函数的实现 (24)5.4.3 平方根与倒数以及余数的实现 (26)5.5 本章小结 (27)结论 (28)致谢 (29)参考文献 (30)1 绪论随着科技的日益更新,嵌入式系统与我们的生活愈发息息相关,一些能够使用单片机完成的工具也频繁出现于日常生活中,比如计算器。
基于单片机的计算器设计
![基于单片机的计算器设计](https://img.taocdn.com/s3/m/7bd3415cc4da50e2524de518964bcf84b9d52d96.png)
基于单片机的计算器设计一、设计背景计算器作为一种便携式的计算工具,广泛应用于日常生活和工作中。
随着计算器的智能化程度越来越高,它的功能越来越丰富。
本设计以基于单片机的计算器设计为目标,设计一个具备基本计算功能和显示功能的计算器,能够满足用户的日常计算需求。
二、设计内容1.功能本设计的计算器主要包括基本的算术运算功能,包括加、减、乘、除、取余等。
此外,还应该具备一些常用的科学计算功能,例如开方、平方等。
2.界面计算器采用1602液晶屏作为显示界面,在界面上能够显示输入的数字和计算结果。
液晶屏上可以设置清屏、退格等按钮。
3.输入计算器通过数字按钮和功能按钮进行输入。
数字按钮可以输入0至9的数字,功能按钮可以输入加、减、乘、除等功能选项。
4.输出计算结果将在液晶屏上显示,并且可以选择将计算结果通过串口输出到其他设备。
三、实现思路1.硬件部分本设计需要使用单片机作为计算器的核心处理器,采用1602液晶屏作为显示界面,并通过数字按钮和功能按钮进行输入。
此外,还需要考虑电源部分和按键部分的设计。
2.软件部分软件部分主要是编程实现计算器的各种功能和界面显示。
首先,需要编写界面显示的程序,包括液晶屏的初始化和显示结果的函数。
然后,需要编写按键输入的程序,包括数字按钮和功能按钮的检测和响应。
接着,需要编写计算功能的程序,包括加、减、乘、除等基本运算以及一些科学计算的函数。
最后,需要编写串口输出的程序,将计算结果输出到其他设备。
四、实施计划1.硬件部分首先,需要确定所需的单片机型号,并进行相应的硬件电路设计,包括电源部分、按键部分等。
然后可以开始进行电路制版和焊接工作。
2.软件部分首先,需把液晶屏控制程序编写好,实现液晶屏初始化和显示功能。
然后,编写键盘输入程序,实现数字按钮和功能按钮的响应。
接着,编写计算功能程序,实现加、减、乘、除等基本运算以及科学计算函数。
最后,编写串口输出程序,实现计算结果的输出。
3.调试测试完成软硬件部分的设计后,需要对整个计算器进行调试和测试。
自制1602显示计算器(8位)
![自制1602显示计算器(8位)](https://img.taocdn.com/s3/m/df6b27d0c1c708a1284a4411.png)
double sqr(double x1);
sbit lcdrs = P1^0;
sbit lcden = P1^1;
uchar code kaiji1[]=" Welcome use "; //16
uchar code kaiji2[]=" Zhenyu jisuanqi"; //16
}
while(temp!=0xf0) //释放按键
{
temp=P3;
temp=temp&0xf0;
}
}
}
P3=0xfd;
temp=P3;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(5);
{
write_date(lcd_show[KeyNO]);
point=1;
}
figure='.';
break;
case 0xb7:KeyNO=14;pattern=op_key;operator=5;priority=1;break;//第14个键,功能键op_key,operator操作5,执行=运算,priority优先权为1
uchar pre_operator=0; //
uchar code lcd_show[]={0x37,0x38,0x39,0x2B, //对应键盘显示:789+;456-;123*;0.=/;
0x34,0x35,0x36,0x2d,
0x31,0x32,0x33,0x78,
case 0xbd:KeyNO=6;pattern=num_key;figure=6;break;
基于51单片机的lcd1602液晶显示的计算器
![基于51单片机的lcd1602液晶显示的计算器](https://img.taocdn.com/s3/m/9ee66b33e009581b6ad9eb7f.png)
基于51单片机的lcd 1602液晶显示的计算器/**************************************************************** 阿斌独家制作:计算器,1602液晶显示可计算10以下数加减乘除可连续运算,最大显示结果数值65536*****************************************************************/ 键盘设置:液晶初始显示:运算显示:主程序:#include<reg52.h>#include <intrins.h> #define uint unsigned int #define uchar unsigned char sbit lcden=P2^2;sbit lcdrw=P2^1;sbit lcdrs=P2^0;uchar num,temp,jia=0,jian=0,cheng=0,chu=0,qing=0;uint key,key1,shu;uchar fuhao,flag1,flag=0; uchar table[]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x0}; void delay(uint z) {uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--); }bit lcd_bz(){bit result;lcdrs=0;lcdrw=1;lcden=1;_nop_();_nop_();_nop_();_nop_();result=(bit)(P0&0x80);lcden=0;return result; }void write_com(uchar com){while(lcd_bz());lcdrs=0;lcden=0;lcdrw=0;P0=com;delay(5);lcden=1;delay(5);lcden=0; }void write_date(uchar date) {while(lcd_bz());lcdrs=1;lcden=0;lcdrw=0;P0=date;delay(5);lcden=1;delay(5);lcden=0;}void lcd_init() {lcden=0;write_com(0x38);write_com(0x0c);write_com(0x06);write_com(0x01); }void keyscan() {P3=0xfe;temp=P3;temp=temp&0xf0;while(temp!=0xf0){delay(5);temp=P3;temp=temp&0xf0;while(temp!=0xf0){temp=P3;switch(temp){case 0xee:key=1;num=0;break; case 0xde:key=2;num=0;break; case 0xbe:key=3;num=0;break; case 0x7e:num=1;break; //加号}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}P3=0xfd;temp=P3;temp=temp&0xf0;while(temp!=0xf0){delay(5);temp=P3;temp=temp&0xf0;while(temp!=0xf0){temp=P3;switch(temp){case 0xed:key=4;num=0;break; case 0xdd:key=5;num=0;break; case 0xbd:key=6;num=0;break; case 0x7d:num=2;break; //减号}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}P3=0xfb;temp=P3;temp=temp&0xf0;while(temp!=0xf0){delay(5);temp=P3;temp=temp&0xf0;while(temp!=0xf0){temp=P3;switch(temp){case 0xeb:key=7;num=0;break; case 0xdb:key=8;num=0;break; case 0xbb:key=9;num=0;break; case 0x7b:num=3;break; //乘号}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}P3=0xf7;temp=P3;temp=temp&0xf0;while(temp!=0xf0){delay(5);temp=P3;temp=temp&0xf0;while(temp!=0xf0){temp=P3;switch(temp){case 0xe7:key=0;num=0;break; case 0xd7:num=6;break; //清除case 0xb7:num=5;break; //等于号case 0x77:num=4;break; //除号}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}}void display0(uint shu) { uint ge;ge=shu;write_date(0x30+ge); } void display1(uint shu) { uint shi,ge;shi=shu/10;ge=shu%10;write_date(0x30+shi); write_date(0x30+ge); } void display2(uint shu) { uint bai,shi,ge;bai=shu/100;shi=shu%100/10;ge=shu%10;write_date(0x30+bai); write_date(0x30+shi); write_date(0x30+ge); } void display3(uint shu) {uint qian,bai,shi,ge;qian=shu/1000;bai=shu%1000/100;shi=shu%100/10;ge=shu%10;write_date(0x30+qian);write_date(0x30+bai);write_date(0x30+shi);write_date(0x30+ge); }void display4(uint shu) {uint wan,qian,bai,shi,ge;wan=shu/10000;qian=shu%10000/1000;bai=shu%1000/100;shi=shu%100/10;ge=shu%10;write_date(0x30+wan);write_date(0x30+qian);write_date(0x30+bai);write_date(0x30+shi);write_date(0x30+ge); }void display_key1(uint result) {if(flag1==1){write_com(0x01);flag1=0;}shu=result;write_com(0x80);if(result<10)display0(result);if(result>=10&&result<100) display1(result);if(result>=100&&result<1000) display2(result);if(result>=1000&&result<10000) display3(result);if(result>=10000)display4(result);}void dis_key(result){if(result<10)display0(result);if(result>=10&&result<100) display1(result);if(result>=100&&result<1000)display2(result);if(result>=1000&&result<10000) display3(result);if(result>=10000)display4(result);}void display_key(uint result) { if(shu<10){write_com(0x80+2);dis_key(result);}if(shu>=10&&shu<100){write_com(0x80+3);dis_key(result);}if(shu>=100&&shu<1000){write_com(0x80+4);dis_key(result);}if(shu>=1000&&shu<10000){write_com(0x80+5);dis_key(result);}if(shu>=10000){write_com(0x80+6);dis_key(result);}}void display_fuhao(){switch(fuhao){case 1: write_date(0x2b);break; case 2: write_date(0x2d);break; case 3: write_date(0x2a);break; case 4: write_date(0x2f);break; }fuhao=0;}void fuhao_pan(){if(flag1==1){flag1=0;write_com(0x01);write_com(0x80+1); display_fuhao();}if(shu<10)write_com(0x80+1);if(shu>=10&&shu<100) write_com(0x80+2);if(shu>=100&&shu<1000) write_com(0x80+3);if(shu>=1000&&shu<10000) write_com(0x80+4);if(shu>=10000)write_com(0x80+5); display_fuhao();flag=1;}void fuhao_deng(){write_com(0x80+0x40); write_date(0x3d);flag1=1;flag=0;}void display_result(uint result) {write_com(0x80+0x40+1);if(result<10)display0(result);if(result>=10&&result<100) display1(result);if(result>=100&&result<1000) display2(result);if(result>=1000&&result<10000) display3(result);if(result>=10000)display4(result); }void jia1(){jia=1;jian=cheng=chu=qing=0;key1=key;fuhao=1;fuhao_pan();}void jian1(){jian=1;jia=cheng=chu=qing=0; key1=key;fuhao=2;fuhao_pan(); }void cheng1() {cheng=1;jia=jian=chu=qing=0; key1=key;fuhao=3;fuhao_pan(); }void chu1() {chu=1;jia=jian=cheng=qing=0; key1=key;fuhao=4;fuhao_pan();}void qing1() {qing=1;jia=jian=cheng=chu=0; key1=key=0; }void deng1() {if(jia)key=key1+key;if(jian)key=key1-key;if(cheng)key=key1*key;if(chu)key=key1/key;fuhao_deng();display_result(key);jia=jian=cheng=chu=qing=0;}void deal(){switch(num){case 0:{switch(flag){case 0: display_key1(key);break; case 1: display_key(key);break; }} break;case 1: jia1();break;case 2: jian1();break; case 3: cheng1();break; case 4: chu1();break; case 5: deng1();break; case 6: qing1();break; }}void main(){lcd_init();while(1){keyscan();deal();}}。
STC51单片机开发板计算器LCD1602显示浮点计算设计报告
![STC51单片机开发板计算器LCD1602显示浮点计算设计报告](https://img.taocdn.com/s3/m/51cfb2d3f8c75fbfc67db214.png)
嵌入式系统原理及应用课程设计报告姓名:学号:指导老师:目录引言 (3)第一章硬件介绍 (4)1.1单片机介绍 (4)1.2 设计所用开发板的介绍 (5)1.3 LCD1602的原理及其应用 (7)1.3.1开发板硬件连接关系 (7)1.3.2液晶屏LCD1602的功能及应用 (8)1.3.31602LCD的指令说明及时序 (9)1.3.4 1602LCD的RAM地址映射及标准字库表 (11)1.4开发板矩阵键盘原理及应用 (12)第二章设计思路、仿真及调试 (15)2.1 设计方法 (15)2.2 硬件简介 (15)2.3 软件设计 (15)2.3.1 矩阵键盘 (15)2.3.2 LCD1602 (22)第三章设计结果 (24)第四章设计总结 (27)附录 (28)引言目前单片机渗透到我们生活的各个领域.几乎很难找到哪个领域没有单片机的踪迹。
导弹的导航装置.飞机上各种仪表的控制.计算机的网络通讯与数据传输.工业自动化过程的实时控制和数据处理.广泛使用的各种智能IC卡.民用豪华轿车的安全保障系统.录像机、摄像机、全自动洗衣机的控制.以及程控玩具、电子宠物等等.这些都离不开单片机。
更不用说自动控制领域的机器人、智能仪表、医疗器械了。
因此.单片机的学习、开发与应用将造就一批计算机应用与智能化控制的科学家、工程师。
单片机广泛应用于仪器仪表、家用电器、医用设备、航空航天、专用设备的智能化管理及过程控制等领域.大致可分如下几个范畴:(1)在智能仪器仪表上的应用(2)在工业控制中的应用(3)在家用电器中的应用(4)在计算机网络和通信领域中的应用(5)单片机在医用设备领域中的应用(6)在各种大型电器中的模块化应用(7)单片机在汽车设备领域中的应用此外.单片机在工商.金融.科研、教育.国防航空航天等领域都有着十分广泛的用途。
随着智能化的逐步提高.单片机在我们生活中得到了越来越广泛的应用.其是一种集成在电路芯片.是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU、随机存储器RAM、只读存储器ROM、多种I/O口和中断系统、定时器/计时器等功能(可能还包括显示驱动电路、脉宽调制电路、模拟多路转换器、A/D转换器等电路)集成到一块硅片上构成的一个小而完善的计算机系统。
基于51单片机1602显示的简单计算机
![基于51单片机1602显示的简单计算机](https://img.taocdn.com/s3/m/44fd9317964bcf84b9d57bba.png)
图3-1所示为简易计算器的电路原理图。
P3口用于键盘输入,接4*4矩阵键盘,键值与键盘的对应表如表----所示,p0口和p2口用于显示,p2口用于显示数值的高位,po口用于显示数值的低位。
/*注:4 X4 矩阵接P3口*/#include<reg52.h>#include<stdio.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int#define CHECK_BUSYsbit RS = P3^5;sbit RW = P3^6;sbit EN = P3^4;void Delay(int z){int x,y;for (x=z;x>0;x--)for(y=110;y>0;y--);}/***********判忙函数***********/bit LCD_Check_Busy(){P0= 0xFF;RS=0;RW=1;EN=0;_nop_();EN=1;return (bit)(P0 & 0x80);#elsereturn 0;}/***********写入命令函数***********/ void write_com(uchar com){while(LCD_Check_Busy()); //忙则等待RS=0;RW=0;EN=1;P0= com;_nop_();EN=0;}/**********写入数据函数**********/ void write_dat(uchar dat){while(LCD_Check_Busy()); //忙则等待RS=1;RW=0;EN=1;P0= dat;_nop_();EN=0;}/*******写入字符函数***********/void LCD_Write_Char(uchar x,uchar y,uchar dat){if (y == 0){write_com(0x80 + x);}else{write_com(0xC0 + x);}write_dat( dat);}/******写入字符串函数***********/void Write_String(uchar x,uchar y,uchar *s){while (*s){LCD_Write_Char(x,y,*s);s++;x++;}}/*****初始化函数******/void LCD_Init(){write_com(0x38); /*显示模式设置*/Delay(5);write_com(0x06);/*显示光标移动设置*/Delay(5);write_com(0x0C); /*显示开及光标设置*/write_com(0x01); /*显示清屏*/}/*按键扫描函数,返回扫描键值*/uchar KeyScan() //键盘扫描函数,使用行列反转扫描法{unsigned char cord_h,cord_l;//行列值中间变量P3=0x0f; //行线输出全为0cord_h=P3&0x0f; //读入列线值if(cord_h!=0x0f) //先检测有无按键按下{Delay(10); //去抖if((P3&0x0f)!=0x0f){cord_h=P3&0x0f; //读入列线值P3=cord_h|0xf0; //输出当前列线值cord_l=P3&0xf0; //读入行线值while((P3&0xf0)!=0xf0);//等待松开并输出return(cord_h+cord_l);//键盘最后组合码值}}return(0xff); //返回该值}unsigned char KeyPro(){switch(KeyScan()){case 0x7e:return '+';break;case 0x7d:return '-';break;case 0x7b:return 'x';break;case 0x77:return '/';break;case 0xbe:return '3';break;case 0xbd:return '6';break;case 0xbb:return '9';break;case 0xb7:return '=';break;case 0xde:return '2';break;case 0xdd:return '5';break;case 0xdb:return '8';break;case 0xd7:return '0';break;case 0xee:return '1';break;case 0xed:return '4';break;case 0xeb:return '7';break;case 0xe7:return '0';break;default:return 0xff;break;}}main(){unsigned char num,i,sign;unsigned char temp[16]; //最大输入16个bit firstflag;float a=0,b=0;unsigned char s;LCD_Init(); //初始化液晶屏Delay(10);//延时用于稳定,可以去掉write_com(0x01); //清屏while (1) //主循环{num=KeyPro(); //扫描键盘if(num!=0xff) //如果扫描是按键有效值则进行处理{if(i==0) //输入是第一个字符的时候需要把改行清空,方便观看write_com(0x01);if(('+'==num)|| (i==16) || ('-'==num) || ('x'==num)|| ('/'==num) || ('='==num))//输入数字最大值16,输入符号表示输入结束{i=0; //计数器复位if(firstflag==0) //如果是输入的第一个数据,赋值给a,并把标志位置1,到下一个数据输入时可以跳转赋值给b{sscanf(temp,"%f",&a);firstflag=1;}elsesscanf(temp,"%f",&b);for(s=0;s<16;s++) //赋值完成后把缓冲区清零,防止下次输入影响结果temp[s]=0;LCD_Write_Char(0,1,num);if(num!='=') //判断当前符号位并做相应处理sign=num; //如果不是等号记下标志位else{firstflag=0; //检测到输入=号,判断上次读入的符合switch(sign){case '+':a=a+b;break;case '-':a=a-b;break;case 'x':a=a*b;break;case '/':a=a/b;break;default:break;}sprintf(temp,"%g",a); //输出浮点型,无用的0不输出Write_String(1,1,temp);//显示到液晶屏sign=0;a=b=0; //用完后所有数据清零for(s=0;s<16;s++)temp[s]=0;}}else if(i<16){if((1==i)&& (temp[0]=='0') )//如果第一个字符是0,判读第二个字符{if(num=='0') //如果是小数点则正常输入,光标位置加1{write_com(0x01);}else{temp[0]=num;i++; //如果是1-9数字,说明0没有用,则直接替换第一位0LCD_Write_Char(0,0,num);//输出数据}}else{temp[i]=num;LCD_Write_Char(i,0,num);//输出数据i++;}}}}}。
Lcd1602简易计算器
![Lcd1602简易计算器](https://img.taocdn.com/s3/m/09b80bce360cba1aa811dae0.png)
Lcd1602显示实现千位数加减乘除用4*4矩阵按键输入0~9 +,-,*,/,=,和清除建#include<reg51.h>#define temp P3sbit RS=P0^0;sbit RW=P0^1;sbit E =P0^2;unsigned char key_num;unsigned char lcd_tab3[16]=" ";unsigned char code lcd_tab4[]="0123456789+-*/=";unsigned char lcd_tab5[16]=" ";unsigned char lcd_tab6[]=" ";unsigned char lcd_tab7[]=".";int a,b,c,d,m,i;void decide();long int key_cnt=0,key_number,key_number1;unsigned char flag1=0,flag2=0,flag3=0,flag4=0,flag5=0;long int result, result1, result2, result3, result4,result5, result6, result7, result8;int decimal0,decimal1;delay_nms(unsigned int i){unsigned int j;for(;i!=0;i--){for(j=0;j<61;j++);}}key_scan(void){unsigned char a;temp=0xf0;if(temp!=0xf0){delay_nms(10);{if(temp!=0xf0)switch(temp){case 0xe0 :key_num= 0; break;case 0xd0 :key_num= 1; break;case 0xb0 :key_num= 2; break;case 0x70 :key_num= 3; break;}temp=0x0f;switch(temp){case 0x0e :key_num=key_num; break;case 0x0d :key_num= key_num+4; break;case 0x0b :key_num= key_num+8; break;case 0x07 : key_num=key_num+12; break;default :break;}while((a<50)&&( temp!=0x0f)){delay_nms(1);a++;}temp=0xf0;}}return (key_num);}void write_com(char cod){E=0;RS=0;RW=0;E=1;delay_nms(1);P2=cod;E=0;delay_nms(1);}void write_data(char pat){E=0;RS=1;RW=0;E=1;delay_nms(1);P2=pat;E=0;delay_nms(1);}void write_clean(){write_com(0x38);write_com(0x01);write_com(0x06);write_com(0x0c);}void input(){unsigned char i,x;write_com(0x80);for(i=0;i<16;i++){write_data(lcd_tab3[i]);delay_nms(1);}write_com(0xc0);{for(x=0;x<16;x++){write_data(lcd_tab5[x]);delay_nms(1);}}}void display(){if(flag5==0){lcd_tab5[0]=lcd_tab4[key_num];lcd_tab5[2]=lcd_tab4[result7];lcd_tab5[3]=lcd_tab4[result6];lcd_tab5[4]=lcd_tab4[result5];lcd_tab5[5]=lcd_tab4[result4];lcd_tab5[6]=lcd_tab4[result3];lcd_tab5[7]=lcd_tab4[result2];lcd_tab5[8]=lcd_tab4[result1];if((decimal0!=0)||(decimal1!=0)){lcd_tab5[9]=lcd_tab7[0];lcd_tab5[10]=lcd_tab4[decimal1];lcd_tab5[11]=lcd_tab4[decimal0];}i=0;decide();}else{lcd_tab5[0]=lcd_tab4[key_num];lcd_tab5[1]=lcd_tab4[11];lcd_tab5[2]=lcd_tab4[result8];lcd_tab5[3]=lcd_tab4[result7];lcd_tab5[4]=lcd_tab4[result6];lcd_tab5[5]=lcd_tab4[result5];lcd_tab5[6]=lcd_tab4[result4];lcd_tab5[7]=lcd_tab4[result3];lcd_tab5[8]=lcd_tab4[result2];lcd_tab5[9]=lcd_tab4[result1];i=1;decide();}}void decide(){if(lcd_tab5[1+i]==lcd_tab4[0]){lcd_tab5[1+i]=lcd_tab5[2+i];lcd_tab5[2+i]=lcd_tab5[3+i];lcd_tab5[3+i]=lcd_tab5[4+i];lcd_tab5[4+i]=lcd_tab5[5+i];lcd_tab5[5+i]=lcd_tab5[6+i];lcd_tab5[6+i]=lcd_tab5[7+i];lcd_tab5[8+i]=lcd_tab5[9];lcd_tab5[9]=lcd_tab5[10];lcd_tab5[10]=lcd_tab5[11];lcd_tab5[11]=lcd_tab6[0];if(lcd_tab5[1+i]==lcd_tab4[0]) {lcd_tab5[1+i]=lcd_tab5[2+i];lcd_tab5[2+i]=lcd_tab5[3+i];lcd_tab5[3+i]=lcd_tab5[4+i];lcd_tab5[4+i]=lcd_tab5[5+i];lcd_tab5[5+i]=lcd_tab5[6+i];lcd_tab5[6+i]=lcd_tab5[7+i];lcd_tab5[7+i]=lcd_tab5[8+i];lcd_tab5[8+i]=lcd_tab5[9];lcd_tab5[9]=lcd_tab5[10];lcd_tab5[10]=lcd_tab6[0];lcd_tab5[11]=lcd_tab6[0];if(lcd_tab5[1+i]==lcd_tab4[0]) {if(lcd_tab5[1+i]==lcd_tab4[0]) {lcd_tab5[1+i]=lcd_tab5[2+i];lcd_tab5[2+i]=lcd_tab5[3+i];lcd_tab5[3+i]=lcd_tab5[4+i];lcd_tab5[4+i]=lcd_tab5[5+i];lcd_tab5[5+i]=lcd_tab5[6+i];lcd_tab5[6+i]=lcd_tab5[7+i];lcd_tab5[7+i]=lcd_tab5[8+i];lcd_tab5[8+i]=lcd_tab5[9];lcd_tab5[9]=lcd_tab6[0];lcd_tab5[10]=lcd_tab6[0];lcd_tab5[11]=lcd_tab6[0];if(lcd_tab5[1+i]==lcd_tab4[0]) {lcd_tab5[1+i]=lcd_tab5[2+i];lcd_tab5[2+i]=lcd_tab5[3+i];lcd_tab5[3+i]=lcd_tab5[4+i];lcd_tab5[4+i]=lcd_tab5[5+i];lcd_tab5[5+i]=lcd_tab5[6+i];lcd_tab5[6+i]=lcd_tab5[7+i];lcd_tab5[7+i]=lcd_tab5[8+i];lcd_tab5[8+i]=lcd_tab6[0];lcd_tab5[9]=lcd_tab6[0];lcd_tab5[10]=lcd_tab6[0];lcd_tab5[11]=lcd_tab6[0];if(lcd_tab5[1+i]==lcd_tab4[0]){lcd_tab5[1+i]=lcd_tab5[2+i];lcd_tab5[2+i]=lcd_tab5[3+i];lcd_tab5[3+i]=lcd_tab5[4+i];lcd_tab5[4+i]=lcd_tab5[5+i];lcd_tab5[5+i]=lcd_tab5[6+i];lcd_tab5[6+i]=lcd_tab5[7+i];lcd_tab5[7+i]=lcd_tab6[0];lcd_tab5[8+i]=lcd_tab6[0];lcd_tab5[9]=lcd_tab6[0];lcd_tab5[10]=lcd_tab6[0];lcd_tab5[11]=lcd_tab6[0];if(lcd_tab5[1+i]==lcd_tab4[0]) {lcd_tab5[1+i]=lcd_tab5[2+i];lcd_tab5[2+i]=lcd_tab5[3+i];lcd_tab5[3+i]=lcd_tab5[4+i];lcd_tab5[4+i]=lcd_tab5[5+i];lcd_tab5[5+i]=lcd_tab5[6+i];lcd_tab5[6+i]=lcd_tab6[0];lcd_tab5[7+i]=lcd_tab6[0];lcd_tab5[8+i]=lcd_tab6[0];lcd_tab5[9]=lcd_tab6[0];lcd_tab5[10]=lcd_tab6[0];lcd_tab5[11]=lcd_tab6[0];if(lcd_tab5[1+i]==lcd_tab4[0]) {lcd_tab5[1+i]=lcd_tab5[2+i];lcd_tab5[2+i]=lcd_tab5[3+i];lcd_tab5[3+i]=lcd_tab5[4+i];lcd_tab5[4+i]=lcd_tab5[5+i];lcd_tab5[5+i]=lcd_tab6[0];lcd_tab5[6+i]=lcd_tab6[0];lcd_tab5[7+i]=lcd_tab6[0];lcd_tab5[8+i]=lcd_tab6[0];lcd_tab5[9]=lcd_tab6[0];lcd_tab5[10]=lcd_tab6[0];lcd_tab5[11]=lcd_tab6[0];}}}}}}}}}void lcd_shiftl(void){lcd_tab3[0]=lcd_tab3[1];lcd_tab3[1]=lcd_tab3[2];lcd_tab3[2]=lcd_tab3[3];lcd_tab3[3]=lcd_tab3[4];lcd_tab3[4]=lcd_tab3[5];lcd_tab3[5]=lcd_tab3[6];lcd_tab3[6]=lcd_tab3[7];lcd_tab3[7]=lcd_tab3[8];lcd_tab3[8]=lcd_tab3[9];lcd_tab3[9]=lcd_tab3[10];lcd_tab3[10]=lcd_tab3[11];lcd_tab3[11]=lcd_tab3[12];lcd_tab3[12]=lcd_tab3[13];lcd_tab3[13]=lcd_tab3[14];lcd_tab3[14]=lcd_tab3[15];lcd_tab3[15]=lcd_tab4[key_num];}void displasis(){int i;for(i=0;i<16;i++){lcd_tab3[i]=lcd_tab6[0];}for(i=0;i<16;i++){lcd_tab5[i]=lcd_tab6[0];}key_cnt=key_number=key_number1=0;a=b=c=d=0;result=result1=result2=result3=result4=result5=result6=result7=result8=0;flag1=0,flag2=0,flag3=0,flag4=0,flag5=0;decimal0=0;decimal1=0;}void main(){while(1){write_clean();input();m=1;while(m){P3=0xf0;if(P3!=0xf0){m=0;}}P3=0xf0;if(P3!=0xf0){key_scan();if(key_num<=9){if(key_cnt<4){switch(key_cnt){case 0: a=key_num ; break;case 1: a=a*10 ;b=key_num; a=a+b; break;case 2: a=a*10 ;c=key_num; a=a+c; break;case 3: a=a*10 ;d=key_num; a=a+d; break;}lcd_shiftl();key_cnt++;}while(P3!=0xf0){;}}if(key_num==10)//加法{flag1=1;key_number=a;a=b=c=d=0;key_cnt=0;lcd_shiftl();while(P3!=0xf0){;}}if(key_num==11)//减法{flag2=1;key_number=a;a=b=c=d=0;key_cnt=0;lcd_shiftl();while(P3!=0xf0){;}}if(key_num==12)//乘法{flag3=1;key_number=a;a=b=c=d=0;key_cnt=0;lcd_shiftl();while(P3!=0xf0){;}}if(key_num==13)//除法{flag4=1;key_number=a;a=b=c=d=0;key_cnt=0;lcd_shiftl();while(P3!=0xf0){;}}if(key_num==14){while(P3!=0xf0){;}key_number1=a;a=b=c=d=0;key_cnt=0;if((flag1==1)&&(key_number1!=0)){result=key_number+key_number1;//加法运算result1= result%10;result2= result/10%10;result3= result/100%10;result4= result/1000%10;result5= result/10000%10;result6= result/100000%10;result7= result/1000000%10;result8= result/10000000;delay_nms(2);key_number1=0 ;key_number=result;display();}if((flag2==1)&&(key_number1!=0))//减法运算{result=key_number-key_number1;if(result<0){result=key_number1-key_number;flag5=1;}result1= result%10;result2= result/10%10;result3= result/100%10;result4= result/1000%10;result5= result/10000%10;result6= result/100000%10;result7= result/1000000%10;result8= result/10000000;delay_nms(2);key_number1=0 ;key_number=result;display();}if((flag3==1)&&(key_number1!=0)){result=key_number*key_number1;//乘法运算result1= result%10;result2= result/10%10;result3= result/100%10;result4= result/1000%10;result5= result/10000%10;result6= result/100000%10;result7= result/1000000%10;result8= result/10000000;delay_nms(2);key_number1=0 ;key_number=result;display();}if((flag4==1)&&(key_number1!=0))//除法运算{result=key_number/key_number1;decimal0=((key_number*100)/key_number1)%10;//小数各位decimal1=((key_number*100)/key_number1)/10%10;//小数十位result1= result%10;result2= result/10%10;result3= result/100%10;result4= result/1000%10;result5= result/10000%10;result6= result/100000%10;result7= result/1000000%10;result8= result/10000000;delay_nms(2);key_number1=0 ;key_number=result;display();}}if(key_num==15){while(P3!=0xf0){;}displasis();}}}}。
(最终)1602显示的计算器
![(最终)1602显示的计算器](https://img.taocdn.com/s3/m/3e382606581b6bd97f19eae7.png)
基于单片机的1602显示的简易计算器刘哲电子121 学号2012131017摘要:单片机是一个单芯片形式、面向控制对象的嵌入式应用计算机系统。
他的出现及发展是计算机技术从通用型数值计算领域进入到智能化的控制领域。
从此,计算机技术在两个重要领域——通用计算机领域和嵌入式计算机领域都得到了极其重要的发展,并正在深深地改变我们的社会。
本设计是基于51单片机来进行的数值计算器系统的设计,可以完成计算器的键盘输入,进行加减乘除八位数范围内的基本四则运算,并在LCD上显示出来。
涉及电路采用AT89C51单片机为主要控制电路,利用4*4矩阵键盘作为计算器的数字以及运算符的输入,显示采用字符LCD静态显示。
软件方面使用C语言编程,并用开发板制作和演示。
关键词:51单片机,矩阵键盘,LCD,运算器1 引言本次课程设计,我是基于单片机STC89C51的控制能力,使用包括单片机芯片,1602液晶显示屏,行列式键盘等来设计一个简单的计算器,本计算器因为按键的关系,仅实现了加减乘除四个基本计算法则的运算,初步实现了一个计算器所具有的基本功能。
2 总体架构2.1 设计预想本设计使用STC89C52单片机作为主控芯片,利用矩阵键盘输入0~9十个数值和加减乘除四个运算法则,通过芯片的运算,在LCD上显示过程和结果。
2.2 设计思路根据课程设计要求和设计指标,本系统采用STC89C52作为主控芯片,通过拓展必要的外部电路,实现对计算器的设计,具体设计思路如下:由于要显示的运算式和结果,为了达到良好的显示效果,本系统采用LCD1602液晶显示屛作为显示模块。
计算器一般包括数字键(0~9),符号键(+、—、*、/),清零按键,等号按键,故采用4*4矩阵键盘结合键盘扫描技术容易达到要求,并且电路和程序也比较简单。
鉴于本设计的计算器的难度和功能上的要求,在本设计中决定使用语言功能丰富,表达能力强,使用方便灵活,可移植性好的C语言编程,这样有利于减少工作量和代码量,提高设计效率。
基于511602的可连续运算计算器
![基于511602的可连续运算计算器](https://img.taocdn.com/s3/m/ec894c41a8956bec0975e371.png)
#include <reg51.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#include "LCD1602.h"#define uchar unsigned char uchar k=0,result1;void shortdelay(uchar i)//短延时{for(;i>0;i--);}//长延时void longdelay(uint i){uint j;for(;i>0;i--){for(j=100;j>0;j--);}}//延时程序void delay(int i){int j;for(;i>0;i--)for(j=0;j<100;j++);}//初试状态void io_init(){P1=0xff;}//?---------------------------键盘扫描部分-----------------------------//unsigned char key_scan(){ unsigned char key;unsigned char temp;uint flag;io_init();P1=0xf0;flag=0;loop: temp=P1^0xf0;while(temp){P1=0xfe;delay(1);if((P1&0xfe)!=0xfe)switch(P1){case 0xee: key=0x11;flag=1;break;//读7键和值case 0xde: key=0x12;flag=1;break;case 0xbe: key=0x13;flag=1;break;case 0x7e: key=0x14;flag=1;break;//读除键的值}if(flag)goto exit;elseP1=0xfd;delay(1);if((P1&0xfd)!=0xfd)switch(P1){case 0xed: key=0x21;flag=1;break;case 0xdd: key=0x22;flag=1;break;case 0xbd: key=0x23;flag=1;break;case 0x7d: key=0x24;flag=1;break; //读4到乘的键值}if(flag)goto exit;elseP1=0xfb;delay(1);if((P1&0xfb)!=0xfb)switch(P1){case 0xeb: key=0x31;flag=1;break;case 0xdb: key=0x32;flag=1;break;case 0xbb: key=0x33;flag=1;break;case 0x7b: key=0x34;flag=1;break;//读1到减的键值}if(flag)goto exit;elseP1=0xf7;delay(1);if((P1&0xf7)!=0xf7)switch(P1){case 0xe7: key=0x41;flag=1;break;//后退case 0xd7: key=0x42;flag=1;break;//0case 0xb7: key=0x43;flag=1;break;//等于case 0x77: key=0x44;flag=1;break;//加}exit: return key;}if(temp==0)goto loop;}//---------------------------------键盘扫描完--------------------------------------------// //---------------------------------显示初始化?----------------------------------------// //P0口初始化void initpindata(bit i){if(i==1) pindata=0xff;else pindata=0X00;}//寄存器选择信号void setRS(bit i){if(i==1) pinRS=1;else pinRS=0;}//读写操作控制void setRW(bit i){if(i==1) pinRW=1;else pinRW=0;}//使能信号void setE(bit i){if(i==1) pinE=1;else pinE=0;}//读BF以及AC的值uint read_BF_AC(){uint temp;initpindata(1);setRS(0);setRW(1);setE(1);shortdelay(1);temp=pindata;shortdelay(10);setE(0);return(temp);}//判忙bit statuscheck(){return((bit)(read_BF_AC()&0x80)); }//写指令函数void writeinstruc(uint instruc){while(statuscheck()); initpindata(0);setRS(0);setRW(0);setE(0);pindata=instruc;//short delay(1);setE(1);shortdelay(10);setE(0);}//写数据到RAMvoid writedata(uint data1){initpindata(0);setRS(1);setRW(0);setE(0);pindata=data1;setE(1);shortdelay(10);setE(0);}//从RAM中读数据函数uint readdata(void){uint temp;initpindata(1);setRS(1);setRW(1);setE(1);shortdelay(1);temp=pindata;shortdelay(10);setE(0);return(temp);}//显示程序X为行号,Y为列号,date为要显示的数据void dispcharacter(int x,uint y,uint data1){uint temp;while(statuscheck());temp=y&0x0f;x&=0x01;if(x) temp|=0x40;setDDRAM_Add(temp);writedata(data1);// writedata(data1);}//LCD复位函数void LCDreset(){clearscreen();cursorreturn();}//LCD初始化void initLCD(){LCDreset();inputmode(0x06);//增量方式,不移位dispcontrol(0x0c);//显示开,光标关,闪烁关functionset(0x38);//8位,2行,5*7}//-----------------------------------准备工作完成-----------------------------------// //-----------------------------------计算器-----------------------------------------//compute(char key1,i){signed char m,n,c,act;long int num1,num2,result;signed char str[4][4]={{'7','8','9','/'},{'4','5','6','*'},{'1','2','3','-'},{'c','0','=','+'}};signed char str1[11],string1[2];m=(key1&0xf0);m=m/16;m=m-1;n=key1&0x0f;n=n-1;c=str[m][n];sprintf(string1,"%c",c);strcat(str1,string1);if((c=='+')||(c=='-')||(c=='*')||(c=='/')){act=c;num1=atoi(str1);memset(str1,0,11);memset(string1,0,2);}if(c=='='){num2=atoi(str1);switch(act){case'+':{ if(k==0){result=num1+num2;k++;break;}else{result+=num2;k++;break;}}case'-':{if(k==0){result=num1-num2;k++;break;}else{result-=num2;k++;break;}}case'*':{if(k==0){result=num1*num2;k++;break;}else{result*=num2;k++;break;}}case'/':{if(k==0){result=num1/num2;k++;break;}else{ result/=num2;k++;break;}}}}if(c=='c'){act=0;num1=str1[0];num1=str1[8];memset(str1,0,11);memset(string1,0,2);num1=str1[0];num1=str1[8];k=0;}longdelay(350);switch(key1) //显示部分{case 0x11: dispcharacter(0,i,'7');i++;break; case 0x12: dispcharacter(0,i,'8');i++; break; case 0x13: dispcharacter(0,i,'9');i++; break;case 0x14: dispcharacter(0,i,'/');i++;break; case 0x21: dispcharacter(0,i,'4');i++;break; case 0x22: dispcharacter(0,i,'5');i++;break; case 0x23: dispcharacter(0,i,'6');i++;break; case 0x24: dispcharacter(0,i,'*');i++;break; case 0x31: dispcharacter(0,i,'1');i++;break; case 0x32: dispcharacter(0,i,'2');i++;break; case 0x33: dispcharacter(0,i,'3');i++;break; case 0x34: dispcharacter(0,i,'-');i++;break; case 0x41: clearscreen(); break; case 0x42: dispcharacter(0,i,'0');i++;break; case 0x43: dispcharacter(0,i,'=');i++;m=result/10000;result1=result%10000;if(m!=0||result==0){n=0;m=m+'0';dispcharacter(0,i,m);i++;}m=result1/1000;result1=result1%1000;if(m!=0||n==0){m=m+'0';n=0;dispcharacter(0,i,m);i++;}m=result1/100;result1=result1%100;if(m!=0||n==0){m=m+'0';n=0;dispcharacter(0,i,m);i++;}m=result1/10;result1=result1%10;if(m!=0||n==0){m=m+'0';n=0;dispcharacter(0,i,m);i++;}m=result1;if(m!=0||n==0)m=m+'0';dispcharacter(0,i,m);i++;break;case 0x44: dispcharacter(0,i,'+');i++;break;}return(i);}//---------------------------------------------------------------------------------////-------------------------------------主函数---------------------------------------// void main(){char key1,i;start:initpindata(0);P2=0X00;initLCD();i=0;scan:key1=key_scan();i=compute(key1,i);if(key1==0x41)goto start;elsegoto scan;}#define uint unsigned int#define uchar unsigned charsbit pinRS=P2^0;sbit pinRW=P2^1;sbit pinE=P2^2;#define pindata P0#define clearscreen() writeinstruc(0x01)#define cursorreturn() writeinstruc(0x02)#define inputmode(temp) writeinstruc(temp)//temp取值如下://0x04:减量方式,不移位//0x05:减量方式,移位//0x06:增量方式,不移位//0x07:增量方式,移位#define dispcontrol(temp) writeinstruc(temp)//temp取值如下://0x08:显示关,光标关,闪烁关//0x0c:显示关,光标关,闪烁关//0x0d:显示开,光标关,闪烁开//0x0e:显示开,光标开,闪烁关//0x0f:显示开,光标开,闪烁开#define dispshift(temp) writeinstruc(temp)//temp取值如下://0x10:光标左移//0x14:光标右移//0x18:显示整体左移//0x1c:显示整体右移#define functionset(temp) writeinstruc(temp)//temp取值如下://0x20:4位,1行,5*7//0x24:4位,1行,5*10//0x28:4位,2行,5*7//0x2c:4位,2行,5*10//0x30:8位,1行,5*7//0x34:8位,1行,5*10//0x38:8位,2行,5*7//0x3c:8位,2行,5*10#define setCGRAM_Add(address) writeinstruc(0x40|address)#define setDDRAM_Add(address) writeinstruc(0x80|address)//短延时//void shortdelay(uchar i);//长延时//void longdelay(uint i);//P2口初始化//void initP2(bit i);//寄存器选择信号//void setRS(bit i);//读写操作控制//void setRW(bit i);//使能信号//void setE(bit i);//读BF以及AC的值//uint read_BF_AC();//判忙//bit statuscheck();//写指令函数//void writeinstruc(uint instruc);//写数据到RAM//void writedata(uint data1);//从RAM中读数据函数//uint readdata(void);//显示程序X为行号,Y为列号,date为要显示的数据//void dispcharacter(int x,uint y,uint data1);//LCD复位函数//void LCDreset();。
基于单片机的液晶计算器设计
![基于单片机的液晶计算器设计](https://img.taocdn.com/s3/m/cf845dc533d4b14e85246826.png)
目录1.课程设计的目的 (2)2.课程设计的内容和要求 (2)2.1课程设计内容 (2)2.2课程设计要求 (2)3.课程设计原理 (2)4.课程设计所需器材及其介绍 (2)4.1课程设计所需器材 (2)4.2课程设计所需器材介绍 (2)5.课程设计步骤 (6)5.1问题分析 (6)5.2算法设计 (6)5.3功能模块分割 (6)5.4算术运算程序流程图 (6)5.5系统总流程图 (7)5.6仿真电路模型的构建 (7)6.课程设计结果及结论 (7)6.1课程设计结果 (7)6.1.1仿真模型与结果 (7)6.1.2程序设计 (8)7.心得体会 (10)8.参考文献 (10)9.附录……………………………………………………1 11.课程设计的目的通过本课程设计使学生进一步巩固单片机原理与技术的基本概念、基本理论,分析问题的基本方法;增强学生的软件编程实现能力和解决实际问题的能力,使学生能有效地将理论和实际紧密结合,拓展学生在工程实践方面的专业知识和相关技能。
2.课程设计的内容和要求2.1课程设计内容基于液晶显示的简易计算器设计。
2.2目标1.硬件电路包括1602显示屏,4*4键盘。
2.能够显示不少于4位的数字。
3.能够完成1位以上十进制数的加、减、乘、除运算,结果保留至小数点后1位。
4.设计中使用C语言编程。
3.课程设计原理运用MM74C922芯片作为4*4键盘的译码器输入AT89C51单片机内,再植入运算的程序,通过LCD静态显示相关数字,得到计算结果,电路中同时有复位电路,内部时钟模式电路来控制,是电路更稳定。
4.课程设计所需器材及其介绍4.1课程设计所需器材本设计选用AT89C51单片机为主控单元;显示部分:采用LCD静态显示;按键部分:采用4*4键盘;用MM74C922为4*4键盘扫描IC,读取输入的键值。
AT89C51 LM016L MM74C922 4*4键盘4.2课程设计所需器材介绍(1).AT89C51芯片MCS-51 单片机是在一块芯片中集成了CPU、RAM、ROM、定时器/计数器和多功能I/O 等一台计算机所需要的基本功能部件。
51单片机的+1602计算器
![51单片机的+1602计算器](https://img.taocdn.com/s3/m/4c56d46ecbaedd3383c4bb4cf7ec4afe04a1b18c.png)
#include<at89x52.h>#define uchar unsigned char#define uint unsigned int#define ulong unsigned long#define rs P3_5 //指令存放器或数据存放器的选择#define e P3_4 //读写操作的使能信号#define rw P2_7 //读写操作的选择#define BF 0X80 //忙检测标志位uchar code tab1[]={'c',0,'=','+',1,2,3,'-',4,5,6,'*',7,8,9,'/'}; //键盘的对应的数据uchar number; //按键输入键盘号bit flag0=0; //"=〞号按键标志bit flag1=0; //"+〞号按键标志bit flag2=0; //"-〞号按键标志bit flag3=0; //"*〞号按键标志bit flag4=0; //"/〞号按键标志bit fuhao=0; //正负号标志bit point=0; //小数点标志ulong a=0,b=0;//第一个整数存入a,第二个数整数存入buchar code key[]={0xef,0xdf,0xbf,0x7f};//行扫描按键检测void delay<uint z> //延时1ms子程序{uint x,y;for<x=z;x>0;x-->for<y=115;y>0;y-->;}/*************************************************** 1602夜晶显示器***************************************************/uchar busy<> //1602忙碌检测{rs=0;rw=1;e=1;delay<1>;while<P0&BF>;e=0;return P0;}void wdat<uchar dat> //数据在1602显示{P0=dat;busy<>;rs=1;rw=0;delay<5>;e=1;delay<5>;e=0;}void wcmd<uchar cmd,uchar BFC> //写命令或写数据输出到1602的地址{P0=cmd;if<BFC> busy<>;rs=0;rw=0;delay<5>;e=1;delay<5>;e=0;}void init<> //1602初始化{e=0;wcmd<0x38,0>;wcmd<0x38,0>;wcmd<0x38,0>;wcmd<0x38,1>;wcmd<0x08,1>;wcmd<0x01,1>;wcmd<0x06,1>;wcmd<0x0c,1>;}/******************************************4*4键盘,并得到按键值******************************************/void ankey<> //取4*4键盘输入代表键值number{uchar i,j,temp;for<i=0;i<4;i++>{P1=key[i];temp=P1;temp=temp<<4|0x0f;for<j=0;j<4;j++>{if<key[j]==temp>{number=i*4+j;//按键对应的键号switch<number>//对按键作相应的处理{case0:{wcmd<0x01,1>;flag0=0;flag1=0;flag2=0;flag3=0;flag4=0;fuhao=0;point=0;}break; //清零按键case 2:flag0=1;break; //"=〞号按键case 3:{flag1=1;wdat<0x2b>;}break; //"+〞号按键case 7:{flag2=1;wdat<0x2d>;}break; //"-〞号按键case 11:{flag3=1;wdat<0x2a>;}break; //"*〞号按键case 15:{flag4=1;wdat<0x2f>;}break; //"/〞号按键case 4:case 5:case 6:case 8:case 9:case 10:case 12:case 13:case 14:case 1:if<flag2||flag3||flag4||flag1>//不是符号键时,按键对应的数值放入{ //第一个数中,是时,放入第二个数中b=b*10+tab1[number];wdat<0x30+tab1[number]>;//显示所按的键对应的值}else{if<flag0>{flag0=0;wcmd<0x01,1>;wdat<0x30+tab1[number]>; //显示所按的键对应的值}else{a=a*10+tab1[number];wdat<0x30+tab1[number]>;//显示所按的键对应的值}}break;default:break;}}while<key[i]!=P1> //按键是否松开,假如否,如此在4*4键盘对应那个键的行列为低电平P1=key[i];}}}void keysure<>//延时消除按键抖动{P1=0x0f;if<<P1&0x0f>!=0x0f>{delay<10>;if<<P1&0x0f>!=0x0f>ankey<>;}}/***************************************计算器的运算公式与结果输出***************************************/ulong flag00<>{ulong value; //计算结果变量if<flag0==1> //是否按了"=〞,假如是,如此执行运算法如此{if<flag1==1> //加法运算value=a+b;if<flag2==1> //减法运算{if<a>=b> //判断减数的大小value=a-b;else{value=b-a;fuhao=1; //结果是负数的标志位}}if<flag3==1> //乘法运算value=a*b;if<flag4==1> //除法运算{value=<ulong><<<float>a/b>*1000>;point=1;}}return value;}void result<> //结果显示{uchar i=0;ulong value;value=flag00<>;if<flag0==1>{wcmd<0x04,1>;//设置从后住前写数据,每写完一个数据,光标后退一格wcmd<0xcf,0>; //光标至第二行最后一个显示处do{wdat<0x30+value%10>;//显示数值i++;if<point&&i==3> //取3位小数wdat<0x2e>; //显示小数点value/=10;delay<10>;}while<value>; //计算结果输出if<point&&i<3>{while<3-i>{wdat<0x30>;i++;}wdat<0x2e>;wdat<0x30>;}if<fuhao>wdat<0x2d>; //显示负号wdat<0x3d>;flag1=flag2=flag3=flag4=0; //全部清零a=0;b=0;}}void main<>{init<>;while<1>{keysure<>;result<>;}}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
} }
main() { init(); while(1) {
keyscan(); } }
第4章 仿真和调试
下面用KEIL uVision与 porteus仿真软件实现简易计算器的仿真与调试。 4.1 keil 软件的介绍 单片机开发中除必要的硬件外,同样离不开软件,我们写的汇编语言源程序要变为CPU可
delay(20); 延迟20ms if(P3!=0xfe) { temp=P3&0xf0; switch(temp) { case 0xe0:num=0;
break; case 0xd0:num=1; break; case 0xb0:num=2; break; case 0x70:num=3; break; } } while(P3!=0xfe); if(num==0||num==1||num==2)//如果按下的是'7','8'或'9 { if(j!=0)
P3=0xfd; if(P3!=0xfd) {
delay(5); if(P3!=0xfd) { temp=P3&0xf0; switch(temp) { case 0xe0:num=4;
break;
case 0xd0:num=5; break;
case 0xb0:num=6; break;
case 0x70:num=7; break;
case 0xb0:num=14; break;
case 0x70:num=15;
break;
}
}
while(P3!=0xf7);
switch(num)
Байду номын сангаас
{
case 12:{write_com(0x01);a=0;b=0;flag=0;fuhao=0;}//按下的是"清零"
break;
case 13:{
} void write_com(uchar com) // 写指令函数 { P0=com; //com指令付给P0口 rs=0; rw=0; lcden=0; check(); lcden=1; }
void write_date(uchar date) // 写数据函数 {
P0=date; rs=1; rw=0; lcden=0; check(); lcden=1; }
//按下的是"0"
if(flag==0)//没有按过符号键
{
a=a*10;
write_date(0x30);
P1=0; } else if(flag==1)//如果按过符号键 { b=b*10; write_date(0x30); } } break; case 14:{j=1;
if(fuhao==1){write_com(0x80+0x4f);//按下等于键,光标前进至第 二行最后一个显示处
} } while(P3!=0xfd); if(num==4||num==5||num==6&&num!=7)//如果按下的是'4','5'或'6' { if(j!=0)
{ write_com(0x01); j=0; } if(flag==0)//没有按过符号键 { a=a*10+table[num]; } else//如果按过符号键 { b=b*10+table[num]; } } else//如果按下的是'/' { flag=1; fuhao=3;//3表示乘号已按 } i=table1[num]; write_date(0x30+i); }
} i=table1[num]; write_date(0x30+i); }
P3=0xf7; if(P3!=0xf7) {
delay(5); if(P3!=0xf7) { temp=P3&0xf0; switch(temp) { case 0xe0:num=12;
break;
case 0xd0:num=13; break;
功能 0 1 2 3 4 5 6 7 8 9 + - × ÷ = 清零
表3-1
3.2 计算器的软件设计
#include<reg51.h> //头文件 #define uint unsigned int // #define uchar unsigned char
sbit lcden=P2^3; //定义引脚 sbit rs=P2^4; sbit rw=P2^0; sbit busy=P0^7;
3.1 硬件连接 图3-1所示为简易计算器的电路原理图。P3口用于键盘输入,接4*4
矩阵键盘,键值与键盘的对应表如表----所示,p0口和p2口用于显示, p2口用于显示数值的高位,po口用于显示数值的低位。
图3-1 简易计算器电路原理图 键值与功能对应表 键值 0 1 2 3 4 5 6 7 8 9 + - × / = ON/C
num_1=0; i=0; j=0; a=0; //第一个参与运算的数 b=0; //第二个参与运算的数 c=0; flag=0; //flag表示是否有符号键按下, fuhao=0; // fuhao表征按下的是哪个符号 } void keyscan() // 键盘扫描程序 {
P3=0xfe; if(P3!=0xfe) {
void delay(uchar z) // 延迟函数 { uchar y; for(z;z>0;z--)
for(y=0;y<110;y++); }
void check() // 判断忙或空闲 {
do{ P0=0xFF; rs=0; //指令 rw=1; //读 lcden=0; //禁止读写 delay(1); //等待,液晶显示器处理数据 lcden=1; //允许读写 }while(busy==1); //判断是否为空闲,1为忙,0为空闲
write_com(0x04); //设置从后住前写数据,每写完一个数据,光 标后退一格
c=a+b; while(c!=0) { write_date(0x30+c%10); c=c/10; } write_date(0x3d); //再写"=" a=0;b=0;flag=0;fuhao=0; } else if(fuhao==2){write_com(0x80+0x4f);//光标前进至第二行最后一个 显示处 write_com(0x04); //设置从后住前写数据,每写完一个数据,光 标后退一格(这个照理说顺序不对,可显示和上段一样) if(a-b>0) c=a-b; else c=b-a; while(c!=0) { write_date(0x30+c%10); c=c/10; } if(a-b<0)
char i,j,temp,num,num_1; long a,b,c; //a,第一个数 b,第二个数 c,得数 float a_c,b_c; uchar flag,fuhao;//flag表示是否有符号键按下,fuhao表征按下的是哪个 符号
uchar code table[]={ 7,8,9,0, 4,5,6,0, 1,2,3,0, 0,0,0,0}; uchar code table1[]={ 7,8,9,0x2f-0x30, 4,5,6,0x2a-0x30, 1,2,3,0x2d-0x30, 0x01-0x30,0,0x3d-0x30,0x2b-0x30};
} } while(P3!=0xfb); if(num==8||num==9||num==10)//如果按下的是'1','2'或'3' { if(j!=0)
{ write_com(0x01); j=0; } if(flag==0)//没有按过符号键 { a=a*10+table[num]; } else//如果按过符号键 { b=b*10+table[num]; } } else if(num==11)//如果按下的是'-' { flag=1; fuhao=2;//2表示减号已按
以执行的机器码有两种方法,一种是手工汇编,另一种是机器汇编,目前已极少使用手工汇编 的方法了。机器汇编是通过汇编软件将源程序变为机器码,用于MCS-51单片机的汇编软件有早 期的A51,随着单片机开发技术的不断发展,从普遍使用汇编语言到逐渐使用高级语言开发,单 片机的开发软件也在不断发展,Keil软件是目前最流行开发MCS-51系列单片机的软件,这从近 年来各仿真机厂商纷纷宣布全面支持Keil即可看出。Keil提供了包括C编译器、宏汇编、连接 器、库管理和一个功能强大的仿真调试器等在内的完整开发方案,通过一个集成开发环境 (uVision)将这些部份组合在一起。运行Keil软件需要Pentium或以上的CPU,16MB或更多 RAM、20M以上空闲的硬盘空间、WIN98、NT、WIN2000、WINXP等操作系统。掌握这一软件的使用 对于使用51系列单片机的爱好者来说是十分必要的,如果你使用C语言编程,那么Keil几乎就是 你的不二之选(目前在国内你只能买到该软件、而你买的仿真机也很可能只支持该软件),即 使不使用C语言而仅用汇编语言编程,其方便易用的集成环境、强大的软件仿真调试工具也会令 你事半功倍。 Keil C51开发系统基本知识Keil C51开发系统基本知识 1. 系统概述 Keil C51是美国Keil Software公司出品的51系列兼容单片机C语言软件开发系统,与汇编 相比,C语言在功能上、结构性、可读性、可维护性上有明显的优势,因而易学易用。用过汇编 语言后再使用C来开发,体会更加深刻。 Keil C51软件提供丰富的库函数和功能强大的集成开发调试工具,全Windows界面。另外重 要的一点,只要看一下编译后生成的汇编代码,就能体会到Keil C51生成的目标代码效率非常 之高,多数语句生成的汇编代码很紧凑,容易理解。在开发大型软件时更能体现高级语言的优 势。下面详细介绍Keil C51开发系统各部分功能和使用。 2. Keil C51单片机软件开发系统的整体结构 C51工具包的整体结构中,其中uVision与Ishell分别是C51 for Windows和for Dos的集成开发 环境(IDE),可以完成编辑、编译、连接、调试、仿真等整个开发流程。开发人员可用IDE本身 或其它编辑器编辑C或汇编源文件。然后分别由C51及A51编译器编译生成目标文件(.OBJ)。目标 文件可由LIB51创建生成库文件,也可以与库文件一起经L51连接定位生成绝对目标文件 (.ABS)。ABS文件由OH51转换成标准的Hex文件,以供调试器dScope51或tScope51使用进行源代 码级调试,也可由仿真器使用直接对目标板进行调试,也可以直接写入程序存贮器如EPROM中。