单片机计算器C语言程序

单片机计算器C语言程序,第1张

//

//

//<程序名>:多功能计算器

//<功能>:可以进行6位数以内正整数的加减乘除运算,以及计时器和自定义倒计时功

// 头文件及宏定义

//

//

#include "includesh"

#define TIME0H 0xFC

#define TIME0L 0x18 //定时器0溢出时间:5ms

#define TIME1H 0x44

#define TIME1L 0x80 //定时器1溢出时间:48ms

//

//

// 全局变量

//

//

//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<定时器0定时刷新LED计数>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

unsigned long ul_Number=0; //LCD实时显示数字。

unsigned char uca_ShowCustom[6]={0x88,0x83,0xC6,0xA1,0x86,0x84};

//存放自定义显示字符。

unsigned char uc_DisCount=1; //LCD时事刷新计数。

bit b_ShowMode=0; //显示模式标志位。

//0--数字模式,将要显示的数字赋给ul_Number便可时事显示数值,

// 默认为数字模式;

//1--自定义模式,该模式下自定义字符显示。

//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<定时器1计数刷新定时(计时模式)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

unsigned char uc_TimeCount=1; //定时器1定时计数。

bit b_ClockStart=0; //定时器1显示计数标志位。

extern bit b_ClockOppose; //TimeOpposec

extern unsigned long ul_ClockOppose;

//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<防抖动标志>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

bit b_KeyShock=0; //键盘防抖动标志位。

//当按键中断产生时,首先判断此位。

//0--执行键盘扫描及键码处理程序;1--不执行。

bit b_KillShock=0; //防抖标志清除位:0--不清除;1--清除。

unsigned char uc_KillCount=1; //抖动标志清除计数,使用定时器1。

//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<LCD闪烁显示报告>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

bit b_LCDClean=0; //通过设置b_LCDClean为1便可启动延时清空LCD显示。

unsigned char uc_CleanCount=1; //延迟时间可在T1中断中设定。

unsigned char uc_ReportSymbol;

bit b_ReportFlash=0;

unsigned char uca_FlashBlank[]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};

//

//

// 主函数

//

//

void main()

{

P2=0x0F; //初始化键盘接口。

TMOD=0x11; //定时器0:模式一;定时器0:模式一

//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<定时器0,用于LCD刷新>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

TH0=TIME0H;

TL0=TIME0L;

TR0=1; //开启定时器0

ET0=1; //开定时器0中断

//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<定时器1,用于1s计时 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

TH1=TIME1H;

TL1=TIME1L;

TR1=1; //开启定时器1

ET1=1; //开定时器1中断

//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<外部中断0,用于执行键盘扫描和键处理程序>>>>>>>>>>>>>>>>>>>>>>>>>>>

IT0=1; //外部中断0,中断方式:下降沿

EX0=1; //开启外部中断0

PT0=1; //把定时器0溢出中断设为高优先级。

EA=1; //开启总中断

while(1);

}

//

//

// 外部中断0,调用键盘扫描程序

//

//

void vINT0(void) interrupt 0

{

EX0=0; //在键扫描处理时,关闭外部中断0,防抖动。

if(b_KeyShock==0)

{

vKeyProcess(ucKeyScan()); //当判断有按键按下时,扫描键盘,并把扫描结果进行处理。

b_KeyShock=1; //设置防抖动标志。

}

else b_KeyShock=0; //如果有抖动则不执行键扫描,恢复防抖动标志。

//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<设置防抖动清除标志位 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

if(b_KeyShock==1)

b_KillShock=1; //如果防抖动标志位开启则开启防抖动标志清除位,

//300ms后清除防抖动标志。

//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<恢复键扫描处理前初始状态 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

P2=0x0F; //恢复P2口。

EX0=1; //恢复按键中断。

}

//

//

// 定时器1中断,用于计时功能和防抖动标志清除以及显示报告

//

//

void vTimer1(void) interrupt 3

