求大神帮写一液晶+STC89c52单片机+4*4矩阵键盘实现简易计算器的C语言程序,实现加减乘除以及扩展功能

求大神帮写一液晶+STC89c52单片机+4*4矩阵键盘实现简易计算器的C语言程序,实现加减乘除以及扩展功能,第1张

没有液晶的,以前做了一个有一个数码管的,发给你供参考。

#include<reg51h>

#define uchar unsigned char;

uchar LED1,LED2,LED3,LED4;

uchar keyval,calflag,s_dat,d_dat;

uchar distab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff};

unsigned int number,r_dat;

void delay(unsigned int a)

{

unsigned int i,j;

for(i=0;i<a;i++)

for(j=0;j<1000;j++);

}

void dealdat()

{

switch(calflag)

{

case 0:

r_dat=s_dat+d_dat;

break;

case 1:

r_dat=s_dat-d_dat;

break;

case 2:

r_dat=s_datd_dat;

break;

case 3:

r_dat=s_dat/d_dat;

break;

default:break;

}

LED1=(r_dat/1000)%10;

LED2=(r_dat/100)%10;

LED3=(r_dat/10)%10;

LED4=r_dat%10;

}

uchar kbscan(void)

{

unsigned char sccode,recode;

P3=0x0f;  //发0扫描,列线输入

if ((P3 & 0x0f) != 0x0f)  //有键按下

{

delay(20);   //延时去抖动

if ((P3&0x0f)!= 0x0f)

{

sccode = 0xef;    //逐行扫描初值

while((sccode&0x01)!=0)

{

   P3=sccode;

if((P3&0x0f)!=0x0f)

{

   recode=(P3&0x0f)|0xf0;

return((~sccode)+(~recode));

}

       else

sccode=(sccode<<1)|0x01;

}

}

}

return 0;  //无键按下,返回0

}

void getkey(void)

{

unsigned char key;

key=kbscan();

if(key==0){keyval=0xff;return;}

switch(key)

{

case 0x11:keyval=7;break;

case 0x12:keyval=4;break;

case 0x14:keyval=1;break;

case 0x18:keyval=10;break;

case 0x21:keyval=8;break;

case 0x22:keyval=5;break;

case 0x24:keyval=2;break;

case 0x28:keyval=0;break;

case 0x41:keyval=9;break;

case 0x42:keyval=6;break;

case 0x44:keyval=3;break;

case 0x48:keyval=11;break;

case 0x81:keyval=12;break;

case 0x82:keyval=13;break;

case 0x84:keyval=14;break;

case 0x88:keyval=15;break;

default:keyval=0xff;break;

}

}

void t0isr() interrupt 1

{

TH0=0xf4;

TL0=0x48;

switch(number)

{

case 0:P2=0x04;P0=distab[LED1];break;

case 1:P2=0x08;P0=distab[LED2];break;

case 2:P2=0x01;P0=distab[LED3];break;

case 3:P2=0x02;P0=distab[LED4];break;

default:break;

}

number++;

if(number>3)number=0;

}

main()

{

TMOD = 0x01;

number = 0;

TH0=0xf4;

TL0=0x48;

TR0=1;

ET0=1;

EA=1;

LED1=0;

LED2=0;

LED3=0;

LED4=0;

while(1)

{

getkey();

switch(keyval)

{

case 0:

case 1:

case 2:

case 3:

case 4:

case 5:

case 6:

case 7:

case 8:

case 9:

LED3=LED4;

LED4=keyval;

LED1=0;

LED2=0;

break;

case 10:break; //"ON"

case 11: //"="

d_dat=LED310+LED4;

dealdat();

break;

case 12: //"/"

calflag=3;

s_dat=LED310+LED4;

LED3=0;

LED4=0;

break;

case 13: //""

calflag=2;

s_dat=LED310+LED4;

LED3=0;

LED4=0;

break;

case 14: //"-"

calflag=1;

s_dat=LED310+LED4;

LED3=0;

LED4=0;

break;

case 15: //"+"

calflag=0;

s_dat=LED310+LED4;

LED3=0;

LED4=0;

break;

default:break;

}

}

}

