|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
单片机计算器设计 内附原理图和PCB 程序 仿真( Z4 M5 X' ~' }- o/ A: f; A
4 t* ]- H3 [" S8 B5 Z
* [+ _2 M9 D1 K下面是计算器的proteus仿真原理图:& m, {, |5 O+ G7 Y% A
& p* k9 I- b% ?$ t$ r" q7 f3 e7 F% X: r) c8 |4 Y) X, Y& p
单片机做的计算器的ad画的原理图:) z" b- j- a( ?& y* _- O4 X# w
$ g7 q) s6 o- \8 _, v+ T
) @6 d1 V; W! F+ E7 y1 c" F单片机计算器的pcb:
/ p7 d7 `- x: B
: ~) c4 ?: u# N1 t3 l9 j( I* z7 f' o+ F2 ~
计算器的单片机源程序:
$ T) t) k/ p @0 M% U' ?7 [#include //头文件# ~, r4 O) T3 U( O" G+ a
#define uint unsigned int
% p% v7 F7 K/ E+ V# j#define uchar unsigned char
4 t& e) z+ t: _' @& E' O% l8 R# N
9 I$ F8 G3 Y1 e/ ~4 p# C4 Q% M+ w5 {0 j
sbit lcden=P1^1; //LCD1602控制引脚. N5 Y# D; C5 N
sbit rs=P1^0;1 y+ R D; {0 V5 n5 M0 Y6 e
sbit rw=P1^2;% W& ~7 L9 U' P/ c7 T/ C5 C, e* [
sbit busy=P0^7;//LCD忙+ T! ?! I+ m2 S/ p3 Q/ S. c
. K1 U4 Z8 E1 x7 E8 C* O; c5 q8 ~9 M' v1 t' a) W1 i
char i,j,temp,num,num_1;6 U# s+ W' h' ^+ t' A4 f
long a,b,c; //a,第一个数 b,第二个数 c,得数
# B5 z7 K, \: T6 E8 Rfloat a_c,b_c;) }9 v. j4 T- O2 K. B+ X
uchar flag,fuhao;//flag表示是否有运算符键按下,fuhao表征按下的是哪个运算符9 s7 d2 }$ j; l: t- i7 c
//flag=1表示运算符键按下,flag=0表示运算符键没有按下;
2 y' ~+ F$ g8 A3 U- P//fuhao=1为加法,fuhao=2为减法,fuhao=3为乘法,fuhao=4为除法。
7 d, b5 O: i( x1 ?, ?: t- s% P
" T' C. A% b' B3 H& [; O0 [2 C; g0 @* _
2 v( f6 D% [, }% euchar code table[]={//运算数字输入数组
/ M9 g7 ~) Q/ r5 F& o& _5 V# n a5 _7,8,9,0,
; o5 K P4 C D4,5,6,0,
( i6 R$ W- w* x+ I: A8 ^1,2,3,0,
) P4 V9 Q- T# h9 K0,0,0,0};2 @4 z# \9 t1 D3 q( d
uchar code table1[]={ //经处理后进行键输入显示准备的数组
& y0 p0 [5 `- q8 s5 A5 q7,8,9,0x2f-0x30, //7,8,9,÷7 R j3 [ Z; h& C7 N# l
4,5,6,0x2a-0x30, //4, 5, 6,×4 z, [. Y' j! h) R5 \& i
1,2,3,0x2d-0x30, //1, 2, 3,-
5 l r; X3 T7 q* J3 j0x01-0x30,0,0x3d-0x30,0x2b-0x30//C,0,=,+! F2 q; x2 m- E
};# m$ v6 o6 j1 `# E
void delay(uchar z) // 延迟函数
+ B! [/ P2 e0 Z$ q! p% L{0 t1 J' n3 |. j
uchar y;% L ^3 |0 M6 N$ Z4 D8 T# z
for(z;z>0;z--)
q: F; x. z1 W6 v& E6 e8 \ for(y=0;y<110;y++);
* o+ Q- m# T* _5 q. ~}
n8 ?3 ?( N+ s, u2 xvoid write_com(uchar com) // 写指令函数
: v; ^7 U& O& |% W: K9 x9 Q+ }7 P{; P; ?* s- W) G' @8 Z7 q$ H
rs=0;! P/ H! P8 x! X) v( |7 i
P0=com; //com指令付给P0口) m3 V' j, @" H5 R1 i
delay(5);lcden=1;delay(5); lcden=0;
! F. p j- V. ]2 g, H: R! P' r+ u2 N}/ a5 T% }2 r+ {- X% t6 Y
7 {+ c# \, r( q8 T8 x
1 \' l2 B% G1 ~& T3 yvoid write_date(uchar date) // 写数据函数
$ }/ k4 f6 r3 B4 L5 U{
9 H6 A! c# Q6 Z; U9 u4 u4 f rs=1; P0=date; delay(5);0 d3 E: M" [0 M( {* j
lcden=1; delay(5); lcden=0;# H) ^0 T; D# B! H2 k
}2 C! e! g! V* ?" ^" K" { P
- L9 T7 o" N2 X
0 D# M7 w# D9 xvoid init() //初始化9 c U U9 x; l! @
{
+ ?/ o% B. V9 N& q; r num=-1;
, r$ |$ ?% k$ b3 c3 @lcden=1; //使能信号为高电平
4 p- h9 [+ _ u3 L8 Jrw=0;
* X; ? \- u' X$ i( z, t4 G8 |* Pwrite_com(0x38); //8位,2行
- ~. [& y- v; n$ }7 q. ?delay(5); write_com(0x38); //8位,2行! X) T# E: V+ _+ A
delay(5); write_com(0x0c); //显示开,光标关,不闪烁*/
+ w5 \+ _& ]8 o( Sdelay(1); write_com(0x06); //增量方式不移位 显竟獗暌贫 柚?
2 y# y: v+ T5 a" }: [4 p4 pdelay(1); write_com(0x80); //检测忙信号
, c1 { [- ?$ {' w& v* Z# H6 zdelay(1); write_com(0x01); //显示开,光标关,不闪烁
; }( c) A- l! F; `& s8 m3 U' Y3 D4 hnum_1=0;* U! h7 e6 `: j. A
i=0; j=0;# ]5 y; e; S5 [) N$ _1 `
a=0; //第一个参与运算的数% F) j* d8 w( l1 I" E7 ?
b=0; //第二个参与运算的数8 q+ f O- ?* v( A `8 `) ]
c=0;
1 d" b! [8 F% I; ]* X5 Wflag=0; //flag表示是否有符号键按下, 8 d" w# {5 k- k5 ]
fuhao=0; // fuhao表征按下的是哪个符号
: }* W3 V) ^2 o3 V}. j! t& P, F. @9 ~5 H
void keyscan() // 键盘扫描程序
3 i: V: L2 [- u7 K- g{
) l- _4 `3 c; \6 u# P3 z; M3 H; ? P2=0xfe; 4 X( V- W) @ x+ |
if(P2!=0xfe)
- Q, S$ A* u3 c0 t7 o6 F/ B {
3 j2 X% B, O! t1 Y' |: R delay(20);// 延迟20ms8 N) L( z9 A) O. ~: N( X) S( B
if(P2!=0xfe) { temp=P2&0xf0;
* f$ w# D1 Q* n; ^ switch(temp)6 x% `+ K8 R6 M6 R
{
7 p' [7 |5 H# |6 ~ case 0xe0:num=0; break; //7
( }: a8 I" e: T# x7 i% p' l case 0xd0:num=1; break; //8
, E4 m( e2 y" f# w1 R& A case 0xb0:num=2; break; //9- I5 ]( x4 R9 ]3 v
case 0x70:num=3; break; //÷
3 f1 `' V' m B! F0 O }5 r' D. @& y6 E- q$ e# N
} while(P2!=0xfe);5 E6 A5 |) u) }3 Z9 `* R
if(num==0||num==1||num==2)//如果按下的是'7','8'或'9) D/ _9 n% D" I* A' M2 ?
{ ( _% Q( g, u: \! g/ K2 F8 E. D
if(j!=0){write_com(0x01); j=0; }9 C1 z+ G5 v1 S% `. j0 z( V
if(flag==0)//没有按过运算符键8 |& W& B% K5 N- b. E# B5 O' O
{ a=a*10+table[num]; } //按下数字存储到a2 o4 O [: G: y$ d( Q
else//如果按过运算符键6 w7 e$ `# V x7 e: S
{ b=b*10+table[num]; }//按下数字存储到b) K5 ^) J8 i( |
}
6 M2 h2 h, K2 n1 _9 s. P8 A9 N/ q else//如果按下的是'/' 除法& Y4 N8 r" o1 ^: @* z9 ?
{
; x! s$ L9 b3 I0 k flag=1; //按下运算符/ F% H5 a) |- u, |: h- o, v
fuhao=4;//4表示除号已按+ Q$ F: r# c) \
}! ~& u. O# Z" J9 Z
i=table1[num]; //数据显示做准备
- z+ S3 G/ E& N: r7 p write_date(0x30+i);//显示数据或操作符号
" s' q- q! k4 U$ H4 s& ?" j }
9 Z7 H' u# Z3 z: _
' [' O" ^. T" D# d' v0 x/ R
: ?, i; G# d K; e P2=0xfd;0 B. G5 C* v% J+ Q( _
if(P2!=0xfd)
8 l7 p4 v; _6 g3 w# Y: |: f, [; s {7 r9 k) Y8 g5 l' T& b4 O' M0 ~% a; j
delay(20);
( E5 p6 }. h! C1 O if(P2!=0xfd){ temp=P2&0xf0;5 Z/ a" O: \) D
switch(temp)# b# G5 s/ x- S, ^- V" G0 r( N
{: W( M4 I8 F$ [+ H6 q- I! `
case 0xe0:num=4; break; //4
' `" M+ h6 N1 K case 0xd0:num=5; break; //5
- {7 u5 O$ F# E) n! W! _ case 0xb0:num=6; break; //6, a$ a' G7 I; y9 |- N
case 0x70:num=7; break; //×0 J" A5 f$ ~& B1 [- i
}' S; {4 p0 u* r1 a
} while(P2!=0xfd);//等待按键释放8 y' m0 f1 U7 P2 l. _, A
if(num==4||num==5||num==6&&num!=7)//如果按下的是'4','5'或'6'
1 F- K7 d o- X; E: _/ u# e { ; O8 U8 l+ J8 e; W3 f
if(j!=0){ write_com(0x01); j=0; }
- e4 l: t7 ]& ~( a$ r# I if(flag==0)//没有按过运算符键
( k4 {- K) J% m! R; o { a=a*10+table[num]; }" `, z; ~- v4 o' `6 d. b
else//如果按过运算符键) v4 r' p* d& D" ~3 U: y
{ b=b*10+table[num]; }/ G$ ]# {4 j/ h& j5 R
}' a( q# |9 t# u9 U8 c
else//如果按下的是'×'
1 y7 E2 N/ R/ R7 u { flag=1;8 D4 z# }) Q) z a) W9 H
fuhao=3;//3表示乘号已按# J2 B' J, O$ _& e( x! J5 _9 h5 D
}
% j; |3 z7 s8 I0 t; A' r% M- o5 R$ s i=table1[num]; //数据显示做准备
- x3 R7 v9 E4 h; Z0 Z# Q write_date(0x30+i);//显示数据或操作符号
/ {* p( A: b) H6 D8 L) | }
2 x8 Y: f9 \3 ?& Q
3 {+ ?' p4 a1 L( ^- @- x
3 |- B0 } r/ F) B, F P2=0xfb;3 L3 g: M3 {) T3 i# y" m
if(P2!=0xfb){ delay(20);
& I( y0 L6 t" O( s4 ^7 u if(P2!=0xfb) { temp=P2&0xf0;# q( O2 p1 l ~- Q; P
switch(temp)) c4 l+ Q- j$ v1 S
{
8 F f4 ^- g* J" G case 0xe0:num=8; break; //1
8 @5 u6 i i8 y: S; \ case 0xd0:num=9; break; //2; e- ? G1 b3 P- `% t
case 0xb0:num=10; break; //3' K4 J M( i4 d% L
case 0x70:num=11; break; //-
( X6 C5 Q3 g. z' ^- j }7 s6 y% C4 b% [4 l. B) y
} while(P2!=0xfb);) P; U( d7 @! e9 F5 W: J) J/ p
if(num==8||num==9||num==10)//如果按下的是'1','2'或'3'
0 z& f( I2 m( T" U( U { * J1 \$ J/ d6 T6 n+ t6 S3 B5 _6 S
if(j!=0){ write_com(0x01); j=0; }
1 ~& U8 @/ n( H1 d& l, O! M3 p. D if(flag==0)//没有按过运算符键
1 l/ y) i2 {( r% L" f; W { a=a*10+table[num]; }% e3 i+ E% N6 t
else//如果按过运算符键
9 D8 r2 `' l; Z( x0 C4 X { b=b*10+table[num]; }
! P) j% W! U5 q, R2 V# Q9 a$ |. Y }4 Y2 p6 L# F: y3 N
else if(num==11)//如果按下的是'-'8 n% o% y- i& ~( V
{0 s8 [+ D$ j# t+ c- ~' g
flag=1;* l+ Z( Q, @# B j+ O
fuhao=2;//2表示减号已按
3 M* i$ x9 [# Y& g1 \, G9 W* M* k }
, {- B5 I, [, e/ d/ V& n j& } i=table1[num]; //数据显示做准备
3 s- U9 \/ M2 y& b! @! ] write_date(0x30+i);//显示数据或操作符号
; D* j# P0 @+ n6 y }+ N0 w9 O6 C9 p
( Q/ z! {# T- j: n1 k/ F9 a
1 c8 ?( V2 n$ q0 F7 S P2=0xf7;
- ^9 R' z7 N' e) i- s8 \ if(P2!=0xf7){ delay(20);
, T: V* o# E0 _% m+ `8 w2 l if(P2!=0xf7){ temp=P2&0xf0;: |* K4 S! {+ f4 Z8 U. v
switch(temp). s% I& L$ l2 s3 M
{* {" p9 a" h3 B
case 0xe0:num=12; break; //清0键 + \: }9 B- n! P6 ^
case 0xd0:num=13; break; //数字0
: R8 `/ `6 N, o+ H( A) t case 0xb0:num=14; break; //等于键 ( D9 |0 l: {) P- m: b. h$ y6 T9 C8 Q
case 0x70:num=15; break; //加( ~: \: K7 ^0 E" L6 K' u
}
1 R7 v( p3 N9 b! l1 K7 _8 O } while(P2!=0xf7);
% q. L! s& j7 s l" q% H' i' P4 V& X( a9 m% d
7 G$ S+ }3 \! \- Z switch(num)
3 s- W# b$ M2 k: G! X {4 j1 u0 j3 }# b2 }. F
case 12:{write_com(0x01);a=0;b=0;flag=0;fuhao=0;}//按下的是"清零"0 P' b4 T/ v2 G, j7 ]$ g
break;9 {1 ]( N# H, T" m
case 13:{ //按下的是"0"9 Q% U% H; D" ^6 I
if(flag==0)//没有按过运算符键* b8 {2 Z! s- s
{ a=a*10; write_date(0x30); P2=0; }' p1 w" Y7 Q) M
else if(flag>=1)//如果按过运算符键
3 K3 Q$ ^# U4 | { b=b*10; write_date(0x30); }
/ s+ _5 G) k% J1 ?% Z } break;
9 q! G$ H$ c+ @8 n case 14:{j=1; //按下等于键,根据运算符号进行不同的算术处理
+ z" l) [' D3 k; b3 K, H: g5 w if(fuhao==1) //加法运算7 m3 Z! V5 t. I
{# p% u' e @6 F% G4 T
write_com(0x80+0x4f);//按下等于键,光标前进至第二行最后一个显示处 ! M1 l; x' u0 o+ @
write_com(0x04); //设置从后住前写数据,每写完一个数据,光标后退一格 " n# ?5 \6 d7 L3 e. `6 _- X+ D0 A
c=a+b;
: S, y% J$ s3 i while(c!=0){write_date(0x30+c%10); c=c/10; } # g4 }5 Y, N# S1 v) y# Q. O
write_date(0x3d); //再写"="; @! Q e8 F: s/ r
a=0;b=0;flag=0;fuhao=0;
* x" g0 R- H f4 g. q }6 G1 W3 H( L, v+ I( L3 r
else if(fuhao==2) //减法运算
' D8 V! V' ~( O8 ?3 C+ `8 W {
9 k& a2 G; C3 M5 t3 M4 v/ r( N write_com(0x80+0x4f);//光标前进至第二行最后一个显示处" Y9 ?$ Q' T& W% C
write_com(0x04); //设置从后住前写数据,每写完一个数据,光标后退一格(这个照理说顺序不对,可显示和上段一样). I/ u/ l# ~) {9 @) p; A7 |
if(a-b>0) c=a-b;* `0 p# B% [/ U8 }" F u
else c=b-a;3 T, F! P9 l9 L/ Y3 e* l2 R- z
while(c!=0) { write_date(0x30+c%10);c=c/10; } 9 n' l: U. q- N" n7 C: [
if(a-b<0) write_date(0x2d);$ z% Y% C9 s* B' m. \9 d
write_date(0x3d); //再写"=" 0 U+ n" \% E* T9 E1 r# _
a=0;b=0;flag=0;fuhao=0;
3 G& e9 }% X) S$ T5 G }2 A( @# A7 H! u& X" z
else if(fuhao==3) //乘法运算 4 j) y: M$ C2 c2 M, G
{write_com(0x80+0x4f); write_com(0x04);1 w; e3 R) i+ k3 _8 g1 Y8 N1 G
c=a*b;/ e$ F( ~* Z+ m3 c5 m
while(c!=0) {write_date(0x30+c%10); c=c/10; }
- \/ x7 i: w- W" j/ { write_date(0x3d); a=0;b=0;flag=0;fuhao=0;
" F& R9 B5 u: b. l! J }% k7 v; ^. w& p; [
else if(fuhao==4)//除法运算
; p( `3 W- {; ?9 B9 g% f {write_com(0x80+0x4f);
. s H8 z# h9 X4 w/ X2 U1 A( W& E write_com(0x04);; b* ]- Z" c& p1 D8 ?! ?6 e7 F3 Y
i=0;3 p) h" r* T5 f$ n
if(b!=0)
, }5 x& w k) e N+ M2 i {5 a; ?; Q, `) K+ m9 K
c=(long)(((float)a/b)*1000);
) s4 Q% b u2 k: X, t1 J. I while(c!=0)- I2 A: @" O+ K' [4 U
{ ' C! V- b9 m6 E( ^
write_date(0x30+c%10);
q' R# k: W& f& Q) e3 v6 n! y c=c/10;$ b. R! j6 k6 ^% j; A, o
i++; if(i==3) write_date(0x2e);
5 B: J+ i& v2 h, B7 n }
2 ?* @: u' C3 k) t( @- T5 v) T if(a/b<=0)
1 }0 @, v7 k1 E {
9 K; u: a9 [6 J- g' v& u if(i<=2)
& Y) G) P5 A2 U' `8 M x6 `" L* u {
2 m/ f7 h* Z4 O
8 a/ f6 T+ W5 B# J1 ` if(i==1) write_date(0x30);" o5 U2 N) m8 D1 P) Q) {
write_date(0x2e); // .* B& I5 o3 e& ]' U6 z& f4 m
write_date(0x30);
9 J" L, ?# |- e8 w4 Y& D* H4 @, d) w8 P } ' A0 |7 _3 |& b5 x
- a: u6 o8 P# F; H. C write_date(0x30); //
2 F+ ]2 ]$ F2 {$ | }+ W& t; Y& e/ b! h/ c( U- N3 t/ ]
write_date(0x3d);
6 n q) O, u: b8 b a=0;b=0;flag=0;fuhao=0;
5 I! W) s3 |* Y" i3 S7 K }) l9 c! p* J. o* D0 F, N1 l$ G
else4 m: _( L u" v4 b; P0 r5 b
{' y* s1 F1 T- w. l
write_date('!');write_date('R');write_date('O');9 \ e7 F: E r, d7 h( [; ~1 R
write_date('R');write_date('R');write_date('E');
9 b C+ w% c. ^6 r }
# B* [/ `) m, r% |9 D) d+ s/ |+ ?" @ }
: l# O! X: r9 J } break;1 T2 Q" T8 }. d! V ^* p
case 15:{write_date(0x30+table1[num]);flag=1;fuhao=1;} break; //加键 设置加标志fuhao=1;# g* Q8 _) _6 e0 R, Y4 n
}! f" ~7 |) E) E8 }0 V9 {
}//P2!=0xf7! G3 D% I) F( J1 a- N7 R
}
9 P1 |8 a4 E& x8 p) b) l
' @, P% w- j9 L& g0 {- r5 W0 {3 ]2 ~9 }" R2 J
main()- c6 ]; q+ x# n+ ]6 G7 q, d# M- B
{
; o P7 J- m8 T2 z( Q; P init(); //系统初始化
Z7 M8 m# T" l7 l! |) q while(1)( ]" E: V( _5 h) {0 b! v
{
8 \& m) _6 ^; G5 l# A; I keyscan();//键扫描
' G' Y4 o# e7 U% L( ^- m# [2 G }
2 r5 x$ k/ k+ U& I/ h5 D}
* i/ z7 \$ J8 }0 Z7 t
: s1 p( m( U2 d2 U
3 I& s3 n+ B d2 m3 x7 p3 W8 J% a0 D( l% P
" T7 m+ y: ]* s- x
下载:
! }' N( y' O5 o1 C+ u, b3 o9 e l2 m# U
) N# [; U& E# C; f+ z' }% i# _; q
|
|