{

//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<计时模式计数刷新>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

if(b_ClockStart==1) //当计时模式开启式,如计时处于运行状态则执行定时计数增加。

{

if(b_ClockOppose==0) //正常计时。

{

if(uc_TimeCount%21==0)

{

uc_TimeCount=1;

ul_Number++;

}

else uc_TimeCount++;

}

else

{ //倒计时模式。

if(uc_TimeCount%21==0)

{

uc_TimeCount=1;

if(ul_ClockOppose>0)

{

ul_ClockOppose--;

ul_Number=ul_ClockOppose;

}

else

{

b_ClockStart=0;

uc_ReportSymbol=7;

b_LCDClean=1;

}

}

else uc_TimeCount++;

}

}

//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<防抖动标志清除>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

if(b_KillShock==1)

{

if(uc_KillCount%5==0) //当防抖动标志位为1时,计时300ms后清除抖动标志位。

{

b_KeyShock=0;

b_KillShock=0;

uc_KillCount=1;

}

else uc_KillCount++;

}

//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<LCD显示报告>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

if(b_LCDClean==1)

{

if(uc_CleanCount==1)

{

EX0=0; //关闭键盘中断,此时按键无效。

vShowReport(uc_ReportSymbol);

b_ShowMode=1;

}

if(uc_CleanCount%40==0) //通过设置b_LCDClean为1便可启动延时清空LCD显示。

{

b_LCDClean=0; //关闭清零标志位,清零结束。

uc_CleanCount=1; //恢复清零计数为初始值1

b_ShowMode=0; //恢复显示模式为默认的数字模式。

b_ReportFlash=0;

EX0=1; //重新开启键盘中断。

}

else

{

//<<<<<<<<<<<<<<<<<<<<<<<<<实现闪烁报告功能>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

if(uc_CleanCount%7==0)

{

if(b_ReportFlash==0)

{

vCharCopy(uca_FlashBlank);

b_ReportFlash=1;

}

else

{

vShowReport(uc_ReportSymbol);

b_ReportFlash=0;

}

}

uc_CleanCount++;

}

}

TH1=TIME1H;

TL1=TIME1L;

}

//

//

// 定时器0,定时刷新LED

//

//

void vTimer0(void) interrupt 1

{

if(b_ShowMode==0)

//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<数字模式>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

{

vShowOneNum((pucLedNum(ul_Number)+uc_DisCount),6-uc_DisCount); //在LCD上显示1位数字。

if(uc_DisCount==5)

uc_DisCount=0; //定时器0在每次被触发时,改变LCD显示。

else uc_DisCount++; //从第一位到第六位循环显示。

}

else

//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<自定义模式>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

{

vShowCustom(uca_ShowCustom[uc_DisCount],uc_DisCount);

if(uc_DisCount==5)

uc_DisCount=0; //定时器0在每次被触发时,改变LCD显示。

else uc_DisCount++; //从第一位到第六位循环显示。

}

//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<恢复定时器0初始状态 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

TH0=TIME0H;

TL0=TIME0L;

},

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

//

//

//<程序名>:键盘扫描子程序

//<功能>:当有外部中断0时调用此函数,使用列扫描的方式获取键码,键码由2位数字组成。高位为行号

// 低位为列号。

//

//

//

//

// 头文件及宏定义

//

//

#include <at89x51h>

#define SCANPORT P2 //4×4键盘扫描端口,低4位是行线,高4位是列线。

//采用逐列扫描的方法,无按键时,低4位输出1,高4位输出0。

//当有按键时,高4位输出扫描电位,低4位输入扫描结果。

//

//

// 全局变量

//

//

unsigned char uca_LineScan[4]={0xEF,0xDF,0xBF,0x7F}; //列线扫描电压,分为第1,2,3,4根列线

//为低电平,其他为高电平。

//

//

// 函数实现

//

//

unsigned char ucKeyScan()

{

unsigned char ucTemp=0; //扫描状态暂存。

unsigned char ucRow=0,ucLine=0; //行号,列号。

for(ucLine=0;ucLine<4;ucLine++) //列扫描

{

SCANPORT=uca_LineScan[ucLine]; //输出扫描电位。

ucTemp=SCANPORT&0x0F; //输入扫描电位,并屏蔽高4位。

if(ucTemp!=0x0F)

{ //判断该列是否有按键按下。

switch(ucTemp)

{

case 0x0E: ucRow=10;break; //如果有,则判断行号。

case 0x0D: ucRow=20;break;

case 0x0B: ucRow=30;break;

case 0x07: ucRow=40;break;

default: ucRow=50;break;

}

break;

}

}

return ucRow+ucLine+1; //返回按键编码。格式为2位数,高位为行号,低位为列号。

}

/////////////////////////////////////////////////////////////////////

//

//