#include <reg51h>

#define uchar unsigned char

long First,End; //定义全局变量

void delay(int n) //延时程序//

{int i,j;

for(i=0;i<n;i++)

{for(j=0;j<50;j++)

;}

}

long add(long x,long y) //加法程序//

{long z;

z=x+y;

return(z);

}

long sub(long x,long y) //减法程序//

{long z;

if(x>=y)

z=x-y;

else

{z=y-x;

z=z+10e6;} //最高位用1表示负数//

return(z);

}

long mul(long x,long y) //乘法程序//

{long z;

z=xy;

return(z);

}

long div(long x,long y) //除法程序//

{long z;

z=x/y;

return(z);

}

uchar kbscan(void) //键盘扫描程序//

{

uchar sccode;

P1=0xf0;

if((P1&0xf0)!=0xf0) //发全0行扫描码,列线输入

{ delay(222); //延时去抖

if((P1&0xf0)!=0xf0)

{sccode=0xfe; //逐行扫描初值

while((sccode&0x10)!=0)

{P1=sccode; //输出行扫描码

if((P1&0xf0)!=0xf0)

{

return(P1);} //如果检测到有键按下,返回键值

else

sccode=(sccode<<1)|0x01; //行扫描码左移一位

}

}

}

return(0); //无键按下,返回值为0

}

void display(void) //显示程序//

{int i;

uchar code rel[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe}; //数码管选通

uchar code led[]={0x7e,0x30,0x6d,0x79,0x33,0x5b,0x5f,0x70,0x7f,0x7b}; //定义0-9

uchar data num[8];

num[0]=First/10000000; //千万位

num[1]=First/1000000%10; //百万位

num[2]=First/100000%10; //十万位

num[3]=First/10000%10; //万位

num[4]=First/1000%10; //千位

num[5]=First/100%10; //百位

num[6]=First/10%10; //十位

num[7]=First%10; //个位

for(i=7;i>=0;i--)

{P3=rel[i]; //位选输出

P2=led[num[i]]; //数据输出

delay(2); //此延时必不可少?

}

}

void main(void) //主程序//

{ int k,n;

uchar f,g,key,gn1;

n=0;

f=0;

P0=0; //初始时指示灯灭

while(1) //不断查询是否有按键动作

{ key=kbscan(); //获取返回键值

if(key!=0)

{

switch(key) //译码,将对应按键返回值转换为相应数值

{

case 0xee: k=0;break;//0

case 0xde: k=1;break;//1

case 0xbe: k=2;break;//2

case 0x7e: k=3;break;//3

case 0xed: k=4;break;//4

case 0xdd: k=5;break;//5

case 0xbd: k=6;break;//6

case 0x7d: k=7;break;//7

case 0xeb: k=8;break;//8

case 0xdb: k=9;break;//9

case 0xbb: k=10;First=0;End=0;f=0;break;//清除

case 0x7b: k=11;break;//等于

case 0xe7: k=12;f=1;break;//加

case 0xd7: k=13;f=2;break;//减

case 0xb7: k=14;f=3;break;//乘

case 0x77: k=15;f=4;break;//除

}

P0=1;

delay(280); //有按键时,指示灯的显示时间

P0=0; //按键指示灭

if(k<10) //为数字键时(0-9)

{

if(f!=0) //为数字键时,如果已经有功能键按下

{

n++; //记录数字键所按次数

gn1=0; //清除标志,再次为功能键时进行运算

g=f; //保存运算标志

if(n==1) //输入为各位数时,直接赋值

First=k;

else if(n>1) //输入为多位数时,将它转化为10进制的多位数

First=First10+k;

}

else //如果没有功能键按下

{

n++;

gn1=1; //定义标志,当下一次为功能键时,停止数据输入

if(n==1)

First=k;

else if(n>1)

First=First10+k;

End=First; //将第一个数保存

}

}

else if(k>11) //为功能键时(+-/)

{

if(gn1==1) //前一次数字键之后为功能键时

{

n=0; //清除计数标志

}

else //如果再次输入功能键,则进行运算

{n=0; //清除计数标志

switch(g)

{case 1: First=add(End,First);break;

case 2: First=sub(End,First);break;

case 3: First=mul(End,First);break;

case 4: First=div(End,First);break;}

}

End=First; //保存本次结果

}

else if(k==11) //为等于号时(=)

{n=0;

gn1=1; //接着输入为功能键时可以继续运算

switch(g)

{case 1: First=add(End,First);break;

case 2: First=sub(End,First);break;

case 3: First=mul(End,First);break;

case 4: First=div(End,First);break;

}

End=First; //保存最终运算结果

f=0; //清除运算标志

}

}

display(); //调用显示程序

}

}

