基于51单片机的计算器设计程序代码汇编
- 格式:doc
- 大小:27.50 KB
- 文档页数:7
基于单片机的计算器——汇编编号:单片机综合设计实训 (论文)说明书题目:基于单片机的电子计算器院(系):专业:学生姓名:学号:指导教师:年01 月 1 日摘要当今社会,随着人们物质生活的不断提高,电子产品已经走进了家家户户,无论是生活或学习,还是娱乐和消遣几乎样样都离不开电子产品,大型复杂的计算能力是人脑所不能胜任的,而且比较容易出错。
计算器作为一种快速通用的计算工具方便了用户的使用。
计算器可谓是我们最亲密的电子伙伴之一。
单片机由于其微小的体积和极低的成本,广泛的应用于家用电器、工业控制等领域中。
在工业生产中。
单片微型计算机是微型计算机的一个重要分支,也是颇具生命力的机种。
单片微型计算机简称单片机,特别适用于控制领域,故又称为微控制器。
本系统就是充分利用了AT89S52芯片的I/O引脚。
系统以采用MCS-51系列单片机Intel8051为中心器件来设计计算器控制器,以矩阵键盘输入、八位数码管显示,实现了能根据实际输入值计算并显示的功能。
关键词:计算器 AT89S52 八位数码管矩阵键盘AbstractIn today's society, with people constantly improve the material life, the electronic produc ts have entered the each and every family, whether living or studying, or entertainment and recreation almost everything is inseparable from the electronic products, large and complex co mputing capability is the human brain are not competent, but relatively easy to go wrong.Calc ulator as a rapid generic computational tool is convenient for users to use.The calculator is our most intimate electronic partners.SCM because of its small size and low cost, widely used in household appliances, industr ial control and other areas.In industrial production.Single chip microcomputer, the microcomp uter is an important branch, is full of vitality.Single chip micro computer referred to as SCM, is particularly applicable to the control field, it is also known as the micro controller.The system is to make full use of the AT89S52 chip I / O pins.System for using MCS-51 MCU Intel8051 as the center device to design the computer controller, with the matrix keybo ard input, the eight digital tube display, can be achieved according to the actual input value ca lculation and display functions.Key words: calculator AT89S52 digital tube eight matrix keyboard目录1实训设计内容 (4)1.1 设计目的 (4)1.2 设计任务 (4)2 系统硬件设计 (4)2.1 芯片介绍 (4)2.1.1主控芯片AT89S52概述与介绍 (4)2.1.2 MAX232芯片介绍 (9)2.2 硬件电路 (10)2.2.1 键盘接口电路 (10)2.2.2 7段LED数码管 (10)2.2.3 程序下载接口 (11)2.2.4 单片机时钟电路 (11)2.2.5 单片机复位电路 (12)3 软件设计 (12)3.1 按键扫程序设计 (12)3.2 算法设计 (13)4 电路板制作过程 (13)5 作品调试 (14)5.1硬件调试 (14)5.2 程序调试 (14)致谢 (16)参考文献: (17)附录: (18)1实训设计内容1.1 设计目的通过本次课题设计,应用《单片机原理及应用》等所学相关知识及查阅资料,完成简易计算器的设计,以达到理论与实践更好的结合、进一步提高综合运用所学知识和设计的能力的目的。
//利用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(); //显示结果}}}}。
#include <reg51.h>#include <intrins.h>unsigned char data digit;unsigned char data index;unsigned char data buf[16];unsigned char code table[11]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};unsigned int temp_dat;unsigned long int temp1,temp2,temp;unsigned int flag,flag1,key_times,key_flag,key_temp;unsigned char key_scan();void delay(void);void key_proc();void sys_init();void dis_result();void dis_init();void result_proc();void start_proc();void dat_proc(unsigned int key_dat);void char_proc(unsigned char i);void delayms(unsigned char ms);void main(){sys_init();while(1){key_proc();dis_result();}}void sys_init(){P0=0xff;P2=0x00;TMOD=0x01;TH0=0xfc;TL0=0x17;digit=0x00;index=0;temp=0;temp1=0;temp2=0;flag=0;key_times=0;temp_dat=0;key_flag=0;key_temp=0;dis_init();IE=0x82;TR0=1;}void dis_init(){buf[0]=table[10];buf[1]=table[10];buf[2]=table[10];buf[3]=table[10];buf[4]=table[10];buf[5]=table[10];buf[6]=table[10];buf[7]=table[10];buf[8]=table[10];buf[9]=table[10];buf[10]=table[10];buf[11]=table[10];buf[12]=table[10];buf[13]=table[10];buf[14]=table[10];buf[15]=table[10];}void dis_result(){if((temp<=4294967295)&&(temp>999999999)) {buf[0]=table[10];buf[1]=table[10];buf[2]=table[10];buf[3]=table[10];buf[4]=table[10];buf[5]=table[10];buf[6]=table[temp/1000000000];buf[7]=table[(temp%1000000000)/100000000];buf[8]=table[((temp%1000000000)%100000000)/10000000];buf[9]=table[(((temp%1000000000)%100000000)%10000000)/1000000];buf[10]=table[((((temp%1000000000)%100000000)%10000000)%1000000)/100000];buf[11]=table[(((((temp%1000000000)%100000000)%10000000)%1000000)%100000)/10000];buf[12]=table[((((((temp%1000000000)%100000000)%10000000)%1000000)%100000)%10000) /1000];buf[13]=table[(((((((temp%1000000000)%100000000)%10000000)%1000000)%100000)%10000 )%1000)/100];buf[14]=table[((((((((temp%1000000000)%100000000)%10000000)%1000000)%100000)%1000 0)%1000)%100)/10];buf[15]=table[((((((((temp%1000000000)%100000000)%10000000)%1000000)%100000)%1000 0)%1000)%100)%10];}if((temp<=999999999)&&(temp>99999999)){buf[0]=table[10];buf[1]=table[10];buf[2]=table[10];buf[3]=table[10];buf[4]=table[10];buf[5]=table[10];buf[6]=table[10];buf[7]=table[temp/100000000];buf[8]=table[(temp%100000000)/10000000];buf[9]=table[((temp%100000000)%10000000)/1000000];buf[10]=table[(((temp%100000000)%10000000)%1000000)/100000];buf[11]=table[((((temp%100000000)%10000000)%1000000)%100000)/10000];buf[12]=table[(((((temp%100000000)%10000000)%1000000)%100000)%10000)/1000]; buf[13]=table[((((((temp%100000000)%10000000)%1000000)%100000)%10000)%1000)/100];buf[14]=table[(((((((temp%100000000)%10000000)%1000000)%100000)%10000)%1000)%100) /10];buf[15]=table[(((((((temp%100000000)%10000000)%1000000)%100000)%10000)%1000)%100) %10];}if((temp<=99999999)&&(temp>9999999)){buf[0]=table[10];buf[1]=table[10];buf[2]=table[10];buf[3]=table[10];buf[4]=table[10];buf[5]=table[10];buf[6]=table[10];buf[7]=table[10];buf[8]=table[temp/10000000];buf[9]=table[(temp%10000000)/1000000];buf[10]=table[((temp%10000000)%1000000)/100000];buf[11]=table[(((temp%10000000)%1000000)%100000)/10000];buf[12]=table[((((temp%10000000)%1000000)%100000)%10000)/1000];buf[13]=table[(((((temp%10000000)%1000000)%100000)%10000)%1000)/100];buf[14]=table[((((((temp%10000000)%1000000)%100000)%10000)%1000)%100)/10];buf[15]=table[((((((temp%10000000)%1000000)%100000)%10000)%1000)%100)%10];}if((temp<=9999999)&&(temp>999999)){buf[0]=table[10];buf[1]=table[10];buf[2]=table[10];buf[3]=table[10];buf[4]=table[10];buf[5]=table[10];buf[6]=table[10];buf[7]=table[10];buf[8]=table[10];buf[9]=table[temp/1000000];buf[10]=table[(temp%1000000)/100000];buf[11]=table[((temp%1000000)%100000)/10000];buf[12]=table[(((temp%1000000)%100000)%10000)/1000];buf[13]=table[((((temp%1000000)%100000)%10000)%1000)/100];buf[14]=table[(((((temp%1000000)%100000)%10000)%1000)%100)/10];buf[15]=table[(((((temp%1000000)%100000)%10000)%1000)%100)%10];}if((temp<=999999)&&(temp>99999)){buf[0]=table[10];buf[2]=table[10];buf[3]=table[10];buf[4]=table[10];buf[5]=table[10];buf[6]=table[10];buf[7]=table[10];buf[8]=table[10];buf[9]=table[10];buf[10]=table[temp/100000];buf[11]=table[(temp%100000)/10000];buf[12]=table[((temp%100000)%10000)/1000];buf[13]=table[(((temp%100000)%10000)%1000)/100];buf[14]=table[((((temp%100000)%10000)%1000)%100)/10];buf[15]=table[((((temp%100000)%10000)%1000)%100)%10]; }if((temp<=99999)&&(temp>9999)){buf[0]=table[10];buf[1]=table[10];buf[2]=table[10];buf[3]=table[10];buf[4]=table[10];buf[5]=table[10];buf[6]=table[10];buf[7]=table[10];buf[8]=table[10];buf[9]=table[10];buf[10]=table[10];buf[11]=table[temp/10000];buf[12]=table[(temp%10000)/1000];buf[13]=table[((temp%10000)%1000)/100];buf[14]=table[(((temp%10000)%1000)%100)/10];buf[15]=table[(((temp%10000)%1000)%100)%10];}else if((temp<=9999)&&(temp>999)){buf[0]=table[10];buf[1]=table[10];buf[2]=table[10];buf[3]=table[10];buf[4]=table[10];buf[5]=table[10];buf[7]=table[10];buf[8]=table[10];buf[9]=table[10];buf[10]=table[10];buf[11]=table[10];buf[12]=table[temp/1000];buf[13]=table[(temp%1000)/100];buf[14]=table[((temp%1000)%100)/10];buf[15]=table[((temp%1000)%100)%10]; }else if((temp<=999)&&(temp>99)){buf[0]=table[10];buf[1]=table[10];buf[2]=table[10];buf[3]=table[10];buf[4]=table[10];buf[5]=table[10];buf[6]=table[10];buf[7]=table[10];buf[8]=table[10];buf[9]=table[10];buf[10]=table[10];buf[11]=table[10];buf[12]=table[10];buf[13]=table[temp/100];buf[14]=table[(temp%100)/10];buf[15]=table[(temp%100)%10];}else if((temp<=99)&&(temp>9)){buf[0]=table[10];buf[1]=table[10];buf[2]=table[10];buf[3]=table[10];buf[4]=table[10];buf[5]=table[10];buf[6]=table[10];buf[7]=table[10];buf[8]=table[10];buf[9]=table[10];buf[10]=table[10];buf[11]=table[10];buf[13]=table[10];buf[14]=table[temp/10];buf[15]=table[temp%10];}else if(temp<=9){buf[0]=table[10];buf[1]=table[10];buf[2]=table[10];buf[3]=table[10];buf[4]=table[10];buf[5]=table[10];buf[6]=table[10];buf[7]=table[10];buf[8]=table[10];buf[9]=table[10];buf[10]=table[10];buf[11]=table[10];buf[12]=table[10];buf[13]=table[10];buf[14]=table[10];buf[15]=table[temp];}}unsigned char key_scan(){unsigned char code_h,code_l;P1=0xf0;if((P1&0xf0)!=0xf0){delayms(2);if((P1&0xf0)!=0xf0) //两次判断,确认有键按下{code_h=0xfe; //低四位为行地址,对每一行进行扫描,即将每一行依次赋值0while((code_h&0x10)!=0x00){P1=code_h;if((P1&0xf0)!=0xf0){code_l=(P1&0xf0|0x0f);return((~code_h)+(~code_l)); //取反之后,高四位与低四位都只有一个1,相加不会进位}elsecode_h=((code_h<<1)|0x01); //依次进行扫描}}}return(0);}void key_proc(){unsigned char key_value;key_value=key_scan();switch(key_value){case 0x18: dat_proc(7);break; //7case 0x28: dat_proc(4);break; //4case 0x48: dat_proc(1);break; //1case 0x14: dat_proc(8);break; //8case 0x24: dat_proc(5);break; //5case 0x44: dat_proc(2);break; //2case 0x84: dat_proc(0);break; //0case 0x12: dat_proc(9);break; //9case 0x22: dat_proc(6);break; //6case 0x42: dat_proc(3);break; //3case 0x82: result_proc();break; //=case 0x11: char_proc(4);break; ///case 0x21: char_proc(3);break; //*case 0x41: char_proc(2);break; //-case 0x81: char_proc(1);break; //+case 0x88: start_proc();break; //ondefault :break;}}void dat_proc(unsigned int key_dat){if(key_times==0)temp=key_dat;else{if(flag==0)temp=(temp1*10+key_dat);else if(flag==1)temp=(temp2*10+key_dat);}if(flag==0)temp1=temp;else if(flag==1)temp2=temp;delayms(200);key_times++;}void char_proc(unsigned char i){key_times=0;key_flag=i;if(temp==0)flag=0;else{flag=1;}}void result_proc(){unsigned char flag_value;flag_value=key_flag;switch(flag_value){case 1: temp=(temp1+temp2);break;case 2: temp=(temp1-temp2);break;case 3: temp=(temp1*temp2);break;case 4: temp=(temp1/temp2);break;}key_times=0;flag=0;}void start_proc(){temp=0;temp1=0;temp2=0;flag=0;key_times=0;temp_dat=0;key_flag=0;}void time0() interrupt 1 using 2 {TH0=0xfc;TL0=0x17;P2=0x00;P0=buf[index];P2=digit;digit=digit++;index++;index&=0x0f;}void delayms(unsigned char ms) {unsigned char i;while(ms--){for(i = 0; i < 120; i++);}}D0D1D2D3D4D5D6D7P3.1Q1CSDAQ2INT1Q3LCDENQ4WRQ6RDQ7Q0Q5Q4Q7Q5Q6Q 3Q 0Q 1Q 2D 0D 7D 6D 5D 4D 3D 2D 1W 0W 1W 2W 3W 4W 5W 6W 7D 0D 1D 2D 3D 4D 5D 6D 7W 8W 10W 11W 12W 13W 14W 15W 9W0W1W2W3W4W5W6W7W8W9W10W11W12W13W14W15XTAL218XTAL119ALE 30EA31PSEN 29RST9P0.0/AD039P0.1/AD138P0.2/AD237P0.3/AD336P0.4/AD435P0.5/AD534P0.6/AD633P0.7/AD732P1.0/T21P1.1/T2EX 2P1.23P1.34P1.45P1.56P1.67P1.78P3.0/RXD 10P3.1/TXD 11P3.2/INT012P3.3/INT113P3.4/T014P3.7/RD17P3.6/WR 16P3.5/T115P2.7/A1528P2.0/A821P2.1/A922P2.2/A1023P2.3/A1124P2.4/A1225P2.5/A1326P2.6/A1427U3AT89C52234567891RP1RESPACK-812365489=7+CONABCD1243A 1B 2C3E16E24E35Y015Y114Y213Y312Y411Y510Y69Y77U174HC138A 1B 2C3E16E24E35Y015Y114Y213Y312Y411Y510Y69Y77U274HC138U4NOTU5NOTU6NOTU7NOTU8NOTU9NOTU10NOTU11NOTU12NOTU13NOTU14NOTU15NOTU16NOTU17NOTU19NOTU20NOTU22NOT。
#include <reg52.h>#include <intrins.h>#include <math.h>#define uchar unsigned char#define uint unsigned intsbit LCD_RS=P2^2;//数据和命令端sbit LCD_EN=P2^0;//使能端sbit LCD_RW=P2^1;sbit CS1=P2^4;sbit CS2=P2^3;uint keytime,keyno[10];uint result,date1,date2,w_date1,w_date2;uint KeyNO1,opercha;uint date10n;uint date10n_d[16];uchar code hz[]={/*-- 文字: 数--*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x10,0x92,0x54,0x38,0xFF,0x38,0x54,0x52,0x80,0xF0,0x1F,0x12,0x10,0xF0,0x10,0x00,0x42,0x42,0x2A,0x2E,0x13,0x1A,0x26,0x02,0x40,0x20,0x13,0x0C,0x33,0x60,0x20,0x00,/*-- 文字: 据--*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x08,0x08,0x08,0xFF,0x88,0x40,0xFE,0x92,0x92,0x92,0xF2,0x92,0x92,0x9E,0x80,0x00,0x02,0x42,0x81,0x7F,0x40,0x30,0x0F,0xFC,0x44,0x44,0x47,0x44,0x44,0xFC,0x00,0x00,/*-- 文字: 结--*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x20,0x30,0xAC,0x63,0x10,0x00,0x08,0x48,0x48,0x48,0x7F,0x48,0x48,0x48,0x08,0x00,0x22,0x23,0x22,0x12,0x12,0x00,0x00,0x7E,0x22,0x22,0x22,0x22,0x22,0x7E,0x00,0x00,/*-- 文字: 果--*//*-- 宋体12; 此字体下对应的点阵为:宽x高=16x16 --*/0x00,0x00,0x00,0x3E,0x2A,0x2A,0x2A,0xFE,0x2A,0x2A,0x2A,0x3E,0x00,0x00,0x00,0x00,0x21,0x21,0x11,0x11,0x09,0x05,0x03,0xFF,0x03,0x05,0x09,0x09,0x11,0x31,0x11,0x00};uchar code sz[]={0x00,0x00,0xF0,0xF8,0x08,0x68,0xF8,0xF0,0x00,0x00,0x07,0x0F,0x0B,0x08,0x0F,0x07, //0 0x00,0x20,0x20,0x30,0xF8,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00, //1 0x00,0x30,0x38,0x08,0x88,0xF8,0x70,0x00,0x00,0x0C,0x0E,0x0B,0x09,0x08,0x08,0x00, //2 0x00,0x30,0x38,0x88,0x88,0xF8,0x70,0x00,0x00,0x06,0x0E,0x08,0x08,0x0F,0x07,0x00, //3 0x00,0x00,0xF8,0xF8,0x00,0xE0,0xE0,0x00,0x00,0x03,0x03,0x02,0x02,0x0F,0x0F,0x02, //4 0x00,0xF8,0xF8,0x88,0x88,0x88,0x08,0x00,0x00,0x08,0x08,0x08,0x0C,0x07,0x03,0x00, //5 0x00,0xC0,0xE0,0x78,0x58,0xC8,0x80,0x00,0x00,0x07,0x0F,0x08,0x08,0x0F,0x07,0x00, //6 0x00,0x08,0x08,0x88,0xE8,0x78,0x18,0x00,0x00,0x00,0x0E,0x0F,0x01,0x00,0x00,0x00, //7 0x00,0x70,0xF8,0xC8,0x88,0xF8,0x70,0x00,0x00,0x07,0x0F,0x08,0x09,0x0F,0x07,0x00, //8 0x00,0xF0,0xF8,0x08,0x08,0xF8,0xF0,0x00,0x00,0x00,0x09,0x0D,0x0F,0x03,0x01,0x00, //90x00,0x00,0x00,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x0C,0x0C,0x0C,0x00,0x00, //: 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x0C,0x0C,0x00,0x00//.};/*******************************名称:delay()输入:延时数输出: 无功能:延时********************************/void delay(uint x){int y,z;for(y=x;y>0;y--)for (z=120;z>0;z--);}void write_c(uchar c) //写指令端{LCD_RW=0;LCD_RS=0;LCD_EN=1;P0=c;LCD_EN=0;delay(1);LCD_EN=1;}void write_d(uchar d)//写数据{LCD_RW=0;LCD_RS=1;LCD_EN=1;P0=d;LCD_EN=0;delay(1);LCD_EN=1;}void pianxuan(screen) //片选{switch(screen){case 0:CS1=0;CS2=0;break;case 1:CS1=1;CS2=0;break;case 2:CS1=0;CS2=1;break;case 3:CS1=1;CS2=1;break;}}void qinping(screen)//清屏,从第一行第一列开始{uint x,y; //页的设置位pianxuan(screen);//选择哪个清屏for(x=0xb8;x<0xc0;x++){write_c(x);//页初始值为0XB8到0xc0共八页write_c(0x40);//列的初始地址为0x40,共64列for(y=0;y<64;y++){write_d(0x00);//选择全部清屏}}}/*LCD显示汉字字库函数*/void lcd_display_hanzi(uchar screen,uchar page,uchar lie,uint mun) //screen:选择屏幕参数,page:选择页参数0-3,lie列参数0-3,mun:显示第几个汉字的参数{int i; //page页其实就是行,是行计数器页指针共九位计数器,高三位为X,低六位为Ymun=mun*32;pianxuan(screen) ; //片选看哪个段write_c(0x40+(lie*16)); //一个汉字占用两个字节write_c(0xb8+(page*2)); //一个字节显示for ( i=0;i<16;i++){write_d(hz[mun++]);}write_c(0x40+(lie*16));write_c(0xb8+(page*2)+1);for (i=0;i<16;i++){write_d(hz[mun++]);}}void lcd_display_shuzi(uchar screen,uchar page,uchar lie,uint mun) //screen:选择屏幕参数,page:选择页参数0-3,lie列参数0-3,mun:显示第几个汉字的参数{int i; //page页其实就是行,是行计数器页指针共九位计数器,高三位为X,低六位为Ymun=mun*16;pianxuan(screen) ; //片选看哪个段write_c(0x40+(lie*8)); //一个汉字占用两个字节write_c(0xb8+(page*2)); //一个字节显示for ( i=0;i<8;i++){write_d(sz[mun++]);}write_c(0x40+(lie*8));write_c(0xb8+(page*2)+1);for (i=0;i<8;i++){write_d(sz[mun++]);}}void LCD_init(){write_c(0x3f);// 显示开启write_c(0xc0); //显示起始行,从第一位开始,从0到63 write_c(0xb8);// 设置页得地址从0到7write_c(0x40); //设置列的地址,从第一位开始,从0到63 }/*******************************名称:GET_key()输入:无输出: 按键的相应数目功能:扫描按键********************************/uchar GET_key(){uchar Tmp,KeyNO;P1 = 0xf0;delay(1);Tmp = P1;switch(Tmp){case 0xe0: KeyNO = 3; break;case 0xd0: KeyNO = 2; break;case 0xb0: KeyNO = 1; break;case 0x70: KeyNO = 0;}P1 = 0x0f;delay(1);Tmp = P1;switch(Tmp){case 0x0e: KeyNO+= 12; break;case 0x0d: KeyNO+= 8; break;case 0x0b: KeyNO+= 4; break;case 0x07: KeyNO+= 0; break;default: break;}return(KeyNO);}void write_key(){uchar i,j,m,n;m = 7;n = 7;KeyNO1 = GET_key();if (KeyNO1>=0 && KeyNO1<=9){keytime++;}if (KeyNO1>=10 && KeyNO1<=13){/* keytime= keytime-1;for (j=keytime; j>=0;j--){if ((keytime-j) == 0)w_date1=keyno[keytime];else{for (k=0; k<keytime-j; k++){w_date1=keyno[keytime--]*10;}}date1=date1+w_date1;}*/keytime = 0;opercha = KeyNO1;}if (!(opercha>=10 && opercha<=13)){date1=0;if ((keytime-1) < 10 ){keyno[keytime-1] = KeyNO1;if (keytime-1>=0 && keytime-1 <= 7){for (i=keytime; i>0; i--){lcd_display_shuzi(1,0,m,keyno[i-1]);m--;if ((keytime-i) == 0){w_date1=keyno[i-1];}else{for (j=0; j<keytime-i; j++){w_date1=keyno[i-1]*10;}}date1=date1+w_date1;}}else{for (i=keytime-8; i>0; i--){lcd_display_shuzi(2,0,n,keyno[i-1]);n--;for (j=0; j<keytime-i; j++){w_date1=keyno[i-1]*10;}date1=date1+w_date1;}m=7;for (i=keytime; i>keytime-8; i--){lcd_display_shuzi(1,0,m,keyno[i-1]);m--;if ((keytime-i) == 0)w_date1=keyno[i-1];else{for (j=0; j<keytime-i; j++){w_date1=keyno[i-1]*10;}}date1=date1+w_date1;}}}}if ( (opercha>=10 && opercha<=13) && (KeyNO1 != 14) ) {date2=0;if ((keytime-1)<10 && (keytime-1)>=0){keyno[keytime-1] = KeyNO1;if (keytime-1 <= 7){for (i=keytime; i>0; i--){lcd_display_shuzi(1,1,m,keyno[i-1]);m--;if ((keytime-i) == 0)w_date2=keyno[i-1];else{for (j=0; j<keytime-i; j++){w_date2=keyno[i-1]*10;}}date2=date2+w_date2;}}else{for (i=keytime-8; i>0; i--){lcd_display_shuzi(2,1,n,keyno[i-1]);n--;for (j=0; j<keytime-i; j++){w_date1=keyno[i-1]*10;}date2=date2+w_date2;}m=7;for (i=keytime; i>keytime-8; i--){lcd_display_shuzi(1,1,m,keyno[i-1]);m--;if ((keytime-i) == 0)w_date2=keyno[i-1];else{for (j=0; j<keytime-i; j++){w_date2=keyno[i-1]*10;}}date2=date2+w_date2;}}}}/*if (KeyNO1 == 15){keytime= keytime-1;for (j=keytime; j>=0;j--){if ((keytime-j) == 0)w_date2=keyno[keytime];else{for (i=0; i<keytime-j; i++){w_date2=keyno[keytime--]*10;}}date2=date2+w_date2;}} */if (opercha>=10 && opercha<=13){m=7;if (KeyNO1 == 14){switch(opercha){case 10:result=date1+date2;break;case 11:result=date1-date2;break;case 12:result=date1*date2;break;case 13:result=date1/date2;break;default:break;}for (i=1; ;i++){date10n=1;for (j=0; j<i-1; j++){date10n=date10n*10;}date10n_d[i-1]=(result / date10n) % 10;if (date10n*10>result){j=i;break;}}P3=result / date10n;for (i=0;i<j;i++){lcd_display_shuzi(1,2,m,date10n_d[i]);m--;}/* lcd_display_shuzi(1,2,7,result);P3 =opercha; */}}}void main(){keytime=0;date1=0;date2=0;w_date1=0;w_date2=0;result=0;opercha=0;KeyNO1=16;date10n=1;LCD_init();qinping(0);lcd_display_hanzi(2,0,0,0); //LCD显示汉字"数" //screen:选择屏幕参数,page:选择页参数0-3,lie列参数0-3,mun:显示第几个汉字的参数lcd_display_hanzi(2,0,1,1); //LCD显示汉字"据"lcd_display_shuzi(2,0,4,1); //LCD显示数字"1"lcd_display_shuzi(2,0,5,10);//LCD显示符号":"lcd_display_hanzi(2,1,0,0); //LCD显示汉字"数"lcd_display_hanzi(2,1,1,1); //LCD显示汉字"据"lcd_display_shuzi(2,1,4,2); //LCD显示数字"2"lcd_display_shuzi(2,1,5,10);//LCD显示符号":"lcd_display_hanzi(2,2,0,2); //LCD显示汉字"结"lcd_display_hanzi(2,2,1,3); //LCD显示汉字"果"lcd_display_shuzi(2,2,4,10);//LCD显示符号":"while(1){P1 = 0x0f;if (P1 != 0x0f){delay(1);if (P1 != 0x0f){write_key();while (P1 != 0x0f);}}}}。
怎样用51单片机做计算器啊?原理图51单片机简易计算器程序:#include <reg51.h>#include <math.h>#define uchar() unsigned char()#define uint unsigned int//---------定义引脚--------------------bit clr=0;bit ok=0;bit xiaoshu=0;bit jiego=0;bit first_1=1;bit first_2=1;sbit dout = P3^2;sbit load = P2^0;sbit din = P2^1;sbit dclk = P2^2;sbit beer=P0^1;sbit LCD1602_RS=P2^3;sbit LCD1602_RW=P2^4;sbit LCD1602_E=P2^5;//---------定义变量-------------------- uchar() ch451_key=0xff;uchar yun_sign;uchar xiabiao=0;uchar tab[32];uchar tab1[]={"welcome to use!"};uchar tab2[]={" make by JunRu!"};uchar tab3[]={"ERR0R"};float opr_1=0,opr_temp=0,end=0,a;//---------声明函数--------------------void ch451_init(void); //CH451初始化void ch451_write(uint command);//写命令或数据到ch451uchar ch451_read()(void); //读按键值uchar get_char(void);void LCD_init(void);//初始化;void delay(unsigned int k);//延时程序void LCD_inter_command(unsigned char command);//写入控制字void LCD_inter_dat(unsigned char dat);//写入要显示的数据void set_xy(unsigned char x,unsigned char y);//找地址void write(unsigned char date);//写入字符void lcdbusy();//查忙时void display()(void);void spec(void);void get_end(void);void hun_he(uchar n);//-------- 主函数----------------------void main(){uchar i;LCD_init();//LCD初始化;ch451_init();//CH451初始化EA = 1;//打开中断LCD_inter_command(0x01);//清屏for(i=0;i<=14;i++){LCD_inter_dat(tab1[i]);beer=0;delay(4000);//延时beer=1;}LCD_inter_command(0xc0);//从第二行开始显示for(i=0;i<=14;i++){LCD_inter_dat(tab2[i]);beer=0;delay(4000);//延时beer=1;}delay(0xffff);delay(0xffff);LCD_inter_command(0x01);while(1){if(ok){display()();ok=0;clr=1;}}}//----------子函数--------------------void hun_he(uchar n){int j;switch(n){case '+':opr_temp=opr_temp+opr_1;break;case '-':opr_temp=opr_temp-opr_1;break;case '*':opr_temp=opr_temp*opr_1;break;case '/':{if(a==0)//减数为零显错{ LCD_inter_command(0xc0);for(j=0;j<=4;j++){LCD_inter_dat(tab3[j]);beer=0;delay(4000);//延时beer=1;}}else{opr_temp=opr_temp/opr_1;}break;}default:break;}}void ch451_init(void)//CH451初始化{EX0 = 1;din = 0;din = 1;ch451_write(0x403); //开显示ch451_write(0x580); //BCD译码方式}void ch451_write(uint command)//写命令或数据到ch451 { uchar i;load = 0;for(i=0;i<12;i++){din = command&1;dclk = 0;command>>=1;dclk = 1;}load = 1;EX0 = 1;}uchar ch451_read()(void)//读按键值{ uchar key=0x07;uchar i;EX0=0;load = 0;for(i=0;i<4;i++) //将0111读入{din = key &1;dclk = 0;key>>=1;dclk =1;}load = 1;key = 0;for(i=0;i<7;i++) //从CH451读出按键值{key<<=1;key|= dout;dclk =1;}EX0 =1;return key;}void EX0_ISR(void)interrupt 0 //中断程序{uchar temp;ch451_key=ch451_read()(); //将读出的按键值赋给变量spec();if(clr) {LCD_inter_command(0x01);clr=0;}temp=get_char();if(temp){tab[xiabiao++]=temp; LCD_inter_dat(temp);}if(xiabiao>=16)LCD_inter_command(0xc0);//若大于16,则从第2行开始显示if(ok) get_end();beer=0;delay(3000);beer=1;}uchar get_char(void){uchar dis=0;uint temp=0,temp1=0;switch(ch451_key){case 0x40:dis='1';break;case 0x41:dis='2';break;case 0x42:dis='3';break;case 0x48:dis='4';break;case 0x49:dis='5';break;case 0x4A:dis='6';break;case 0x50:dis='7';break;case 0x51:dis='8';break;case 0x52:dis='9';break;case 0x58:dis='0';break;case 0x43:dis='+';break;case 0x4B:dis='-';break;case 0x53:dis='x';break;case 0x5B:dis='/';break;case 0x44:dis='!';break;case 0x5A:dis='=';ok=1; //遇到“=”,开始运算break;case 0x59:dis='.';break; //小数点case 0x5C: //删除键LCD_inter_command(0x01);xiabiao=0;break;default: break;}return dis;}void spec(void) //特殊功能键{switch(ch451_key){case 0x4C:LCD_inter_command(0x10);{if(xiabiao>0)xiabiao-=1;}break; //左移case 0x54:LCD_inter_command(0x14);{xiabiao+=1;}break; //右移default:break;}}void delay(unsigned int k)//延时程序{while (k--);}void LCD_inter_command(unsigned char command)//写入控制字{delay(5000);LCD1602_RS=0;LCD1602_RW=0;LCD1602_E=1;P1=command;LCD1602_E=0;lcdbusy();}void LCD_init(void)//初始化;{delay(5000);LCD_inter_command(0x01);//清屏delay(5000);LCD_inter_command(0x38);//设置为8位的数据接口,两行显示,5、7点字符delay(5000);LCD_inter_command(0x0E);//显示打开,光标开并闪烁delay(5000);}void LCD_inter_dat(unsigned char dat)//写入要显示的数据{delay(5000);LCD1602_RS=1;LCD1602_RW=0;LCD1602_E=1;P1=dat;LCD1602_E=0;lcdbusy();}void lcdbusy()//查忙{P1=0xFF;LCD1602_RS=0;LCD1602_RW=1;LCD1602_E=1;while((P1&0x80)==1);}void display()(void) //转化在LCD上显示计算结果{int temp=end; //浮点数int i;uint xiao_temp;uint xx; //浮点数的整数部分if (end>-32769&&end<32768){xx=fabs(end);xiao_temp=(fabs(end)-xx)*1000;//取出浮点数的小数部分LCD_inter_command(0xc0);if(end<0) LCD_inter_dat('-');beer=0;delay(4000); beer=1;//判断是否为负数,若是则显示负号if(xx>9999) LCD_inter_dat((xx/10000)%10+'0'); beer=0;delay (4000);beer=1;if(xx>999) LCD_inter_dat((xx/1000)%10+'0');beer=0;delay(40 00);beer=1; //在LCD上显示千位的数if(xx>99)LCD_inter_dat((xx/100)%10+'0'); beer=0;delay(400 0);beer=1;//百位if(xx>9)LCD_inter_dat((xx/10)%10+'0');beer=0;delay(4000); b eer=1;//十位LCD_inter_dat(xx%10+'0');beer=0;delay(4000); beer=1;//个位if(xiao_temp!=0) //显示小数部分{LCD_inter_dat('.');beer=0;delay(4000);beer=1;LCD_inter_dat((xiao_temp/100)%10+'0');beer=0;delay(4000); beer=1;LCD_inter_dat((xiao_temp/10)%10+'0');beer=0;delay(4000);b eer=1;LCD_inter_dat(xiao_temp%10+'0');beer=0;delay(4000);beer= 1;}}else {LCD_inter_command(0xc0);//从第二行开始显示for(i=0;i<=4;i++){ LCD_inter_dat(tab3[i]);beer=0;delay(4000);//延时beer=1;}}}void get_end(void)//计算子程序{ float xiaoshu=1;uchar fu_flag=0;uchar xiao_flag=0;uchar lianji_sign;uchar i=0;uchar j;uchar n;//正负标记符while(i<=xiabiao){while(tab[i]<=0x39&&tab[i]>=0x30){n=0;opr_1*=10;opr_1+=tab[i++]-0x30;n='+';}switch(tab[i]){case '.': xiao_flag=1;break;//遇到小数点跳到“if(xiao_flag)”里case '!': fu_flag=1;break;case '+': xiaoshu=1;yun_sign='+';if(opr_temp==0){end=opr _temp=opr_1;}else hun_he(lianji_sign);opr_1=0;lianji_sign='+'; br eak;case '-': xiaoshu=1;yun_sign='-';if(opr_temp==0){end=opr_temp=opr_1;}else hun_he(lianji_sign );opr_1=0;lianji_sign='-'; break;case 'x': xiaoshu=1;yun_sign='x';if(opr_temp==0){end=opr_temp=opr_1;}else hun_he(lianji_sign);opr_1=0;lianji_sign='*';brea k;case '/': xiaoshu=1;yun_sign='/';if(opr_temp==0){end=opr_ temp=opr_1;}else hun_he(lianji_sign);a=opr_1;opr_1=0;lianji_sig n='/';break;case '=':switch(yun_sign)//进行运算{case '+':end=opr_temp+opr_1;break;case '-':end=opr_temp-opr_1;break;case 'x':end=opr_temp*opr_1;break;case '/':{if(a==0)//减数为零显错{ LCD_inter_command(0xc0);for(j=0;j<=4;j++){LCD_inter_dat(tab3[j]);beer=0;delay(4000);//延时beer=1;}}else{end=opr_temp/opr_1;}break;}default:break;}ok=1;//开始进行显示,标志位置1xiabiao=0;//小数的标志位清零break;default:break;}i++;if(xiao_flag)//表示小数{while(tab[i]<=0x39&&tab[i]>=0x30){xiaoshu*=0.1;switch(n){case '+': opr_1=opr_1+(tab[i++]-0x30)*xiaoshu;break; case '-': opr_1=opr_1-(tab[i++]-0x30)*xiaoshu; break ; default:break; }xiao_flag=0;}}if(fu_flag){while(tab[i]<=0x39&&tab[i]>=0x30){n=0;opr_1=-opr_1*10;opr_1=-(opr_1+(tab[i++]-0x30));n='-';fu_flag=0;}}}opr_1=0;opr_temp=0; xiabiao=0; xiaoshu=1;下方为原理图:。
自己制作的单片机程序,既可以用数码管显示,也可以用1602显示,且可以显示小数~~~#include<reg52.h>#include <math.h>#define uint unsigned int#define uchar unsigned charuchar code tabledu[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71 };uchar code tabledu1[16]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,0xf7,0xfc,0xb9,0xde,0xf9,0xf1}; uchar code tablewe[8]={0,1,2,3,4,5,6,7};uchar code table[]="0123456789";uchar dispbuf[4]={0,0,0,0};float dispbuf1[4]={0,0,0,0};uchar aa,temp,key,keypos,flag,fuhao,a0,b0,c0,d0,e0,flag1,flag2,a1,b1,c1,d1;float num1,num2,num3,flag3=1;int num5,num6,num7,n2;long n1;sbit RS=P2^5;sbit RW=P2^6;sbit E=P2^7;sbit key1=P3^2;sbit key2=P3^3;sbit key3=P3^4;void keyscan1();void ukeyscan1();void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void change(uchar *p,uchar count){count=4-count;while(count<3){*(p+count)=*(p+count+1);count++;}}float jisuan(float x,char y,float z){float m;if(y==10)m=x+z;if(y==11)m=x-z;if(y==12)m=x*z;if(y==13)m=x/z;return m;}bit Busy(void){bit busy_flag = 0;RS = 0;RW = 1;E = 1;delay(1);busy_flag = (bit)(P0 & 0x80);E = 0;return busy_flag;}void wcmd(uchar del){while(Busy());RS=0;RW=0;E=0;P0=del;delay(1);E=1;delay(1);E=0;}void wdata(uchar del){while(Busy());RS=1;RW=0;E=0;P0=del;delay(1);E=1;delay(1);E=0;}void keyscan(){P1=0xfe;temp=P1;temp=temp&0xf0;while(temp!=0xf0){delay(5);temp=P1;temp=temp&0xf0;while(temp!=0xf0){temp=P1;switch(temp){case 0xee:key=1;break;case 0xde:key=2;break;case 0xbe:key=3;break;case 0x7e:key=4;break;}while(temp!=0xf0){temp=P1;temp=temp&0xf0;}if ((key>=0)&&(key<10)){keypos++;if(flag2==0){if(keypos<=4){change(dispbuf,keypos);dispbuf[3]=key;}}else dispbuf1[keypos-1]=key;}}}P1=0xfd;temp=P1;temp=temp&0xf0;while(temp!=0xf0){delay(5);temp=P1;while(temp!=0xf0){temp=P1;switch(temp){case 0xed:key=5;break;case 0xdd:key=6;break;case 0xbd:key=7;break;case 0x7d:key=8;break;}while(temp!=0xf0){temp=P1;temp=temp&0xf0;}if ((key>=0)&&(key<10)){keypos++;if(flag2==0){if(keypos<=4){change(dispbuf,keypos);dispbuf[3]=key;}}else dispbuf1[keypos-1]=key;}}}P1=0xfb;temp=P1;temp=temp&0xf0;while(temp!=0xf0){delay(5);temp=P1;while(temp!=0xf0){temp=P1;switch(temp){case 0xeb:key=9;break;case 0xdb:key=0;break;case 0xbb:key=10;break;case 0x7b:key=11;break;}while(temp!=0xf0){temp=P1;temp=temp&0xf0;}if ((key>=0)&&(key<10)){keypos++;if(flag2==0){if(keypos<=4){change(dispbuf,keypos);dispbuf[3]=key;}}else dispbuf1[keypos-1]=key;}if ((key>9)&&(key<14)){fuhao=key;num1=1000*dispbuf[0]+100*dispbuf[1]+10*dispbuf[2]+dispbuf[3]+dispbuf1[0]/10+dispbuf 1[1]/100+dispbuf1[2]/1000+dispbuf1[3]/10000;dispbuf[0]=0;dispbuf[1]=0;dispbuf[2]=0;dispbuf[3]=0;dispbuf1[0]=0;dispbuf1[1]=0;dispbuf1[ 2]=0;dispbuf1[3]=0;keypos=0;flag2=0;while(1){keyscan1();if(key==15)break;}}if(key==15){dispbuf[0]=0;dispbuf[1]=0;dispbuf[2]=0;dispbuf[3]=0;dispbuf1[0]=0;dispbuf1[1]=0;dispbuf1[ 2]=0;dispbuf1[3]=0;keypos=0;flag2=0;}}}P1=0xf7;temp=P1;temp=temp&0xf0;while(temp!=0xf0){delay(5);temp=P1;temp=temp&0xf0;while(temp!=0xf0){temp=P1;switch(temp){case 0xe7:key=12;break;case 0xd7:key=13;break;case 0xb7:key=14;break;case 0x77:key=15;break;}while(temp!=0xf0){temp=P1;temp=temp&0xf0;}if ((key>=0)&&(key<10)){keypos++;if(flag2==0){if(keypos<=4){change(dispbuf,keypos);dispbuf[3]=key;}}else dispbuf1[keypos-1]=key;}if ((key>9)&&(key<14)){fuhao=key;num1=1000*dispbuf[0]+100*dispbuf[1]+10*dispbuf[2]+dispbuf[3]+dispbuf1[0]/10+dispbuf 1[1]/100+dispbuf1[2]/1000+dispbuf1[3]/10000;dispbuf[0]=0;dispbuf[1]=0;dispbuf[2]=0;dispbuf[3]=0;dispbuf1[0]=0;dispbuf1[1]=0;dispbuf1[ 2]=0;dispbuf1[3]=0;keypos=0;flag2=0;while(1){keyscan1();if(key==15)break;}}if(key==15){dispbuf[0]=0;dispbuf[1]=0;dispbuf[2]=0;dispbuf[3]=0;dispbuf1[0]=0;dispbuf1[1]=0;dispbuf1[ 2]=0;dispbuf1[3]=0;keypos=0;flag2=0;}}}if(keypos==4)keypos=0;if(key1==0){delay(5);if(key1==0){while(key1==0);flag2=1;keypos=0;}}if(key2==0){delay(5);if(key2==0){while(key2==0);num1=1000*dispbuf[0]+100*dispbuf[1]+10*dispbuf[2]+dispbuf[3]+dispbuf1[0]/10+dispbuf 1[1]/100+dispbuf1[2]/1000+dispbuf1[3]/10000;num3=sqrt(num1);num6=num3;num5=(num3-num6)*10000;dispbuf[0]=num6/1000;dispbuf[1]=num6%1000/100;dispbuf[2]=num6%1000%100/10;dispbuf[3]=num6%1000%100%10;dispbuf1[0]=num5/1000;dispbuf1[1]=num5%1000/100;dispbuf1[2]=num5%1000%100/10;dispbuf1[3]=num5%1000%100%10;}}}void keyscan1(){P1=0xfe;temp=P1;temp=temp&0xf0;while(temp!=0xf0){delay(5);temp=P1;temp=temp&0xf0;while(temp!=0xf0){temp=P1;switch(temp){case 0xee:key=1;case 0xde:key=2;break;case 0xbe:key=3;break;case 0x7e:key=4;break;}while(temp!=0xf0){temp=P1;temp=temp&0xf0;}if ((key>=0)&&(key<10)){keypos++;if(flag2==0){if(keypos<=4){change(dispbuf,keypos);dispbuf[3]=key;}}else dispbuf1[keypos-1]=key;}}}P1=0xfd;temp=P1;temp=temp&0xf0;while(temp!=0xf0){delay(5);temp=P1;temp=temp&0xf0;while(temp!=0xf0){temp=P1;switch(temp){case 0xed:key=5;break;case 0xdd:key=6;case 0xbd:key=7;break;case 0x7d:key=8;break;}while(temp!=0xf0){temp=P1;temp=temp&0xf0;}if ((key>=0)&&(key<10)){keypos++;if(flag2==0){if(keypos<=4){change(dispbuf,keypos);dispbuf[3]=key;}}else dispbuf1[keypos-1]=key;}}}P1=0xfb;temp=P1;temp=temp&0xf0;while(temp!=0xf0){delay(5);temp=P1;temp=temp&0xf0;while(temp!=0xf0){temp=P1;switch(temp){case 0xeb:key=9;break;case 0xdb:key=0;。
***************51单片机简易计算器************按键介绍:| 7 | 8 | 9 | + |-------------| 4 | 5 | 6 | -|-------------| 1 | 2 | 3 | * |-------------| 0 | = | C | / |操作说明:按下第一个数(0—9)后再按运算符(+ - * /),最后按=显示结果,按C 可以清除全屏加最大:9999+9999=19998乘最大:9999*9999=99980001除:1/9=0.1111保留小数点后四位#include <REGX52.H>#define uint unsigned int#define uchar unsigned char/******************LCD1602**********************/#define LCD_RS P2_4//定义LCD_RS端口#define LCD_RW P2_5//定义LCD_RW端口#define LCD_EN P2_6//定义LCD_EN端口#define LCD_DA P0//定义LCD_DA端口(数据端)#define KEY P3//定义矩阵按键为P3口#define Speak P2_3//定义蜂鸣器端口#define LED P2_2//定义指示灯#define KEY_1P2_0//定义按键为P1.7口(开/关蜂鸣器、LED灯) #define LED1P1//定义流水指示灯/**************定义显示数据数组*************/uchar code table[]= {" "};/****************定义动画数组***************/uchar code table1[]={" Welcome to "};uchar code table2[]={" 51 MCU Counter "};/*************定义流水灯显示数组************/uchar code table3[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//从低位往高位(流水)uchar code table4[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//从高位往低位(流水)uchar code table5[]={0x7e,0xbd,0xdb,0xe7};//从两边往中间(流水)uchar code table6[]={0xe7,0xdb,0xbd,0x7e};//从中间往两边(流水)/***************定义运算数据***************/long int data_a=0;//第一个数long int data_b=0; //第二个数long int data_c=0;//计算结果uchar dispaly[10]; //显示缓冲uchar i,j;//定义i,juchar flag=1;//定义开/关蜂鸣器、LED灯标志位,初始化为1uchar n=1;//定义n为1(默认8位LED显示流水状态1)uchar k=0;//定义kuchar num=0;//定义时间基数初始值为0uchar key=0xff; //键值初始化uchar a=0;//第1个数可以按1-4次(在主函数中体现)uchar b=5; //第2个数可以按1-4次(在主函数中体现)uchar x=0; //定义x=0/***************延时函数*********************/void delay(uint time)//延时函数{uint i,j;for(i=time;i>0;i--)for(j=110;j>0;j--);}/***************蜂鸣器响延时函数************/void delay_fmq(uint time)//蜂鸣器响延时函数{uint x,y;for(x=time;x>0;x--)for(y=5;y>0;y--);}/************LED灯闪烁并且蜂鸣器响***********/void spk()//LED灯闪烁并且蜂鸣器响{LED=0;//LED亮for(j=0;j<100;j++)//利用for语句延时{Speak=0;//蜂鸣器为低电平delay_fmq(5);//延时Speak=1;//蜂鸣器为高电平delay_fmq(5);//延时}LED=1;//LED灭}/***************1602液晶写指令*****************/void write_com(uchar com) //1602液晶写指令(参照LCD1602时序图) {LCD_RS=0; //写指令LCD_RW=0;//写液晶LCD_DA=com; //写入指令comdelay(2); //延时LCD_EN=1; //使能1602delay(2); //延时LCD_EN=0;//使能1602}/****************1602液晶写数据***************/void write_date(uchar date) //1602液晶写数据(参照LCD1602时序图) {LCD_RS=1; //写数据LCD_RW=0; //写液晶LCD_DA=date; //写入数据datedelay(2);//延时LCD_EN=1; //使能1602delay(2); //延时LCD_EN=0;//使能1602}/****************指定x,y写入字符函数*********/void W_lcd(unsigned char x,unsigned char y,unsigned char Data){if(y==0)//如果y=0{write_com(0x80 + x);//第一行}else//否则y=1{write_com(0xc0 + x);//第二行}write_date(Data); //写入数据}/****************指定x,y写入字符串函数********/void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s){if(y==0)//如果y=0{write_com(0x80 + x);//第一行}else//否则y=1{write_com(0xC0 + x);//第二行}while(*s){write_date(*s);//写入数据s++;//s++}}/*****************初始化液晶******************/void LCD_init() //初始化液晶{write_com(0x38); //8 位总线,双行显示,5X7 的点阵字符write_com(0x0c); //开显示,无光标,光标不闪烁write_com(0x01); //清屏}/*****************开机动画********************/void cartoon()//开机动画{spk();//蜂鸣器响,LED亮write_com(0x80);//写指令准备显示第1行第1个for(i=0;i<16;i++)//for语句循环16次{write_date(table1[i]);//写数据" Welcome to "delay(100);//延时一下(为了数字、字母一个一个显示) }write_com(0xc0);//写指令准备显示第2行第1个for(i=0;i<16;i++)//for语句循环16次{write_date(table2[i]);//写数据" 51 MCU Counter "delay(100);//延时一下(为了数字、字母一个一个显示) }spk();//蜂鸣器响,LED亮delay(200);}/*************反转法键盘扫描******************/short keycheckdown()//反转法键盘扫描{short temp1,temp2,temp,a=0xff;KEY=0xf0;//输入行值(或列值)delay(20);//延时temp1=KEY;//读列值(或行值)KEY=0xff;delay(20);//延时KEY=0x0f;//输入列值(或行值)delay(20);//延时temp2=KEY;//读行值(或列值)KEY=0xff;temp=(temp1&0xf0)|(temp2&0xf);//将两次读入数据组合switch(temp)//通过读入数据组合判断按键位置{/************第一行按键7 8 9 + *********/case 0xee :a=7; //按键7if(flag==1)//若flag为1,则蜂鸣器响,LED亮{spk();}break; //返回case 0xed :a=8; //按键8if(flag==1)//若flag为1,则蜂鸣器响,LED亮{spk();}break; //返回case 0xeb :a=9; //按键9if(flag==1)//若flag为1,则蜂鸣器响,LED亮{spk();}break; //返回case 0xe7 :a=0x0a;//按键+if(flag==1)//若flag为1,则蜂鸣器响,LED亮{spk();}break; //返回/************第二行按键4 5 6 - *********/case 0xde :a=4; //按键4if(flag==1)//若flag为1,则蜂鸣器响,LED亮{spk();}break; //返回case 0xdd :a=5; //按键5if(flag==1)//若flag为1,则蜂鸣器响,LED亮{spk();}break; //返回case 0xdb :a=6; //按键6if(flag==1)//若flag为1,则蜂鸣器响,LED亮spk();}break; //返回case 0xd7 :a=0x0b;//按键-if(flag==1)//若flag为1,则蜂鸣器响,LED亮{spk();}break; //返回/************第三行按键1 2 3 * *********/case 0xbe :a=1; //按键1if(flag==1)//若flag为1,则蜂鸣器响,LED亮{spk();}break; //返回case 0xbd :a=2; //按键2if(flag==1)//若flag为1,则蜂鸣器响,LED亮{spk();}break; //返回case 0xbb :a=3; //按键3if(flag==1)//若flag为1,则蜂鸣器响,LED亮{spk();}break; //返回case 0xb7 :a=0x0c;//按键*if(flag==1)//若flag为1,则蜂鸣器响,LED亮{spk();break; //返回/************第四行按键0 = C / *********/case 0x7e :a=0;//按键0if(flag==1)//若flag为1,则蜂鸣器响,LED亮{spk();}break; //返回case 0x7d :a=0x0e;//按键=if(flag==1)//若flag为1,则蜂鸣器响,LED亮{spk();}break; //返回case 0x7b :a=0x0f;//按键Cif(flag==1)//若flag为1,则蜂鸣器响,LED亮{spk();}break; //返回case 0x77 :a=0x0d;//按键/if(flag==1)//若flag为1,则蜂鸣器响,LED亮{spk();}break; //返回default :a=0xff;//没有键按下}return a;//返回按键值}/******************显示数据a******************/ void display_a() //显示数据a{dispaly[3]=data_a%10000/1000; //千位dispaly[2]=data_a%1000/100; //百位dispaly[1]=data_a%100/10; //十位dispaly[0]=data_a%10; //个位write_com(0x80+0); //显示数据aif(data_a>999){write_date('0'+dispaly[3]);//显示千位}if(data_a>99){write_date('0'+dispaly[2]);//显示百位}if(data_a>9){write_date('0'+dispaly[1]); //显示十位}write_date('0'+dispaly[0]); //显示个位}/******************显示数据b******************/ void display_b() //显示数据b{write_com(0x80+7); //第一行dispaly[3]=data_b%10000/1000; //千位dispaly[2]=data_b%1000/100; //百位dispaly[1]=data_b%100/10; //十位dispaly[0]=data_b%10; //个位if(data_b>999){write_date('0'+dispaly[3]);//显示千位}if(data_b>99){write_date('0'+dispaly[2]); //显示百位}if(data_b>9){write_date('0'+dispaly[1]); //显示十位}write_date('0'+dispaly[0]); //显示个位}/******************计算结果*******************/void display_c(x){if(data_c<100000000&&data_c>-1)//溢出时显示错误{dispaly[8]=data_c%1000000000/100000000; //万万dispaly[7]=data_c%100000000/10000000; //千万dispaly[6]=data_c%10000000/1000000; //百万dispaly[5]=data_c%1000000/100000; //十万dispaly[4]=data_c%100000/10000; //万dispaly[3]=data_c%10000/1000; //千dispaly[2]=data_c%1000/100; //百dispaly[1]=data_c%100/10; //十dispaly[0]=data_c%10; //个write_com(0x80+0x40+7); //第二行if(x==4){if(data_c>99999999){write_date('0'+dispaly[8]);//显示万万}if(data_c>9999999){write_date('0'+dispaly[7]);//显示千万}if(data_c>999999){write_date('0'+dispaly[6]);//显示百万}if(data_c>99999){write_date('0'+dispaly[5]);//显示十万}write_date('0'+dispaly[4]); //万write_date('.');write_date('0'+dispaly[3]); //千write_date('0'+dispaly[2]); //百write_date('0'+dispaly[1]); //十write_date('0'+dispaly[0]); //个}else{if(data_c>99999999){write_date('0'+dispaly[8]);//显示万万}if(data_c>9999999){write_date('0'+dispaly[7]);//千万}if(data_c>999999){write_date('0'+dispaly[6]);//百万}if(data_c>99999){write_date('0'+dispaly[5]);//十万}if(data_c>9999){write_date('0'+dispaly[4]);//万}if(data_c>999){write_date('0'+dispaly[3]);//千}if(data_c>99){write_date('0'+dispaly[2]);//百}if(data_c>9){write_date('0'+dispaly[1]);//十}write_date('0'+dispaly[0]); //个}}else //溢出时显示错误{write_com(0x80+0x40+11); //第二行write_date('E'); //显示Ewrite_date('r'); //显示Rwrite_date('r');//显示Rwrite_date('o');//显示Owrite_date('r');//显示R}}/****************加减乘除运算*****************/void eql(uchar yunsuan)//加减乘除运算{switch(yunsuan)//功能键选择{case 1:data_c=data_a+data_b;//加法break; //返回case 2:if(data_a>=data_b)//若a>b{data_c=data_a-data_b;//减法}else//否则a<b{data_c=data_b-data_a;//减法W_lcd(5,1,'-');//带上负号}break; //返回case 3:data_c=(data_a*data_b);//乘法break;//返回case 4:if(data_b==0)//如果被除数为0{LCD_Write_String(1,1,"Error");//除法溢出时显示错误}else{data_c=(data_a*10000)/data_b;//除法}break;//返回case 0: break;//不做运算返回}}/****************定时器0初始化****************/void Time0_init()//定时器0初始化{TMOD=0x01;//定时器0为方式1TL0=(65536-50000)%256;TH0=(65536-50000)/256;//12M晶振定时时间50msET0=1;//开定时器0中断EA=1;//开总中断TR0=1;//开启定时器0}/****************开/关指示函数***************/void K_G_ZS()//开/关指示函数{if(KEY_1==0)//若按键按下{delay(20);//延时去抖if(KEY_1==0)//再次确认按键是否按下{flag=!flag;//flag取反}//flag=0关闭蜂鸣器响和LED亮。
/*...............菜鸟一枚,不好勿喷→_→............................【简易计算器的功能简介】【时间紧,先做个简易的吧,复杂的算法太难,没那么多时间写【现在也不太会→_→】,以后再研究→_→】此程序是完全基于开发板的,可在板子上直接测试【程序跑飞的概率比较大,还不太明白是哪的问题】可实现总数小于等于九位【long int】的数字的加减乘除运算【每次只能进行一项】,可清楚修改输入的数据,由于键盘等因素显示【4X4】,没有小数点键,故无法直接进行小数运算,进行除法运算时,小数点后最多可保留6位,第7位进行四舍五入。
显示器采用1602,输入或修改时开光标并闪烁,输入数据超出9位,有警告提示,加上运算符总的输入不超过15位【超过10输入逻辑已经错误】。
显示结果时关光标【重复按下时结果不变】,显示结果后,也可对输入端进行修改,按下等于键再次显示结果。
2015/1 qq:1036894850 */#include"reg52.h"#include"stdio.h"#define uchar unsigned charsbit rs=P2^4;//lcd的控制线口sbit rw=P2^5;sbit ep=P2^6;uchar ip[15];//存输入的数据,15位【理论上10位就够了】'$'记运算符'*'记为负号uchar sign;//存运算符int k=0,equ=0,sk=0,ksk=0,sg=0;void write_data(uchar dat); //给1602写数据void write_com(uchar com);void lcdinit();void delay(int z);void warn();void key_deal(uchar key);void sdeal(uchar i);void key_sub_deal();void key_equ_deal();void key_del_deal();uchar scankey();void main(){uchar key=0xff;lcdinit(); //1602初始化,结果输出位显示0,数据输入位光标闪烁。
DBUF EQU 30HTEMP EQU 40HYJ EQU 50H ;结果存放YJ1 EQU 51H ;中间结果存放GONG EQU 52H ;功能键存放ORG 00HSTART: MOV R3,#0 ;初始化显示为空MOV GONG,#0MOV 30H,#10HMOV 31H,#10HMOV 32H,#10HMOV 33H,#10HMOV 34H,#10HMLOOP: CALL DISP ;PAN调显示子程序WAIT: CALL TESTKEY ;判断有无按键JZ WAITCALL GETKEY ;读键INC R3 ;按键个数CJNE A,#0,NEXT1 ;判断就是否数字键LJMP E1 ;转数字键处理NEXT1: CJNE A,#1,NEXT2LJMP E1NEXT2: CJNE A,#2,NEXT3LJMP E1NEXT3: CJNE A,#3,NEXT4LJMP E1NEXT4: CJNE A,#4,NEXT5LJMP E1NEXT5: CJNE A,#5,NEXT6LJMP E1NEXT6: CJNE A,#6,NEXT7LJMP E1NEXT7: CJNE A,#7,NEXT8LJMP E1NEXT8: CJNE A,#8,NEXT9LJMP E1NEXT9: CJNE A,#9,NEXT10LJMP E1NEXT10: CJNE A,#10,NEXT11 ;判断就是否功能键LJMP E2 ;转功能键处理NEXT11: CJNE A,#11,NEXT12LJMP E2NEXT12: CJNE A,#12, NEXT13LJMP E2NEXT13: CJNE A,#13,NEXT14LJMP E2NEXT14: CJNE A,#14,NEXT15LJMP E2NEXT15: LJMP E3 ;判断就是否清除键E1: CJNE R3,#1,N1 ;判断第几次按键LJMP E11 ;为第一个数字N1: CJNE R3,#2,N2LJMP E12 ;为第二个数字N2: CJNE R3,#3,N3LJMP E13 ;为第三个数字N3: LJMP E3 ;第四个数字转溢出E11: MOV R4,A ;输入值暂存R4 MOV 34H,A ;输入值送显示缓存MOV 33H,#10HMOV 32H,#10HLJMP MLOOP ;等待再次输入E12: MOV R7,A ;个位数暂存R7 MOV B,#10MOV A,R4MUL AB ;十位数ADD A,R7MOV R4,A ;输入值存R4MOV 32H,#10H ;输入值送显示缓存MOV 33H,34HMOV 34H,R7LJMP MLOOPE13: MOV R7,AMOV B,#10MOV A,R4MUL ABJB OV,E3 ;输入溢出ADD A,R7JB CY,E3 ;输入溢出MOV R4,AMOV 32H,33H ;输入值送显示缓存MOV 33H,34HMOV 34H,R7LJMP MLOOPE3: MOV R3,#0 ;按键次数清零MOV R4,#0 ;输入值清零MOV YJ,#0 ;计算结果清零MOV GONG,#0 ;功能键设为零MOV 30H,#10H ;显示清空MOV 31H,#10HMOV 32H,#10HMOV 33H,#10HMOV 34H,#10HLJMP MLOOPE2: MOV 34H,#10HMOV 33H,#10HMOV 32H,#10HMOV R0,GONG ;与上次功能键交换MOV GONG,AMOV A,R0CJNE A,#10,N21 ;判断功能键LJMP JIA ;"+"N21: CJNE A,#11,N22LJMP JIAN ;"-"N22: CJNE A,#12,N23LJMP CHENG ;"*"N23: C JNE A,#13,N24LJMP CHU ;"/"N24: C JNE A,#0,N25LJMP FIRST ;首次按功能键N25: L JMP DEN ;"="N4: LJMP E3FIRST: MOV YJ,R4 ;输入值送结果MOV R3,#0 ;按键次数清零LJMP DISP1 ;结果处理JIA: MOV A,YJ ;上次结果送累加器ADD A,R4 ;上次结果加输入值JB CY,N4 ;溢出MOV YJ,A ;存本次结果MOV R3,#0 ;按键次数清零LJMP DISP1JIAN: MOV A,YJSUBB A,R4 ;上次结果减输入值JB CY,N4 ;负数溢出MOV YJ,AMOV R3,#0LJMP DISP1CHENG: MOV A,YJMOV B,AMOV A,R4MUL AB ;上次结果乘输入值JB OV,N4 ;溢出MOV YJ,ALJMP DISP1CHU: MOV A,R4MOV B,AMOV A,YJDIV AB ;上次结果除输入值MOV YJ,AMOV R3,#0LJMP DISP1DEN: MOV R3,#0LJMP DISP1DISP1: MOV B,#10MOV A,YJ ;结果送累加器DIV AB ;结果除10MOV YJ1,A ;暂存"商"MOV A,B ;取个位数MOV 34H,A ;个位数送显示缓存MOV A,YJ1JZ DISP11 ;结果就是否为一位数MOV B,#10MOV A,YJ1DIV ABMOV YJ1,AMOV A,BMOV 33H,A ;十位送显示缓存MOV A,YJ1JZ DISP11 ;结果就是否为二位数MOV 32H,A ;百位数送显示缓存DISP11: LJMP MLOOPDISP: MOV R0,#DBUF ;显示子程序MOV R1,#TEMP+4MOV R2,#5DP10: MOV DPTR,#SEGTABMOV A,@R0MOVC A,@A+DPTRMOV @R1,AINC R0DEC R1DJNZ R2,DP10MOV R0,#TEMPDP12: MOV A,@R0MOV P0,Aclr P2、7CALL D1MSsetb P2、7INC R0MOV A,@R0MOV P0,Aclr P2、6CALL D1MSsetb P2、6INC R0MOV A,@R0MOV P0,Aclr P2、5CALL D1MSsetb P2、5INC R0MOV A,@R0MOV P0,Aclr P2、4CALL D1MSsetb P2、4INC R0MOV A,@R0MOV P0,Aclr P2、3CALL D1MSsetb P2、3RETD1MS: MOV R7,#02HDMS: MOV R6,#0FFHDJNZ R6,$DJNZ R7,DMSRETSEGTAB: DB 028H,7eH,0A2H,062HDB 74H, 61H, 21H, 7aHDB 20H, 60H, 88H, 83HDB 0C6H, 0A1H, 86H, 8EH,0ffHTESTKEY:ACALL DISPMOV P1,#0FH ;读入键状态MOV A,P1CPL AANL A,#0FH ;高四位不用RETKEYTABLE:DB 0DEH,0EDH,0DDH,0BDH ;键码定义DB 0EBH,0DBH,0BBH,0E7HDB 0D7H,0B7H,07EH,07DHDB 07BH,077H,0BEH,0EEHGETKEY: ;读键子程序MOV R6,#10ACALL DELAYMOV P1,#0FHMOV A,P1CJNE A,0FH,K12LJMP MLOOPK12: MOV B,AMOV P1,#0EFHMOV A,P1CJNE A,#0EFH,K13MOV P1,#0DFHMOV A,P1CJNE A,#0DFH,K13MOV P1,#0BFHMOV A,P1CJNE A,#0BFH,K13MOV P1,#07FHMOV A,P1CJNE A,#07FH,K13LJMP MLOOPK13: ANL A,#0F0HORL A,BMOV B,AMOV R1,#16MOV R2,#0MOV DPTR,#KEYTABLEK14: MOV A,R2MOVC A,@A+DPTRCJNE A,B,K16MOV P1,#0FHK15: MOV A,P1CJNE A,#0FH,K15MOV R6,#10ACALL DELAYMOV A,R2RETK16: INC R2DJNZ R1,K14AJMP MLOOPDELAY: MOV R7,#80 ;延时子程序DLOOP: DJNZ R7,DLOOPDJNZ R6,DLOOPRET END。