//<程序名>:计算器处理主程序,根据计算器的输入状态分派不同的函数对按键进行处理。

//<功能>:当b_WorkMode=0是,若有键按下则调用此函数对键码进行处理。

//

//

//

//

// 头文件及宏定义

//

//

#include "CalReadyh"

//

//

// 全局变量

//

//

extern unsigned long ul_Number; //LCE显示数据,LCD实时显示该数字。

//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<工作模式(默认为计算器模式)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

extern bit b_WorkMode; //0--计算器模式;

//1--计时模式。

//定义在KeyProcessc中。

unsigned char uc_ModeChange=0;

extern bit b_LCDClean;

extern unsigned char uc_ReportSymbol;

unsigned long ul_NumberOne=0; //第一个数

unsigned long ul_NumberTwo=0; //第二个数

unsigned char uc_Operator=0; //运算符

unsigned long ul_Result=0; //运算结果

unsigned char uc_NumPointer=1; //计算状态

//

//

// 计算器处理主函数

//

//

void vCalculator(unsigned char ucKeyCode)

{

if(ucKeyCode==41) //判断按键是不是'NO/C'。

{

if(uc_NumPointer==1) //如果是‘NO/C’键则判断手机否是状态一。

{

if(uc_ModeChange==2) //如果是状态一则看uc_ModeChange是不是2。

{

uc_ModeChange=0; //如果是2则计时器模式。

b_WorkMode=1;

uc_ReportSymbol=3; //闪烁显示:-CHAG-1。表明正在切换状态。

b_LCDClean=1;

}

else

{

uc_ModeChange++; //如果uc_ModeChange不是2则加一。

ul_NumberOne=0; //清除所有数据,将所有数据恢复到状态一。

ul_NumberTwo=0;

ul_Number=0;

uc_NumPointer=1;

}

}

else

{

ul_NumberOne=0; //清除所有数据,将所有数据恢复到状态一。

ul_NumberTwo=0;

ul_Number=0;

uc_NumPointer=1;

}

}

else

{ //如果不是“NO/C”键,首先将uc_ModeChange清零。

uc_ModeChange=0;

//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<根据不同状态分派不同的键处理函数>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

switch(uc_NumPointer)

{

case 1:

vCalReadyOne(ucKeyCode); //进入状态一。

break;

case 2:

vCalReadyTwo(ucKeyCode); //进入状态二。

break;

case 3:

vCalReadyThree(ucKeyCode); //进入状态三。

break;

default:break;

}

}

}

我以前做过4x4键盘控制电动机转速,用数码管显示电机转速的程序,程序如下:

AD EQU 30H

RTR EQU 31H

LTR EQU 32H

STR EQU 33H

BW EQU 34H

BWS EQU 35H

SHW EQU 36H

SHWS EQU 37H

GW EQU 38H

GWS EQU 39H

WSHR EQU 3AH;WSHR=BWS100+SHWS10+GWS

sz EQU 3BH;数字与代码对应程序的数字变量

xsm EQU 3CH;数字与代码对应程序的代码变量

TODH EQU 3DH;计算的10进位数的高位电机的要求转速高位

TODL EQU 3EH;计算的10进位数的低位电机的要求转速低位

TODHT EQU 3FH;测试后电机的实际转速高位

TODLT EQU 40H;测试后电机的实际转速低位

PCK EQU 41H;pc口当前的状态植

TOH EQU 42H;定时器高位数

T0L EQU 43H;定时器低位数

pink1 EQU 44H;电机转动1/4圈定时器1的奇数次数

pink2 EQU 45H

VTIMES EQU 46H;速度显示次数

T1H EQU 47H

T1L EQU 48H

TESTK DATA 49H ;高电平脉冲的个数

TTH0 EQU 1AH

TTL0 EQU 4BH

SUBNOW EQU 4CH

ORG 0000H

LJMP MAIN

ORG 03H

AJMP INTR0;中段0,用来计算电机转速

ORG 0BH

MOV A,PCK

ANL A,#00000111B

MOV PCK,A

MOV A,#00000110B

CJNE A,PCK,INTT0LF

LJMP INTT0L;

ORG 1BH;pwm停转子程序

AJMP INTT0H

ORG 0040H

;定时器中断子程序

;电机停止程序

INTT0H:

mov th0,TOH

mov tl0,T0L

SETB TR0;定时器0开始计数

CLR TR1;定时器1禁止计数