以下是我原来写过的一个关于矩阵的类,里面实现了求方阵的行列式函数:int det(matrix);

//matrixh

//

# ifndef matrix_h

# define matrix_h

class matrix

{

private:

int m;

int n;

double arr[8][8];

public:

matrix();

matrix(double);

void set();// 对矩阵的赋值;

void show();//在屏幕上显示矩阵;

friend int homotype(matrix,matrix);//是否同型;

friend int multipliable(matrix,matrix);

//判断矩阵是否可相乘

friend matrix operator +(matrix,matrix);

//矩阵相加,对加号重载;

friend matrix operator -(matrix,matrix);

//矩阵机减,对减号重载;

friend matrix add(matrix,matrix);

//矩阵相加;

friend matrix minus(matrix,matrix);

//矩阵相减

friend matrix multiply(matrix,matrix);

//矩阵相乘

friend matrix operator (matrix,matrix);

//矩阵相乘,对乘号重载;

friend double det(matrix);

//求方阵的行列式;

int issquare()

{

return m==n;

}

//判断是否为方阵;

matrix left(int x,int y);

//求元素arr[x][y](x,y从0开始)的余子式;

};

# endif

//

//matrixcpp

//下面是对类中成员及友元函数的实现

//

# include <iostreamh>

# include "matrixh"

matrix::matrix()

{

m = 8;

n = 8;

for(int i=0;i<m;i++)

{

for(int j=0;j<n;j++)

arr[i][j] = 0;

}

}

matrix::matrix(double x)

{

m = 1;

n = 1;

arr[0][0] = x;

}

void matrix::set()

{

cout<<"Set the type of the matrix()"<<endl;

cin>>m>>n;

cout<<"Now input the elements of the matrix:"<<endl;

for(int i=0;i<m;i++)

{

for(int j=0;j<n;j++)

cin>>arr[i][j];

}

}

void matrix::show()

{

cout<<"This is the matrix:"<<endl;

for(int i=0;i<m;i++)

{

for(int j=0;j<n;j++)

{

cout<<arr[i][j]<<ends;

}

cout<<endl;

}

}

int homotype(matrix x,matrix y)

{

if(xm==ym&&xn==yn)

return 1;

else

return 0;

}

int multipliable(matrix x,matrix y)

{

if(xn==ym)

return 1;

else

return 0;

}

matrix add(matrix x,matrix y)

{

matrix z;

if(homotype(x,y))

{

zm = xm;

zn = xn;

for(int i=0;i<zm;i++)

for(int j=0;j<zn;j++)

zarr[i][j] = xarr[i][j] + yarr[i][j];

return z;

}

else

{

cout<<"cannot be added!"<<endl;

return z;

}

}

matrix operator +(matrix x,matrix y)

{

return add(x,y);

}

matrix minus(matrix x,matrix y)

{

matrix z;

if(homotype(x,y))

{

zm = xm;

zn = xn;

for(int i=0;i<zm;i++)

for(int j=0;j<zn;j++)

zarr[i][j] = xarr[i][j] - yarr[i][j];

return z;

}

else

{

cout<<"cannot be added!"<<endl;

return z;

}

}

matrix operator -(matrix x,matrix y)

{

return minus(x,y);

}

matrix multiply(matrix x,matrix y)

