Lcd1602简易计算器
- 格式:docx
- 大小:131.13 KB
- 文档页数:12
//利用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 液晶显示屏简介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;}}}}```上述代码只是一个简单的示例,实际应用中还需要进行更多的优化和完善,比如处理输入错误、添加更多的功能等。
#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]);}}}。
嵌入式系统原理及应用课程设计报告姓名:学号:指导老师:目录引言 (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单片机的多功能计算器院系:机电工程学院专业(班级):电子信息工程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液晶显示计算器院系:机械工程学院班级:测控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(); }}。
基于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();}}。
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显示的简易计算器刘哲电子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语言编程,这样有利于减少工作量和代码量,提高设计效率。
基于C51单⽚机的智能计算器、矩阵键盘、lcd1602⽬录1绪论 (1)1.1选题背景 (1)1.2起源与发展 (1)1.3研究的⽬的和意义 (2)2项⽬总体设计框架 (2)2.1芯⽚STC89C52 (2)2.2采⽤矩阵式键盘作为输⼊模块 (2)2.3显⽰模块 (3)2.4硬件资源分配 (3)3计算器硬件设计 (4)3.1系统组成及硬件框图 (4)3.2元器件简介 (4)3.2.1 STC89C52的特点 (4)3.2.2 LCD1602 液晶显⽰屏 (5)4系统电路设计 (6)4.1键盘电路设计 (7)4.2显⽰电路设计 (8)4.3其他电路部分 (8)4.3.1 蜂鸣器模块 (8)4.3.2 电源模块 (9)4.3.3 单⽚机最⼩系统 (9)5计算器软件设计 (10)5.1整体设计结构 (10)5.2液晶屏读写函数 (10)5.2.1 初始化函数 (10)5.2.2 写命令函数 (11)5.2.3 写数据函数 (11)5.3接收矩阵键盘输⼊函数 (12)5.4调试和运⾏程序 (13)5.4.1 Proteus仿真运⾏程序 (13)5.4.2 在实验箱上运⾏程序 (13)6总结 (14)基于51单⽚机的简易计算器摘要:近⼏年单⽚机技术的发展很快,其中,电⼦产品的更新速度迅猛。
计算器是⽇常⽣活中⽐较常见的电⼦产品之⼀。
如何才能使计算器技术更加的成熟,充分利⽤已有的硬件和软件条件,设计出更出⾊的计算器。
本设计是以STC89C52单⽚机为核⼼的计算器模拟系统设计,输⼊采⽤4*4矩阵键盘,可以进⾏加、减、乘、除带符号数字运算(六位整数或两位⼩数点点),并在液晶显⽰屏LCD1602上静态显⽰操作过程及结果。
对字符液晶显⽰模块的⼯作原理,如初始化、清屏、显⽰、调⽤及外特性有较清楚的认识,并会使⽤LCD(液晶显⽰模块)实现计算结果的显⽰;掌握液晶显⽰模块的驱动和编程,设计LCD和单⽚机的接⼝电路,以及利⽤单⽚机对液晶显⽰模块的驱动和操作;在充分分析内部逻辑的概念,进⾏软件和调试,学会使⽤,并能够以其为平台设计出具有四则运算能⼒简易计算器的硬件电路和软件程序。
;****************************************************************** ;* * ;* ME500单片机开发系统演示程序- 简单的计算器* ;* * ;* LCD1602 显示* ;* * ;* 版本:V1.0 (2006/11/20) *;* 作者:gguoqing (Email: gguoqing@) *;* 网站:(伟纳电子) (伟纳单片机世界) *;* 邮箱:support@ * ;* * ;*【版权】Copyright(C)伟纳电子 All Rights Reserved *;*【声明】此程序仅用于学习与参考,引用请注明版权和作者信息!* ;* * ;****************************************************************** ;-------------------------------;简单的计算器演示程序;0-99之间的加、减、乘、除运算;-------------------------------;矩阵键盘定义:;P1.0-P1.3为列线,P1.4-P1.7为行线;出口:A、R3存键值;-------------------------------RELAY EQU P1.3BEEP EQU P3.7;-------------------------------RS EQU P2.0RW EQU P2.1EN EQU P2.2X EQU 3fH ;LCD 地址变量;-------------------------------TEMP1 EQU 30H ;临时暂存器TEMP2 EQU 31HTEMP3 EQU 32HTEMP4 EQU 33HRES_H EQU 24H ;输入被加(减、乘、除)数RES_L EQU 25H ;输入加(减、乘、除)数OUT_H EQU 26H ;运算结果高位OUT_L EQU 27H ;运算结果低位;-------------------------------ORG 0000HJMP MAIN;-------------------------------MAIN: MOV SP,#60HCLR ENCALL SET_LCDMOV 20H,#00HCALL BEEP_BL ;起延时作用MOV R1,#00HMOV TEMP1,#00HMOV TEMP2,#00HMOV TEMP3,#00HMOV RES_L,#00HMOV RES_H,#00HMOV OUT_H,#00HMOV OUT_L,#00HLOOP:CALL KEY_IN ;送被(加、减、乘、除)数JNB 20H.0,LOOP ;键标记CALL BEEP_BLINC R1CJNE R1,#01H,LOOP_1MOV TEMP2,A ;高位MOV X,#2CALL CONV0LOOP_1: CJNE R1,#02H,LOOPSUBB A,#0AH ;判是否是功能键?JNC LOOP_2 ;是,转LOOP_2MOV TEMP1,TEMP2MOV A,TEMP1MOV X,#1CALL CONV0MOV A,R3 ;恢复有效键值MOV TEMP2,A ;低位MOV X,#2CALL CONV0MOV A,TEMP1ANL A,#0FHSW AP AORL A,TEMP2MOV RES_H,AJMP LOOP0LOOP_2:MOV RES_H,TEMP2AJMP LOOP0ALOOP0: CALL KEY_INJNB 20H.0,LOOP0CALL BEEP_BLLOOP0A: MOV A,R3 ;重装键值CJNE A,#0AH,LOOP1 ;加运算CALL CONV1SETB 20H.1 ;加运算标记AJMP LOOP5LOOP1: CJNE A,#0BH,LOOP2 ;减运算CALL CONV2SETB 20H.2 ;减运算标记AJMP LOOP5LOOP2: CJNE A,#0CH,LOOP3 ;乘运算CALL CONV3SETB 20H.3 ;乘运算标记AJMP LOOP5LOOP3: CJNE A,#0DH,LOOP4 ;除运算CALL CONV4SETB 20H.4 ;除运算标记AJMP LOOP5LOOP4: CJNE A,#0FH,LOOP4AAJMP MAINLOOP4A: AJMP LOOP0LOOP5: MOV R1,#00HMOV TEMP1,#00HMOV TEMP2,#00HCLR 20H.0 ;送(加、减、乘、除)数LOOP5A: CALL KEY_INJNB 20H.0,LOOP5ACALL BEEP_BLCJNE A,#0FH,LOOP5BAJMP MAINLOOP5B: INC R1CJNE R1,#01H,LOOP5CMOV TEMP2,AMOV X,#6CALL CONV0LOOP5C: CJNE R1,#02H,LOOP5ASUBB A,#0AH ;判是否是功能键?JNC LOOP5D ;是,转LOOP5CMOV TEMP1,TEMP2MOV A,TEMP1MOV X,#6CALL CONV0MOV A,R3MOV TEMP2,AMOV X,#7CALL CONV0MOV A,TEMP1ANL A,#0FHSW AP AORL A,TEMP2MOV RES_L,AJMP LOOP6LOOP5D: MOV RES_L,TEMP2JMP LOOP6ALOOP6: CALL KEY_INLOOP6A: MOV A,R3 ;重装键值CJNE A,#0FH,LOOP6BAJMP MAINLOOP6B: CJNE A,#0EH,LOOP6 ;显示(=)CALL CONV5CALL BEEP_BL ;显示运算结果JNB 20H.1,LOOP6CCALL SUADDLOOP6C: JNB 20H.2,LOOP6DCALL SUSUBLOOP6D: JNB 20H.3,LOOP6ECALL SUMULLOOP6E: JNB 20H.4,LOOP7CALL SUDIVLOOP7: CALL KEY_INCJNE A,#0FH,LOOP7 ;复位(清零)AJMP MAIN;------------------------;加法运算子程序;入口:R0-被加数,R1-加数;出口:R4(高)、R2(低)为和值;------------------------SUADD:MOV R1,RES_LMOV R0,RES_HMOV A,R0ADD A,R1DA AMOV R2,ACLR AADDC A,#00HMOV R4,AMOV OUT_H,R4MOV OUT_L,R2CALL T_CONVRET;------------------------;减法运算子程序;入口:R0-被减数,R1-减数;出口:R2-差值;------------------------SUSUB:MOV R1,RES_LMOV R0,RES_HCLR CMOV A,#9AHSUBB A,R1 ;减数十进制求补ADD A,R0DA AMOV R2,A ;差值送R2JC POSI ;C=1,表示差值为正NEGA: MOV A,#9AH ;差值为负,求补后得差值的绝对值SUBB A,R2MOV R2,ASETB 20H.5 ;显示负号标记POSI: MOV OUT_H,#00HMOV OUT_L,R2CALL T_CONVRET;-------------------------;乘法运算子程序; 单字节BCD码乘法子程序;入口: R0(被乘数)、R1(乘数);出口: R3(高)、R2(低),积为双字节,BCD码形式的积;从乘数高位开始进行BCD码移位乘法;-------------------------SUMUL:MOV R1,RES_LMOV R0,RES_HBCDMUL:CLR A ;积单元清零MOV R2,AMOV R3,AMOV A,R1JZ RETURNANL A,#0F0H ;取乘数高位JZ LBCD ;乘数高位是否为0?SW AP AMOV R4,AACALL DDBCDMSW AP A ;BCD码左移一位MOV R3,AMOV A,R2SW AP AMOV R2,AANL A,#0FHORL A,R3MOV R3,AMOV A,R2ANL A,#0F0HMOV R2,ALBCD: MOV A,R1 ;取乘数低位ANL A,#0FHJZ RETURN ;乘数低位是否为0?MOV R4,AACALL DDBCDMRETURN: MOV OUT_H,R3MOV OUT_L,R2CALL T_CONVRETDDBCDM: ;一位BCD码乘法MOV A,R2ADD A,R0DA AMOV R2,AMOV A,R3ADDC A,#00HDA AMOV R3,ADJNZ R4,DDBCDMRET;------------------------------------------------;除法运算子程序;单字节BCD码除法;入口:R0(被除数)、R1(非零除数);出口:R2(商)、R3(余数);《MCS-51系列单片机实用子程序集锦》Page 73;-----------------------------------------------SUDIV:MOV R1,RES_LMOV R0,RES_HBCDDIV:MOV R2,#00H ;商单元清零MOV A,R1 ;除数求补CPL AADD A,#9BHMOV R1,AMOV A,R0 ;被除数高位移入ANL A,#0F0H ;部分余单元SW AP ALP0: MOV R3,A ;做除法ADD A,R1DA AJNC LP1 ;部分余数>=除数?INC R2 ;商加1SJMP LP0LP1: MOV A,R3 ;SW AP AMOV R3,AMOV A,R2 ;商左移一位SW AP AMOV R2,AMOV A,R0 ;移位ANL A,#0FHORL A,R3LP2: MOV R3,A ;做除法ADD A,R1DA AJNC LP3INC R2 ;商加1SJMP LP2LP3: MOV A,R3 ;四舍五人ADD A,R3DA AJC LP4ADD A,R1DA AJNC RETURN1LP4: MOV A,R2ADDC A,#00HDA AMOV R2,ARETURN1: MOV OUT_H,#00HMOV OUT_L,R2CALL T_CONVRET;-----------------------------------------------------; LCD 初始化设置;-----------------------------------------------------SET_LCD:CLR ENCALL INIT_LCD ;初始化LCDCALL DELAY1MOV DPTR,#INFO1 ;指针指到显示信息1MOV A,#1 ;显示在第一行CALL LCD_SHOWMOV DPTR,#INFO2 ;指针指到显示信息2MOV A,#2 ;显示在第二行CALL LCD_SHOWRET;-----------------------------------------------------INFO1: DB " CALCULATOR ",0 ;LCD 第一行显示信息INFO2: DB " ",0 ;LCD 第二行显示信息;----------------------------------------------------INIT_LCD: ;8位I/O控制LCD 接口初始化MOV A,#38H ;双列显示,字形5*7点阵CALL WCOMCALL DELAY1MOV A,#38H ;双列显示,字形5*7点阵CALL WCOMCALL DELAY1MOV A,#38H ;双列显示,字形5*7点阵CALL WCOMCALL DELAY1MOV A,#0FH ;开显示,关光标,CALL WCOMCALL DELAY1MOV A,#01H ;清除LCD 显示屏CALL WCOMCALL DELAY1RET;----------------------------------------------------LCD_SHOW: ;在LCD的第一行或第二行显示信息字符CJNE A,#1,LINE2 ;判断是否为第一行LINE1: MOV A,#80H ;设置LCD 的第一行地址CALL WCOM ;写入命令CALL CLR_LINE ;清除该行字符数据MOV A,#80H ;设置LCD 的第一行地址CALL WCOM ;写入命令JMP FILLLINE2: MOV A,#0C0H ;设置LCD 的第二行地址CALL WCOM ;写入命令CALL CLR_LINE ;清除该行字符数据MOV A,#0C0H ;设置LCD 的第二行地址CALL WCOMFILL: CLR A ;填入字符MOVC A,@A+DPTR ;由信息区取出字符CJNE A,#0,LC1 ;判断是否为结束码RETLC1: CALL WDATA ;写入数据INC DPTR ;指针加1JMP FILL ;继续填入字符RET;---------------------------------------------------CLR_LINE: ;清除该行LCD 的字符MOV R0,#24CL1: MOV A,#' 'CALL WDA TADJNZ R0,CL1RET;-----------------------------------------------------; 写指令、数据使能子程序;-----------------------------------------------------WCOM: ;写指令使能MOV P0,ACLR RS ;RS=L,RW=L,D0-D7=指令码,E=高脉冲CLR RWSETB ENCALL DELAY0CLR ENRETWDATA: ;写数据使能MOV P0,ASETB RS ;RS=H,RW=L,D0-D7=数据,E=高脉冲CLR RWSETB ENCALL DELAY0CLR ENRETDELAY0: MOV R7,#250 ;延时500微秒DJNZ R7,$RET;---------------------------------------------------;在LCD 第二行显示字符;A=ASC DATA, B=LINE X POS;---------------------------------------------------LCDP2: ;在LCD的第二行显示字符PUSH ACC ;MOV A,B ;设置显示地址ADD A,#0C0H ;设置LCD的第二行地址CALL WCOM ;写入命令POP ACC ;由堆栈取出ACALL WDA TA ;写入数据RET;-----------------------------------------------------;矩阵键盘键值读取子程序;-----------------------------------------------------KEY_IN: MOV P1,#0F0H ;置列线为0,行线为1MOV A,P1ANL A,#0F0HMOV B,AMOV P1,#0FH ;置列线为1,行线为0MOV A,P1ANL A,#0FHORL A,B ;高四位与低四位重新组合CJNE A,#0FFH,KEY_IN1 ;0FFH为末按键CLR 20H.0RETKEY_IN1: MOV B,AMOV DPTR,#KEYTABLEMOV R3,#0FFHKEY_IN2: INC R3MOV A,R3MOVC A,@A+DPTRCJNE A,B,KEY_IN3MOV A,R3 ;找到,取顺序码MOV R5,#08H ;延时CALL DELAYSETB 20H.0RETKEY_IN3: CJNE A,#0FFH,KEY_IN2 ;末完,继续查RET ;0FFH为结束码;------------------------;在指定位置显示符合子程序;------------------------CONV0:add A,#30hMOV B,XCALL LCDP2retCONV1:MOV X,#4MOV A,#2BH ;+MOV B,XCALL LCDP2RETCONV2:MOV X,#4MOV A,#2DH ;-MOV B,XCALL LCDP2RETCONV3:MOV X,#4MOV A,#2AH ;*MOV B,XCALL LCDP2RETCONV4:MOV X,#4MOV A,#2FH ;/MOV B,XCALL LCDP2RETCONV5:MOV X,#09HMOV A,#3DH ;=MOV B,XCALL LCDP2RET;--------------------------;;--------------------------CONV:;MOV X,#3 ;设置显示起始位置MOV A,R3ANL A,#0FH ;取出低四位二进制数PUSH ACC ;压入堆栈CLR C ;C=0SUBB A,#0AH ;减10POP ACC ;弹出堆栈JC ASCII0 ;该数小于10,转ASCII0JMP ASCII1;ADD A,#07H ;大于10的数加上37H ASCII0: ADD A,#30H ;小于10的数加上30HMOV B,XCALL LCDP2ASCII1: ;MOV A,R3RET;-------------------------------------------------------T_CONV:MOV A,OUT_H ;取高位数mov x,#11cjne a,#00h,t_conv1 ;判高位数是否为0?setb 20h.6 ;为0,20h.6置1jmp t_conv3 ;转取低位数;高位数不为0,则t_conv1: anl a,#0f0h ;判高位数的高四位是否为0?cjne a,#00h,t_conv2 ;不为0,2位数都显示setb 20h.6 ;为0,20h.6置1,只显示低四位t_conv2: mov a,out_hCALL SHOW_DIG2inc xclr 20h.6 ;清显示标记位t_conv3: mov a,out_l ;取低位数jnb 20h.6,t_conv5 ;高位数有显示,则不判低位数。
嵌入式系统原理及应用课程设计报告姓名:学号:指导老师:目录引言 (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转换器等电路)集成到一块硅片上构成的一个小而完善的计算机系统。
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();}}}}。