基于51单片机的简易计算器设计,急
//函数0123456789+-×÷=清除表3-1 3.2计算机程序设计
#include
#defineu intunsignedint //
#defineucharunsignedchar
sbitlcden=P2^3;//定义引脚
sbitrs=P2 ^4;
sbitrw=P2^0;
sbitbusy=P0^7;
chari,j,temp,num,num_1;
长,b,c; ,第一个数字b,第二个数字c,有数字
float_c, b_c;
ucharflag, fuhao; // flag表示是否表示关键符号,fuhao表示。
按下了哪个代码
ucharcodetable[]={7,8,9,0,4,5,6,0,1,2,3,0,0,0,0,0};< /
ucharcodetable1[] ={
7,8,9,0x2 f-0x30,
4,5,6,0x2a-0x30,
1,2,3,0x2d-0x30,
inca(ucharz)//延迟函数
{
uchary;
0;z--)for(y=0;y<110;y++);
} voidcheck()//判断忙还是空闲
{
做{
P0=0xFF;
rs=0; // 读取
lcden=0; 1; sy==1);//判断是否空闲,1忙,0空闲
}
voidwrite_com(ucharcom)//写命令函数
{
P0=com; // com 命令给出 P0 端口
rs=0;
rw=0;
lcden=0;
check( ) ;
lcden=1;
}
voidwrite_date(uchardate)//写入日期函数{
P0=日期;
rs=1;
rw=0;
lcden =0;
check();
lcden=1;
}
voidinit()//初始化
{
num=-1;
lcden==;//拉低信号为高电平
write_com(0x38);//8 位,2 lines
write_com(0x0c);//设置,光标关闭不闪烁*/
write_com(0x06);//递增不改变显示模式?
write_com(0x80);//检测忙信号
write_com(0x01);//显示,光标关闭,不闪烁
num_1=0;
i=0;
j=0;
a=0; 参与操作的数量
b=0;
flag=0;//flag表示是否按下了含义键,
fuhao=0;//fuhao表示按下了哪个数字
}
voidkeyscan()//键盘扫描
{
P3=0xfe;
if(p3!=0xfe
{
wait(20);//等待 20ms
if(P3!=0x fe
{
temp=P3&0xf0;
转(temp
{
cas0xe0:num =0;
断路器;case0xd0:num=1;
break;
case0xb0:num=2;
case0x70:num=3 ;break;}
}
while(P3!=0xfe);
if(是否==0 ||num==||num==2)//如果按'7', '8' 或 '9
{
if(j!=0
{
if(j!=0
{
}
if(fl ag==0)/ / 未按下按键符号 is
{
else // 如果按键被按下
{
flag=1; 4 表示按下除号
}
}P3=0xfd;
i f(p3!=0xfd
{
延迟(5);
if(p3!=0xfd
{
temp=P3&0xf0;
开关(temp
{
case0xe0:num=4;
break;
case se0xb0:num=6;
break;
case0x70:num=7;
break;
}
}
while(P3!=0x fd);
if(num==4||num == 5||num==6&&num!=7)//如果按'4'、'5'或 '6'
{
if(j!=0
{
write_com(0x01); key
{
a=a*10+table[num];
}
else // 如果按下数字键
{
else // 如果按 '/' {flag=1;
}
i=table1[num];
write_date( 0x30+i);
}
P3=0xfb;if(P3!=0xfb
{
延迟(5);
如果 (p3!=0xfb
{
temp=P3&0xf0;
return(temp
{
break;
case0xd0:num=9;
<case0x70:num=11,
break;
}
}
while(P3!=0xfb);
if(num==8||n um==9||num==10)//如果按'1'、'2'或'3'
{
if(j!=0)< /p>
{
write_com(0x01);
j=0;
}
if(flag== 0)//符号键未按下
{
a=a*10+table[num];}
else// 如果按下信号键{
b=b*10+table[num];}
}
seif(num==111)//如果按'-'
{
flag=1;
fuhao=2;/ /2表示信号压力较小
}
i=table1[num];
write_date(0x30+i);
}
P3=0xf7 ;
if(P3!=0xf7
{
延迟(5); <if(P3!=0xf7
{
temp=P3&0xf0;
return(temp
{case0xe0:num=12;
中断;case0x70:num=15;
中断;
}
}
while(P3!=0xf7) ;
switch(num .)
{
case12:{write_com(0x01); a=0;b=0;flag=0;fuhao=0;}//按下的“清除”
break;
> > > > > > > > > > > > case13 > case13 p=a*10; write_date(0x30);P1=0;
}
elseif(flag==1)//如果数字键被按下
{b=b*1 0;
write_date(0x30);
}
}
break;
case14:{j =1; =1){ write_com(0x80+0x4f); 从最后到第一个,每次写入数据,光标都会向后移动一个空格
c=a+b;
while(c!=0
>{write_date(0x30+c%10);
c=c/10 ;
}
write_date(0x3d);
}
0)c=a-b;
else
c=b-a;
while(c!=0
{
write_date(0x30+c%10);
c = c/10;
}
i f(a-b<0
write_date(0x2d);
c=a*b;p>c=c/10;}
write_date(0x3d);
a=0;b=0; flag=0;fuhao=0;
}
elseif(fuhao ==4) {write_ com(0x80+0x4f);
write_com(0x04);
i=0;
c=(long)(((float)a/b )*M);
while(c!=0)
{
write_date(0x30+c%10);
c=c/10;
i++;
write_date(0x2e);
}
if(a/b<=0
中断;case15:{write _date(0x30+table1[num]);flag=1; fuhao=1;}
中断;
}
}
}
ma(
{
init();
while(1
{
keyscan( );
}
}
51单片机设计的简易的计算器
我已经做了一个程序,使用4x4键盘控制电机转速,并使用数码管显示电机转速。该程序是:ADEQU30HRTREQU31HLTREQU32HSTREQU33HBWEQU34HBWSEQU35HSHWEQU36HSHW。
SEQU37HGWEQU38HGWSEQU39HWSHREQU3AH;WSHR=BWS*100+SHWS*10+GWSszEQU3BH;数字和代码对应程序的数值变量xsmEQU3CH;数字和代码对应程序的数值变量Code变量TODHEQU3DH; 计算出的十进制数高位 * 所需电机转速高位 TODLEQU3EH; 计算出的十进制数低位*所需电机转速低位 TODHTEQU3FH; H; PCKEQU41H测试后实际电机转速偏低; PC口当前状态为TOHEQU42H; 定时器的高位为T0LEQU43H; 定时器底部数字为粉色1EQU44H; 定时器1转1/4圈粉色2EQU 45HVTIMESEQU46H; 速度显示次数 T1HEQU47HT1LEQU48HTESTKDATA49H 高电平脉冲数 TTH0EQU1AHTTL0EQU4BHSUBNOWEQU4CHORG0000H; LJMPMAINORG03HAJMPINTR0; 中心段 0,用于计算电机速度 ORG0BHMOVA、PCKANLA、#00000111BMOVPCK、AMOVA、#00000110BCJNEA、PCK、INTT 0LFLJMPINTT0L;ORG1BH;pwm 失速例程 AJMPINTT0HORG0040H;************ ***** ************中断子程序 定时器******** **** ************ ********;****电机停止程序 INTT0H:movth0,TOHmovtl0,T0LSETBTR0 ;定时器0开始计数 CLRTR1;定时器 1 禁止计数INCpink1MOVDPTR,#7F02H;b 地地址 MOVA,#00000000B ;电机停止转动 MOVX@DPTR,Areti;****电机前转子子程序 INTT0L:movth1,T1Hmovtl1,T1LSETBTR1;定时器1开始计数 CLRTR0; 定时器0禁止MOVDPTR计数,#7F02H; 地址b MOVA,#11001100B; MOVX@DPTR口C输出芯片选择LED,Areti; **** 反转电机 INTT0LF: movth1, T1Hmovtl1, T1 LSETBTR1; 定时器1开始计数CLRTR0; 定时器0禁用MOVDPTR计数,#7F02H; 地址b MOVA,#10101100B; MOVX@DPTR口C输出芯片选择LED,Areti; **************计算发动机转速************************; R2R3R4R5/R6R7=R4R5 和 R2R3///(R2R3R4/R7)=(R2)R3R4 仍为 R7INTR0:M OVR2,#00HMOVR3,#0EHMOVR4,#0A6HMOVR7,粉红1MOV粉红1,#0MOVA,#10CLRCYSUBBA,R7JNBCY,OUTINT0LCALLNDIV31MOVT ODHT,R3MOVTODLT,R4MOVR6,TODHMOVR7,TODLCLRCYMOVA,R4SUBBA,R7MOVSUBNOW,AJBCY,ADVLCALLSUBVJMPOUTINT0ADV:LC ALLADDVOUTINT0:LCALLJSW; 计算每个数字的值,以毫秒为单位,或大约 600 个初始 MOVTODLT,TOH 周期; 计算每个数字的值,以毫秒为单位,或大约 600 个初始 RETI 周期;*** ********** ********************* ************************************************** **************;** ****************** * ************** ********************************** * ************** *****************;******************** * ************* ************************************** ** ********** ******************COMP_M:MOVA,#0FDHSUBBA ,TOHJNBCY,OUT_PMMMMOVTOH,#0FDHMOVT1H,#85OUT_PMM:RET;******************** 加速子程序**************** **** ****** ***添加:CLRE ACLRTR1CLRTR0MOVR1,SUBNOWMOVR0,#10000000BFRT:MOVA,R0RLAMOVR0,AMOVA,R1ANLA,R0JZFRTMOVA,TOHADDA,R0JCVMAX MOVTOH,AMOVA,T1HSUBBA,R0MOVT1H,AJMPTXTVMAX:MOVTOH,#0FDHMOVT1H,#85TXT:SETBTR0SETBTR1SETBEARET;******** ****加速器子程序 减速********************************SUBV:CLREACLRTR1CLRTR0MOVR1,SUBNOWMOVR0,#10000000BFRT1:MOVA,R0RLAMO VR0,AMOVA,R1ANLA,R0JZFRT1MOVA,TOHSUBBA,R0JCVMAX1MOVTOH,AMOVA,T1HADDA,R0MOVT1H,AJMPTXT1VMAX1:MOVTOH,#85MOVT1H,#0FDHTXT1:SETBTR0SETBTR1SETBEARET;******************** **** **********主程序************************************ ** ********* 主要的 : MOVBW,#7DHMOVSHW,#7DHMOVGW、#7DHMOVBWS、#0MOVSHWS、#0MOVGWS、#0MOVSP、#0A0HMOVTOH、#0A1h;**************** ***** ********** ********************************* ****** ****** ***MOVT0L,#0h;*** ************************************************** **************MOVT1H,#0E1h;******** ********************** ************************** * **********MOVT1L,#37h;******** ****************************** * ******************************MOVTMOD,#00H; 定时器0工作在模式1 MOVRTR, #00110110BMOVLTR, #00101101BMOVPCK, #00HMOVTODHT, #2MOVTODLT, #25HMOVTODH, #0MOVTOD L,#0;LCALLJSTIM;计算总值 TODH;TODLMOVpink2,#0MOVpink1,#0SETBEX0SETBIT0START:MOVDPTR,#7F00H;MOVA 状态字地址,#00111 111B; 假设端口 A、B、C 均为输出 MOVX@DPTR,ALCALLDISPLAY;显示 LCALLKEYSC;扫描键盘;MOVTESTK,#44H;******************** * ** ***************************测试******************* * ** **************************ACALLDISPKEYV;OK键盘;LCALLJSTIM;计算计算总TODH值; 总目标DL; 计算每个数字的值,以毫秒为单位,大约 600 个初始周期 LCALLJSEHW; 计算每个代码********************; ** ******JMPSTART;********************************键盘扫描仪******** * ******** ************KEYSC:MOVTESTK,#0movp1,#0FH;p10-3 产生 1 作为输入位 mova,p1AN LA,#0FHCJNEA,# 0FH,DELAYRETDELAY :ACALLDELAY1;延迟解锁 mova,p1ANLA,#0FHCJNEA,#0FH,HAVERETHAVE:MOVA,#0EFH;下一行扫描码:MOVB, AMOVP1, AMOVA, p1ANLA, #0FH; 检测柱 CJNEA、#0FH、YESMOVA、BRLACJNEA、#0FEH、NEXTYES:orla、#0f0h; 四位高位 1CPLAmo vr2,#00hMOVR2,A;保存列码 MOVA,B;获取行码,CPLAORLA,R2;列码+行码=键植MOVAD,#00HMOVTESTK,ARET;*** ******* *** * **************定义正确的键盘程序 ******************************DISPKEYV:MOVA,TESTKKEY0:CJNEA,#11H,KEY1acallWORD0KEY1:CJNEA,#12H ,KEY 2acallWORD1KEY2:CJNEA,#14H,KEY3acallWORD2KEY3:CJNEA,#18H,KEY4acallWORD3KEY4:CJNEA,#21H,KEY5acallWORD4KE Y5:CJNEA,#22H,KEY6acallWORD5KEY6:CJNEA,#24H,KEY7acallWORD6KEY7:CJNEA,#28H,KEY8acallWORD7KEY8:CJNEA,#41H ,KEY9acallWORD8KEY9:CJNEA,#42H,KEY10acallWORD9KEY10:CJNEA,#44H,KEY11acallWORD10KEY11:CJNEA,#48H,KEY12ac allWORD11KEY12:CJNEA,#81H,KEY13acallWORD12KEY13:CJNEA,#82H,KEY14acallWORD13KEY14:CJNEA,#84H,KEY15acallW ORD14KEY15:CJNEA,#88H,PASSAJMPWORD15PASS:RETWORD0:lCALLMOVEMOVA,#0MOVGWS,ALCALLJSTIM;计算总值 TODH;TODLMOVR0 ,TESTKTSTK0:LCALLKEYSCMOVA,R0CJNEA,TESTK,OUT0JMPTSTK0OUT0:MOVR0,#0RETWORD1:lCALLMOVEMOVA,#1MOVGWS,ALCAL LJSTIM; 计算总TODH; TODLMOVR0,TESTKTSTK1:LCALLKEYSCMOVA,R0CJNEA,TESTK,OUT1JMPTSTK1OUT1:MOVR0,#0RETWORD2:lCA。
LLMOVEMOVA,#2MOVGWS,ALCALLJSTIM;计算总值 TODH;TODLMOVR0,TESTKTSTK2:LCALLKEYSCMOVA,R0CJNEA,TESTK,OUT2JMPTSTK2 OUT2:MOVR0,#0ACALLJSEHW; 计算每一位的显示码 RETWORD3:lCALLMOVEMOVA,#3MOVGWS,ALCALLJSTIM 计算总值 TODLMOVR0,TESTKT; STK3:LCALLKEYSCMOVA,R0CJNEA,TESTK,OUT3JMPTSTK3OUT3:MOVR0,#0ACALLJSEHW; 计算每位的显示代码 RETWORD4:lCALLMOVEMOVA, #4MOVGWS,ALCALLJSTIM;计算总值 TODH;TODLMOVA,TESTKTSTK4:LCALLKEYSCCJNEA,TESTK,OUT4JMPTSTK4OUT4:ACALLJSEHW;计算每位的显示代码 RETWORD5:lCALLMOVEMOVA,#5MOVGWS,ALCALLJSTIM; 计算总值 TODLMOVA,TESTKTSTK5:LCALLKEYSCCJNEA,TESTK; OUT5JMPTSTK5OUT5:ACALLJSEHW;计算每位显示代码 RETWORD6:lCALLMOVEMOVA,#6MOVGWS,ALCALLJSTIM;计算总值 TODH;TODLMOVA,TES TKTSTK6:LCALLKEYSCCJNEA,TESTK,OUT6JMPTSTK6OUT6:ACALLJSEHW; 计算每一位的显示码RETWORD7:lCALLMOVEMOVA,#7MOVGWS,ALC ALLJSTIM; 计算总TODH值; TODLMOVA,TESTKTSTK7:LCALLKEYSCCJNEA,TESTK,OUT7JMPTSTK7OUT7:ACALLJSEHW 计算每一位的RETWO显示码;RD8:lCALLMOVEMOVA,#8MOVGWS,ALCALLJSTIM;计算总值 TODH;TODLMOVA,TESTKTSTK8:LCALLKEYSCCJNEA,TESTK,OUT8JMPTSTK8O UT8: ACALLJSEHW; 计算每一位RETWORD9的显示代码:lCALLMOVEMOVA、#9MOVGWS、ALCALLJSTIM; 计算总值TODLMOVA、TESTKTSTK9:LCALL; KEYSCCJNEA,TESTK,OUT9JMPTSTK9OUT9:ACALLJSEHW; 计算每一位的显示代码 RETWORD10:CLREACLRET0CLRTR0movth0,TOHmovtl0,T0LM OVPCK,#00000110BSETBEA;使能所有中断 SETBET0;使能定时器 SETBTR0 中断;开始定时器 0 计数 CLRTR1;禁止定时器 0 定时器 1 计数 SETBET1;使能定时器 1 中断 RETWORD11:CL REACLRET0CLRTR0movth0,TOHmovtl0,T0LMOVPCK,#00000101BSETBEA; 启用所有中断SETBET0; 定时器使能中断SETBTR0; 定时器0开始计数CLRTR1; 定时器1禁用SETBET1计数; 定时器 1 允许中断 RETWORD12:LCALLADDVMOVTODLT、TOHLCALLJSW; 以毫秒为单位计算每个位的值,大约 600 个初始周期 MOVA、TESTKTSTK12:LCA。
LLKEYSCCJNEA,TESTK,OUT12JMPTSTK12OUT12:RETWORD13:LCALLSUBVMOVTODLT,TOHLCALLJSW; 计算每毫秒的值,或大约 600 个初始周期 MOVA, TESTKTSTK11:LCALLKEYSCCJNEA,TESTK,OUT11JMPTSTK11OUT11:RETWORD14:CLRET0; 使能定时器0中断CLRET1; 使能CLREA定时器1中断; 破坏 CLRTR1; 禁用 T1 时序 CLRTR0; 禁用定时 T0 MOVPCK、#00HMOVBW、#7DHMOVSHW、#7DHMOVGW、#77HRETWORD15:JBEA、MID15MOVBWS、#0MOVS HWS,#0MOVGWS,#0JMPOUT15MID15:CLREAMOVA,TESTKTSTK15:LCALLKEYSCCJNEA,TESTK,OUT15JMPTSTK15MOVTODLT,TOHLCALLJSW 以毫秒为单位计算您的值,大约 600 个初始周期 OUT15:SETBEARET;************; ** *********计算每个 代码****************************************JSEHW:MOVSZ,BWSACALLjsMOVBW,xsmMOVSZ,SHWSACALLjsMOVSHW ,xsmMOVSZ,GWSACALLjsMOVGW,xsmRETjs:mova,szjs0 :cjnea,#0,js1movxsm,#7dhjs1:cjnea,#1,js2mov xsm,#14hjs2:cjnea,#2,js3movxsm,#6ehjs3:cjnea,#3,js4movxsm,#3ehjs4:cjn ea,#4,js5movxsm,#17hjs5:cjnea,#5,js6movxsm,#3bhjs6:cjnea,#6,js7movxsm ,#7bhjs7:cjnea,#7,js8movxsm,#00011100Bjs8:cjnea,#8,js9movxsm,#7fhjs9:cjnea,#9,js10movxsm,#3fhjs10:ret;**************** **************计算每毫秒的数值 大约 600 个周期 缩写************************************************JSW :;( R2R3R4/ R7 )=(R2)R3R4 仍为 R7MOVR2,#0MOVR3,TODHTMOVR4,TODLTMOVR7,#100LCALLNDIV31MOVBWS,R4MO VA,R7;MOVR4,AMOVR3,#0MOVR2,#0MOVR7,#10LCALLNDIV31MOVSHWS,R4MOVGWS,R7RET;******************************** *计算小数结果********************************JSTI M:MOVTODL,#0MOVTODH,#0MOVA,GWSMOVB,#1ACALLJSHLMOVA,SHWSMOVB,#10ACALLJSHLMOVA,BWSMOVB,#100ACALLJSHLRETJSHW:JBOV,JSGWCLROVRETJSGW:INCTODH;TES TDATERETJSHL:MULABMOVR1,BADDA,TODLMOVTODL,AMOVA,BADDCA,TODHMOVTODH,AACALLJSHWRET;********************************单字节除法 * ******************; ******************************(R2R3R4/R7)=(R2)R3R4 仍为 R7NDIV31:MOVA,R2MOVB,R7DIVABMOVR2,BMOVB ,# 10HNDV311:CLRCMOVA,R4RLCAMOVR4,AMOVA,R3RLCAMOVR3 ,AMOVA,R2RLCAMOVR2,AMOVF0,CCLRCSUBBA,R7JBF0,NDV312JCNDV313NDV312:MOVR2,AINCR4NDV313:DJNZB,NDV311CLROVJZNDV314SETBOVNDV314:XCHA,R2MOVR7,ARE T;************************ **二减 字节***(R3R4-R6R7)=(R3R4)******** ****NSUB:MOVA,R4CLRCSUBBA, R7MOVR4,AMOVA,R3SUBBA,R6MOVR3,ARETDELAY1:MOVR5,#10D1:MOVR6,#25 0DJNZR6,$DJNZR5,D1RETDELAY_BS:MOVR5,#5D2:MOVR6,#99D3:MOVR7,#99DJNZR7,$DJNZR6,D3DJNZR5,D2RET;************************ *** ********监控显示例程************ ******************************显示:MOVDPTR,#7F01H;MOVA,BW;MOVX@DPTR,AMOVDPTR,#7F03H; cMOVA地址,#00011000B; C口输出芯片选择灯MOVR0、PCK; pck = ********* 奥尔拉,R0;a=***11***MOVR0,#00011111B;a=00011***ANLA,R0MOVX@DPTR,AACALLD_40msMOVDPTR,#7F01H;MOVA,SHW;MOVX@DPTR,AMOVDPTR,#7F03H;caddressMOVA,#00101000BORL A,R0MOVR0,#00101111BANLA,R0MOVX@DPTR,AACALLD_40msMOVDPTR,#7F01H;MOVA,GW;MOVX@DPTR,AMOVDPTR,#7F03H;c 地址 MOVA,#00110000B;C 口输出片选指示 ORLA,R0MOVR0,# 00110111BANLA,R0MOVX@DPTR,AACLLD_40msmova,#0ffhMOVX@DPTR,ARETD_40ms:MOVR7,#10DELAYBB:MOVR6,#10NOPDELAYNN:DJNZR6,DELAYNN;2X198+2=398DJNZR7 ,DELAYBB;(398+2)X200+1=80msRET;********************************每一位从程序 ** *************************移动:MOVA、SHWSMOVBWS、AMOVA、GWSMOVSHWS、ARETEND