{

matrix z;

if(xn!=ym)

{

cout<<"The two matrixes cannot be multiplied"<<endl;

return z;

}

for(int i=0;i<xm;i++)

{

for(int j=0;j<yn;j++)

{

for(int k=0;k<xn;k++)

zarr[i][j] += xarr[i][k]yarr[k][j];

}

}

zm = xm;

zn = yn;

return z;

}

matrix operator (matrix x,matrix y)

{

matrix z;

z = multiply(x,y);

return z;

}

matrix matrix::left(int x,int y)

{

matrix leftmatrix;

if((x>=m)||(y>=n))

{

cout<<"errer"<<endl;

return leftmatrix;

}

/ if(!issquare())

{

cout<<"不是方阵!"<<endl;

return this;

}///

leftmatrixm = m - 1;

leftmatrixn = n - 1;

int testx = 0;

int testy = 0;

for(int i=0;i<leftmatrixm;i++)

{

testy = 0;

for(int j=0;j<leftmatrixn;j++)

{

if(i==x)

testx = 1;

if(j==y)

testy = 1;

if((!testx)&&(!testy))

leftmatrixarr[i][j] = this->arr[i][j];

else if(testx&&(!testy))

leftmatrixarr[i][j] = this->arr[i+1][j];

else if((!testx)&&testy)

leftmatrixarr[i][j] = this->arr[i][j+1];

else

leftmatrixarr[i][j] = this->arr[i+1][j+1];

}

}

return leftmatrix;

}

double det(matrix x)//递归算法

{

if(!xissquare())

{

cout<<"不是方阵!"<<endl;

return 999;

}

if(xm==0)

return 0;

else if(xm==1)

return xarr[0][0];

else if(xm==2)

return (xarr[0][0]xarr[1][1] - xarr[0][1]xarr[1][0]);

else

{

double num = 0;

int a = 1;

for(int i=0;i<xm;i++)

{

num = num + axarr[0][i]det(xleft(0,i));

//按第0行展开

a = -a;

}

return num;

}

}

//

KEYVAL EQU 30H

KEYTM EQU 31H

KEYSCAN EQU 32H

DAT  EQU 33H

SCANLED EQU 37H

S_DAT EQU 38H

D_DAT EQU 39H

R_DATL EQU 3AH

R_DATH EQU 3BH

CALFLAG EQU 3CH

FLAG BIT 00H

ORG 0000H

LJMP MAIN

ORG 000BH

LJMP T0ISR

ORG 0030H

MAIN:

MOV SP,#5FH

MOV TMOD,#01H

MOV TH0,#0D8H

MOV TL0,#0F0H

MOV KEYVAL,#0

MOV P2,#00H

MOV SCANLED,#0

MOV 33H,#0H

MOV 34H,#0H

MOV 35H,#0H

MOV 36H,#0H

MOV S_DAT,#0

MOV D_DAT,#0

CLR FLAG

SETB EA

SETB ET0

SETB TR0

LOOP:

LCALL KEYSEL

MOV A,KEYVAL

CJNE A,#0FFH,LOOP1

SJMP LOOP

LOOP1:

CJNE A,#11,LOOP2 ;“=”

MOV A,33H

MOV B,#10

MUL AB

ADD A,34H

MOV D_DAT,A

LCALL DEALDAT

LCALL HB2

MOV A,R5

ANL A,#0FH

MOV 34H,A

MOV A,R5

SWAP A

ANL A,#0FH

MOV 33H,A

MOV A,R4

ANL A,#0FH

MOV 36H,A

MOV A,R4

SWAP A

ANL A,#0FH

MOV 35H,A

SJMP LOOP

LOOP2:

CJNE A,#15,LOOP3 ;“+”

LCALL GETDAT

SJMP LOOP

LOOP3:

CJNE A,#14,LOOP4 ;“-”

MOV CALFLAG,#1

LCALL GETDAT

SJMP LOOP

LOOP4:

CJNE A,#13,LOOP5 ;“”

MOV CALFLAG,#2

LCALL GETDAT

SJMP LOOP

LOOP5:

CJNE A,#12,LOOP6 ;"/"

MOV CALFLAG,#3