INC pink1

MOV DPTR,#7F02H; b地址

MOV A, #00000000B;电机停止运动

MOVX @DPTR,A

reti

;电动机正转子程序

INTT0L:

mov th1,T1H

mov tl1,T1L

SETB TR1;定时器1开始计数

CLR TR0;定时器0禁止计数

MOV DPTR,#7F02H; b地址

MOV A, #11001100B;C口输出片选号灯

MOVX @DPTR,A

reti

;电动机反转

INTT0LF:

mov th1,T1H

mov tl1,T1L

SETB TR1;定时器1开始计数

CLR TR0;定时器0禁止计数

MOV DPTR,#7F02H; b地址

MOV A, #10101100B;C口输出片选号灯

MOVX @DPTR,A

reti

;计算电机转速

;R2R3R4R5/ R6R7=R4R5余R2R3////(R2R3R4/R7)=(R2)R3R4 余数R7

INTR0:

MOV R2,#00H

MOV R3,#0EH

MOV R4,#0A6H

MOV R7,pink1

MOV pink1,#0

MOV A,#10

CLR CY

SUBB A,R7

JNB CY,OUTINT0

LCALL NDIV31

MOV TODHT, R3

MOV TODLT,R4

MOV R6,TODH

MOV R7,TODL

CLR CY

MOV A,R4

SUBB A,R7

MOV SUBNOW,A

JB CY,ADV

LCALL SUBV

JMP OUTINT0

ADV:

LCALL ADDV

OUTINT0:

LCALL JSW;计算各位的数值毫时大大约600个始周期 ;MOV TODLT,TOH

;LCALL JSW;计算各位的数值毫时大大约600个始周期

RETI;

;

;

COMP_M:

MOV A,#0FDH

SUBB A,TOH

JNB CY,OUT_PMM

MOV TOH,#0FDH

MOV T1H,#85

OUT_PMM:

RET

;加速子程序

ADDV:

CLR EA

CLR TR1

CLR TR0

MOV R1,SUBNOW

MOV R0,#10000000B

FRT:

MOV A,R0

RL A

MOV R0,A

MOV A,R1

ANL A,R0

JZ FRT

MOV A,TOH

ADD A,R0

JC VMAX

MOV TOH,A

MOV A,T1H

SUBB A,R0

MOV T1H,A

JMP TXT

VMAX:

MOV TOH,#0FDH

MOV T1H,#85

TXT:

SETB TR0

SETB TR1

SETB EA

RET

;减加速子程序

SUBV:

CLR EA

CLR TR1

CLR TR0

MOV R1,SUBNOW

MOV R0,#10000000B

FRT1:

MOV A,R0

RL A

MOV R0,A

MOV A,R1

ANL A,R0

JZ FRT1

MOV A,TOH

SUBB A,R0

JC VMAX1

MOV TOH,A

MOV A,T1H

ADD A,R0

MOV T1H,A

JMP TXT1

VMAX1:

MOV TOH,#85

MOV T1H,#0FDH

TXT1:

SETB TR0

SETB TR1

SETB EA

RET

;主程序

MAIN:

MOV BW,#7DH

MOV SHW,#7DH

MOV GW,#7DH

MOV BWS,#0

MOV SHWS,#0

MOV GWS,#0

MOV SP,#0A0H

MOV TOH,#0A1h;

MOV T0L,#0h;

MOV T1H,#0E1h;

MOV T1L,#37h;

MOV TMOD,#00H;定时器0在模式1下工作

MOV RTR,#00110110B

MOV LTR,#00101101B

MOV PCK,#00H

MOV TODHT,#2

MOV TODLT,#25H

MOV TODH,#0

MOV TODL,#0

;LCALL JSTIM;计算总值TODH;TODL

MOV pink2,#0

MOV pink1,#0

SETB EX0

SETB IT0

START:

MOV DPTR,#7F00H; 状态字地址

MOV A, #00111111B;设A,B,C口均为输出

MOVX @DPTR,A

LCALL DISPLAY;显示

LCALL KEYSC;扫描键盘

;MOV TESTK,#44H;TEST

ACALL DISPKEYV ;确定键盘

;LCALL JSTIM;计算总值TODH;TODL

;LCALL JSW;计算各位的数值毫时大大约600个始周期

LCALL JSEHW;计算各个代码

JMP START

;键盘扫描程序