LCALL GETDAT

SJMP LOOP

LOOP6:

CJNE A,#10,LOOP7  ;数字键

LOOP7:

JC LOOP8

LJMP LOOP

LOOP8:

MOV 33H,34H

MOV 34H,KEYVAL

LJMP LOOP

;------------------

HB2:

MOV R6,R_DATH

MOV R7,R_DATL

CLR  A   ;BCD码初始化

MOV  R3,A

MOV  R4,A

MOV  R5,A

MOV  R2,#10H   ;转换双字节十六进制整数

HB3:

MOV  A,R7   ;从高端移出待转换数的一位到 CY 中

RLC  A

MOV  R7,A

MOV  A,R6

RLC  A

MOV  R6,A

MOV  A,R5   ;BCD码带进位自身相加,相当于乘2

ADDC  A,R5

DA  A   ;十进制调整

MOV  R5,A

MOV  A,R4

ADDC  A,R4

DA  A

MOV  R4,A

MOV  A,R3

ADDC  A,R3

MOV  R3,A   ;双字节十六进制数的万位数不超过6,不用调整

DJNZ  R2,HB3   ;处理完16bit

RET

;------------------

GETDAT:

MOV A,33H

MOV B,#10

MUL AB

ADD A,34H

MOV S_DAT,A

MOV 33H,#0

MOV 34H,#0

MOV 35H,#0

MOV 36H,#0

RET

;------------------

DEALDAT:

MOV A,CALFLAG

JNZ DEAL01

DEAL00:    ;+

MOV A,S_DAT

ADD A,D_DAT

MOV R_DATL,A

CLR A

ADDC A,#0

MOV R_DATH,A

RET

DEAL01:    ;=

DEC A

JNZ DEAL02

CLR C

MOV A,S_DAT

SUBB A,D_DAT

MOV R_DATL,A

SUBB A,#0

MOV R_DATH,A

RET

DEAL02:    ;

DEC A

JNZ DEAL03

MOV A,S_DAT

MOV B,D_DAT

MUL AB

MOV R_DATL,A

MOV R_DATH,B

RET

DEAL03:    ;/

MOV A,S_DAT

MOV B,D_DAT

DIV AB

MOV R_DATL,A

MOV R_DATH,#0

RET

;------------------

KEYSEL:

MOV KEYVAL,#0

MOV KEYSCAN,#0EFH

LCALL GETKEY

MOV A,KEYTM

JZ KEYS1

MOV KEYVAL,A

SJMP KEYRTN

KEYS1:

MOV KEYSCAN,#0DFH

LCALL GETKEY

MOV A,KEYTM

JZ KEYS2

CLR C

ADD A,#4

MOV KEYVAL,A

SJMP KEYRTN

KEYS2:

MOV KEYSCAN,#0BFH

LCALL GETKEY

MOV A,KEYTM

JZ KEYS3

CLR C

ADD A,#8

MOV KEYVAL,A

SJMP KEYRTN

KEYS3:

MOV KEYSCAN,#7FH

LCALL GETKEY

MOV A,KEYTM

JZ KEYRTN

CLR C

ADD A,#12

MOV KEYVAL,A

KEYRTN:

LCALL CHGKEY

RET

;--------------------

GETKEY:

MOV KEYTM,#0

MOV A,KEYSCAN

MOV P3,A

NOP

MOV A,P3

ANL A,#0FH

XRL A,#0FH

JZ NOKEY

MOV R2,#10

LCALL DELAY

MOV A,P3

ANL A,#0FH

XRL A,#0FH

JZ NOKEY

MOV A,P3

ANL A,#0FH

MOV R7,A

SF:

MOV A,P3

ANL A,#0FH

XRL A,#0FH

JNZ SF

MOV A,R7

CJNE A,#0EH,NK1

MOV KEYTM,#1

SJMP NOKEY

NK1:

CJNE A,#0DH,NK2

MOV KEYTM,#2

SJMP NOKEY

NK2:

CJNE A,#0BH,NK3

MOV KEYTM,#3

SJMP NOKEY

NK3:

CJNE A,#07H,NOKEY

MOV KEYTM,#4

NOKEY: RET

;--------------------

DELAY:

MOV R3,#50

DELAY1:

MOV R4,#100

DJNZ R4,$

DJNZ R3,DELAY1

DJNZ R2,DELAY

RET

;--------------------

T0ISR:

PUSH ACC

CLR TR0

MOV TH0,#0D8H

MOV TL0,#0F0H

SETB TR0

MOV DPTR,#LEDTAB

T000:      ;数字显示

MOV R0,#DAT

MOV A,SCANLED

ADD A,R0

MOV R0,A

MOV A,SCANLED

JNZ T001

MOV P2,#01H

SJMP T0DIS

T001:

DEC A

JNZ T002

MOV P2,#02H

SJMP T0DIS

T002:

DEC A

JNZ T003

MOV P2,#04H

SJMP T0DIS

T003:

MOV P2,#08H

T0DIS:

MOV A,@R0

MOVC A,@A+DPTR

;  CPL A

MOV P0,A

INC SCANLED

MOV A,SCANLED

ANL A,#03H

MOV SCANLED,A

POP ACC

RETI

;--------------------

CHGKEY:

MOV A,KEYVAL

JZ KV16

DEC A

JNZ KV01

MOV KEYVAL,#7

RET

KV01:

DEC A

JNZ KV02

MOV KEYVAL,#4

RET

KV02:

DEC A

JNZ KV03

MOV KEYVAL,#1

RET

KV03:

DEC A

JNZ KV04

MOV KEYVAL,#10

RET

KV04:

DEC A

JNZ KV05

MOV KEYVAL,#8

RET

KV05:

DEC A

JNZ KV06

MOV KEYVAL,#5

RET

KV06:

DEC A

JNZ KV07

MOV KEYVAL,#2

RET

KV07:

DEC A

JNZ KV08

MOV KEYVAL,#0

RET

KV08:

DEC A

JNZ KV09

MOV KEYVAL,#9

RET

KV09:

DEC A

JNZ KV10

MOV KEYVAL,#6

RET

KV10:

DEC A

JNZ KV11

MOV KEYVAL,#3

RET

KV11:

DEC A

JNZ KV12

MOV KEYVAL,#11 ;=

RET

KV12:

DEC A

JNZ KV13

MOV KEYVAL,#12 ;/

RET

KV13:

DEC A

JNZ KV14

MOV KEYVAL,#13 ;

RET

KV14:

DEC A

JNZ KV15

MOV KEYVAL,#14 ;-

RET

KV15:

DEC A

JNZ KV16

MOV KEYVAL,#15 ;+

RET

KV16:

MOV KEYVAL,#0FFH

RET

;--------------------

LEDTAB:

DB 0C0H ;"0" 00H

DB 0F9H ;"1" 01H

DB 0A4H ;"2" 02H

DB 0B0H ;"3" 03H

DB 99H ;"4" 04H

DB 92H ;"5" 05H

DB 82H ;"6" 06H

DB 0F8H ;"7" 07H

DB 80H ;"8" 08H

DB 90H ;"9" 09H

DB 88H ;"A" 0AH

DB 83H ;"B" 0BH

DB 0C6H ;"C" 0CH

DB 0A1H ;"D" 0DH

DB 86H ;"E" 0EH

DB 8EH ;"F" 0FH

DB 0FFH ;" " 10H

;--------------------

END

以上就是关于求大神帮写一液晶+STC89c52单片机+4*4矩阵键盘实现简易计算器的C语言程序,实现加减乘除以及扩展功能全部的内容,包括:求大神帮写一液晶+STC89c52单片机+4*4矩阵键盘实现简易计算器的C语言程序,实现加减乘除以及扩展功能、怎样用单片机实验板上的矩阵键盘和显示器编写一个简单的计算器,要求能一位数和两位数的加减乘除、求一个 计算矩阵行列式 的C或C++程序!等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

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

原文地址:https://54852.com/zz/9442828.html

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

发表评论

登录后才能评论

评论列表(0条)

    保存