KEYSC:

MOV TESTK,#0

mov p1,#0FH ;p10-3输出1,作为输入位

mov a ,p1

ANL A,#0FH

CJNE A,#0FH,DELAY

RET

DELAY: ACALL DELAY1 ; 延时去键抖

mov a ,p1

ANL A,#0FH

CJNE A,#0FH,HAVE

RET

HAVE:

MOV A,#0EFH ;行扫描码

NEXT:

MOV B,A

MOV P1,A

MOV A,p1

ANL A,#0FH ;检测列

CJNE A,#0FH,YES

MOV A,B

RL A

CJNE A,#0FEH,NEXT

YES: orl a,#0f0h ;高四位置1

CPL A

mov r2,#00h

MOV R2,A ;存列码

MOV A,B ;取行码,

CPL A

ORL A,R2 ;列码+行码=键植

MOV AD,#00H

MOV TESTK,A

RET

;确定键盘程序

DISPKEYV:MOV A,TESTK

KEY0:CJNE A,#11H,KEY1

acall WORD0

KEY1:CJNE A,#12H,KEY2

acall WORD1

KEY2:CJNE A,#14H,KEY3

acall WORD2

KEY3:CJNE A,#18H,KEY4

acall WORD3

KEY4:CJNE A,#21H,KEY5

acall WORD4

KEY5:CJNE A,#22H,KEY6

acall WORD5

KEY6:CJNE A,#24H,KEY7

acall WORD6

KEY7:CJNE A,#28H,KEY8

acall WORD7

KEY8:CJNE A,#41H,KEY9

acall WORD8

KEY9:CJNE A,#42H,KEY10

acall WORD9

KEY10:CJNE A,#44H,KEY11

acall WORD10

KEY11:CJNE A,#48H,KEY12

acall WORD11

KEY12:CJNE A,#81H,KEY13

acall WORD12

KEY13:CJNE A,#82H,KEY14

acall WORD13

KEY14:CJNE A,#84H,KEY15

acall WORD14

KEY15:

CJNE A,#88H,PASS

AJMP WORD15

PASS:RET

WORD0:

lCALL MOVE

MOV A,#0

MOV GWS,A

LCALL JSTIM;计算总值TODH;TODL

MOV R0,TESTK

TSTK0:

LCALL KEYSC

MOV A,R0

CJNE A,TESTK,OUT0

JMP TSTK0

OUT0:

MOV R0,#0

RET

WORD1:

lCALL MOVE

MOV A,#1

MOV GWS,A

LCALL JSTIM;计算总值TODH;TODL

MOV R0,TESTK

TSTK1:

LCALL KEYSC

MOV A,R0

CJNE A,TESTK,OUT1

JMP TSTK1

OUT1:

MOV R0,#0

RET

WORD2:

lCALL MOVE

MOV A,#2

MOV GWS,A

LCALL JSTIM;计算总值TODH;TODL

MOV R0,TESTK

TSTK2:

LCALL KEYSC

MOV A,R0

CJNE A,TESTK,OUT2

JMP TSTK2

OUT2:

MOV R0,#0

ACALL JSEHW;计算各个位的显示代码

RET

WORD3:

lCALL MOVE

MOV A,#3

MOV GWS,A

LCALL JSTIM;计算总值TODH;TODL

MOV R0,TESTK

TSTK3:

LCALL KEYSC

MOV A,R0

CJNE A,TESTK,OUT3

JMP TSTK3

OUT3:

MOV R0,#0

ACALL JSEHW;计算各个位的显示代码

RET

WORD4:

lCALL MOVE

MOV A,#4

MOV GWS,A

LCALL JSTIM;计算总值TODH;TODL

MOV A,TESTK

TSTK4:

LCALL KEYSC

CJNE A,TESTK,OUT4

JMP TSTK4

OUT4:

ACALL JSEHW;计算各个位的显示代码

RET

WORD5:

lCALL MOVE

MOV A,#5

MOV GWS,A

LCALL JSTIM;计算总值TODH;TODL

MOV A,TESTK

TSTK5:

LCALL KEYSC

CJNE A,TESTK,OUT5

JMP TSTK5

OUT5:

ACALL JSEHW;计算各个位的显示代码

RET

WORD6:

lCALL MOVE

MOV A,#6

MOV GWS,A

LCALL JSTIM;计算总值TODH;TODL

MOV A,TESTK

TSTK6:

LCALL KEYSC

CJNE A,TESTK,OUT6

JMP TSTK6

OUT6:

ACALL JSEHW;计算各个位的显示代码

RET

WORD7:

lCALL MOVE

MOV A,#7

MOV GWS,A

LCALL JSTIM;计算总值TODH;TODL

MOV A,TESTK

TSTK7:

LCALL KEYSC

CJNE A,TESTK,OUT7

JMP TSTK7

OUT7:

ACALL JSEHW;计算各个位的显示代码

RET

WORD8:

lCALL MOVE

MOV A,#8

MOV GWS,A

LCALL JSTIM;计算总值TODH;TODL

MOV A,TESTK

TSTK8:

LCALL KEYSC

CJNE A,TESTK,OUT8

JMP TSTK8

OUT8:

ACALL JSEHW;计算各个位的显示代码

RET

WORD9:

lCALL MOVE

MOV A,#9

MOV GWS,A

LCALL JSTIM;计算总值TODH;TODL

MOV A,TESTK

TSTK9:

LCALL KEYSC

CJNE A,TESTK,OUT9

JMP TSTK9

OUT9:

ACALL JSEHW;计算各个位的显示代码

RET

WORD10:

CLR EA

CLR ET0

CLR TR0

mov th0,TOH

mov tl0,T0L

MOV PCK,#00000110B

SETB EA;打开所有中断

SETB ET0;定时器允许中断

SETB TR0;定时器0开始计数

CLR TR1;定时器1禁止计数

SETB ET1;定时器1允许中断

RET

WORD11:

CLR EA

CLR ET0

CLR TR0

mov th0,TOH

mov tl0,T0L

MOV PCK,#00000101B

SETB EA;打开所有中断

SETB ET0;定时器允许中断

SETB TR0;定时器0开始计数

CLR TR1;定时器1禁止计数

SETB ET1;定时器1允许中断

RET

WORD12:

LCALL ADDV

MOV TODLT,TOH

LCALL JSW;计算各位的数值毫时大大约600个始周期

MOV A,TESTK

TSTK12:

LCALL KEYSC

CJNE A,TESTK,OUT12

JMP TSTK12

OUT12:

RET

WORD13:

LCALL SUBV

MOV TODLT,TOH

LCALL JSW;计算各位的数值毫时大大约600个始周期

MOV A,TESTK

TSTK11:

LCALL KEYSC

CJNE A,TESTK,OUT11

JMP TSTK11

OUT11:

RET

WORD14:

CLR ET0;使能定时器0中断

CLR ET1;使能定时器1中断

CLR EA;使能总中断

CLR TR1;关闭T1计时

CLR TR0;关闭T0计时

MOV PCK,#00H

MOV BW,#7DH

MOV SHW,#7DH

MOV GW,#77H

RET

WORD15:JB EA,MID15

MOV BWS,#0

MOV SHWS,#0

MOV GWS,#0

JMP OUT15

MID15:

CLR EA

MOV A,TESTK

TSTK15:

LCALL KEYSC

CJNE A,TESTK,OUT15

JMP TSTK15

MOV TODLT,TOH

LCALL JSW;计算各位的数值毫时大大约600个始周期

OUT15:

SETB EA

RET

;计算各个代码

JSEHW:

MOV SZ,BWS

ACALL js

MOV BW,xsm

MOV SZ,SHWS

ACALL js

MOV SHW,xsm

MOV SZ,GWS

ACALL js

MOV GW,xsm

RET

js:

mov a,sz

js0:cjne a,#0,js1

mov xsm,#7dh

js1:cjne a,#1,js2

mov xsm,#14h

js2:cjne a,#2,js3

mov xsm,#6eh

js3:cjne a,#3,js4

mov xsm,#3eh

js4:cjne a,#4,js5

mov xsm,#17h

js5:cjne a,#5,js6

mov xsm,#3bh

js6:cjne a,#6,js7

mov xsm,#7bh

js7:cjne a,#7,js8

mov xsm,#00011100B

js8:cjne a,#8,js9

mov xsm,#7fh

js9:cjne a,#9,js10

mov xsm,#3fh

js10:ret

;计算各位的数值毫时大大约600个始周期

JSW:;(R2R3R4/R7)=(R2)R3R4 余数R7

MOV R2,#0

MOV R3,TODHT

MOV R4, TODLT

MOV R7,#100

LCALL NDIV31

MOV BWS,R4

MOV A,R7;

MOV R4,A

MOV R3,#0

MOV R2,#0

MOV R7,#10

LCALL NDIV31

MOV SHWS,R4

MOV GWS,R7

RET

;计算十进制结果

JSTIM:

MOV TODL,#0

MOV TODH,#0

MOV A,GWS

MOV B,#1

ACALL JSHL

MOV A,SHWS

MOV B,#10

ACALL JSHL

MOV A,BWS

MOV B,#100

ACALL JSHL

RET

JSHW:

JB OV,JSGW

CLR OV

RET

JSGW:

INC TODH;TEST DATE

RET

JSHL:

MUL AB

MOV R1,B

ADD A,TODL

MOV TODL,A

MOV A,B

ADDC A,TODH

MOV TODH,A

ACALL JSHW

RET

;单字节的除法

;(R2R3R4/R7)=(R2)R3R4 余数R7

NDIV31 :MOV A,R2

MOV B,R7

DIV AB

MOV R2,B

MOV B,#10H

NDV311 :CLR C

MOV A,R4

RLC A

MOV R4,A

MOV A,R3

RLC A

MOV R3,A

MOV A,R2

RLC A

MOV R2,A

MOV F0,C

CLR C

SUBB A,R7

JB F0,NDV312

JC NDV313

NDV312 :MOV R2,A

INC R4

NDV313 :DJNZ B,NDV311

CLR OV

JZ NDV314

SETB OV

NDV314 :XCH A,R2

MOV R7,A

RET

;双字节减法(R3R4-R6R7)=(R3R4)

NSUB :MOV A,R4

CLR C

SUBB A,R7

MOV R4,A

MOV A,R3

SUBB A,R6

MOV R3,A

RET

DELAY1:

MOV R5,#10

D1: MOV R6,#250

DJNZ R6, $

DJNZ R5,D1

RET

DELAY_BS:

MOV R5,#5

D2: MOV R6,#99

D3: MOV R7,#99

DJNZ R7, $

DJNZ R6,D3

DJNZ R5,D2

RET

;显示器显示子程序

DISPLAY:

MOV DPTR,#7F01H;

MOV A, BW;

MOVX @DPTR,A

MOV DPTR,#7F03H; c地址

MOV A, #00011000B;C口输出片选号灯

MOV R0,PCK;pck=

ORL A,R0;a=11

MOV R0,#00011111B;a=00011

ANL A,R0

MOVX @DPTR,A

ACALL D_40ms

MOV DPTR,#7F01H;

MOV A, SHW;

MOVX @DPTR,A

MOV DPTR,#7F03H; c地址

MOV A,#00101000B

ORL A,R0

MOV R0,#00101111B

ANL A,R0

MOVX @DPTR,A

ACALL D_40ms

MOV DPTR,#7F01H;

MOV A, GW;

MOVX @DPTR,A

MOV DPTR,#7F03H; c地址

MOV A, #00110000B;C口输出片选号灯

ORL A,R0

MOV R0,#00110111B

ANL A,R0

MOVX @DPTR,A

ACALL D_40ms

mov a,#0ffh

MOVX @DPTR,A

RET

D_40ms:

MOV R7,#10

DELAYBB:

MOV R6,#10

NOP

DELAYNN:

DJNZ R6,DELAYNN; 2X198+2=398

DJNZ R7,DELAYBB; (398+2)X200+1=80ms

RET

;各个位移位自程序

MOVE:

MOV A,SHWS

MOV BWS,A

MOV A,GWS

MOV SHWS,A

RET

END

C语言的语句可以这样写

#include<stdioh>

void main()

{

float fxx;

unsigned char str[10];

fxx = 125;

sprintf(str,"%82f\n",fxx); //将125转换成82(2位小数)格式以ASCII方式存储到str字符串中

}

由于1620液晶模块支持ASCII码,所以只要将str中的内容送到1602就行了。至于1602的 *** 作我就不写了(其实我也没用过,但知道怎么用,应该不难)

以上就是关于单片机计算器C语言程序全部的内容,包括:单片机计算器C语言程序、51单片机设计的简易的计算器、我想用51单片机,矩阵键盘,lcd1602写个简易计算器程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9279483.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-26
下一篇 2023-04-26

发表评论

登录后才能评论

评论列表(0条)

保存