|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
单片机计算器设计 内附原理图和PCB 程序 仿真
$ N6 t+ `+ Q- C* r4 i5 k& X& A
" X; P3 R7 U5 d( J" j
4 W" c1 W( k p* v" c0 W下面是计算器的proteus仿真原理图:; ~& `( y. a: X0 |; G/ l! K% Y S+ N) Y: L
1 ~3 b4 O' j# |1 x$ e
2 O5 a' P- f k, O5 @单片机做的计算器的ad画的原理图:/ `2 o/ N: M8 Z# g* s+ S
s6 a* u% t5 d6 Q+ D+ }9 p
1 k( d/ Q+ \/ m单片机计算器的pcb:2 ~# j5 n k+ r8 B2 Y
6 Q7 }6 r( E W4 m1 I8 b; [" ^9 {0 Q. L0 ]( b( v: e1 I
计算器的单片机源程序:
/ M0 {) z( Z1 {# Z# G6 S#include //头文件
) n6 \- R( E K: H8 K/ {#define uint unsigned int ) Q& W/ c( e# ^" o5 ]: O
#define uchar unsigned char _4 {& {0 M$ [+ t' v
) U8 G/ h; [4 Q* y
0 _, i6 S5 D% b1 g
sbit lcden=P1^1; //LCD1602控制引脚5 ?: N, f/ ^. }% b/ H. W$ Q7 Q
sbit rs=P1^0;3 U8 G! P* y4 F2 j) v
sbit rw=P1^2;
8 P" E4 H2 X5 B/ Isbit busy=P0^7;//LCD忙
7 I# ^! F% U6 C( T) [6 o4 M: x
) @* V, `; i: }! j7 Z" ~
8 \3 C- A; n3 w, H4 ?2 Bchar i,j,temp,num,num_1;
$ D1 o" s2 N/ n3 s$ ^8 Xlong a,b,c; //a,第一个数 b,第二个数 c,得数
; |9 e% ^/ ]1 D5 S1 kfloat a_c,b_c;$ s1 M) d( D/ z9 O: n4 D
uchar flag,fuhao;//flag表示是否有运算符键按下,fuhao表征按下的是哪个运算符
3 j! j; ?9 `( g6 p ~- N+ T//flag=1表示运算符键按下,flag=0表示运算符键没有按下; D2 X ?9 e; s9 L( y
//fuhao=1为加法,fuhao=2为减法,fuhao=3为乘法,fuhao=4为除法。' i- e6 `0 I0 p4 t6 S# t
5 q: W- ?* P; q0 d% i1 `( z0 {
, }+ S2 I. b2 R, `, Zuchar code table[]={//运算数字输入数组# E. _4 I8 X# V; e% m$ K3 v) o
7,8,9,0,9 c9 W6 b! E6 C( P- ]# W, S1 ]
4,5,6,0,
$ B' [9 N: d7 O9 h9 _7 \1,2,3,0,5 r0 w( V) R3 S" p% Y
0,0,0,0};8 P1 Z1 T9 s) A% {/ Q9 k
uchar code table1[]={ //经处理后进行键输入显示准备的数组9 k3 @" S: @6 \0 K6 u
7,8,9,0x2f-0x30, //7,8,9,÷2 J( |6 a" P" M
4,5,6,0x2a-0x30, //4, 5, 6,×
: F9 G5 Y+ v% h! T) E/ _1 v1,2,3,0x2d-0x30, //1, 2, 3,-
2 y8 X, j& s! s3 K7 n/ f0x01-0x30,0,0x3d-0x30,0x2b-0x30//C,0,=,+- e- j4 z: y) q
};7 Q- \+ |' B, h, s& p+ c8 w
void delay(uchar z) // 延迟函数
6 B# P0 V1 h5 x9 X{# f! _' @4 R$ c0 u1 G! X
uchar y;
& G( h9 _# P# P4 K& ~. C7 l; Rfor(z;z>0;z--)
9 ]7 g& [0 Z B. R( F% c2 ~ for(y=0;y<110;y++);0 W* `. R/ a) @$ R7 k$ r
}
2 f! Z q" h, wvoid write_com(uchar com) // 写指令函数- Y% q$ _0 k ^! b3 C$ U% t
{
% v2 W: V( n7 X. K6 m/ C rs=0;6 `# S2 Z& s: j& y, L( j! h5 ~
P0=com; //com指令付给P0口! @3 B5 _% a" z: B3 Y) D4 C& R
delay(5);lcden=1;delay(5); lcden=0;
. K# J: a6 w, p1 z3 C. Z @, \8 X}
$ c' M, C# s6 S2 Q% v
|7 Y a! Z$ x4 U3 Z% [
" `2 Y" b5 g$ Kvoid write_date(uchar date) // 写数据函数
- f2 F* u% d$ y0 A{, ?8 n. X" R7 A9 \. E# X( ]% R4 m+ Q
rs=1; P0=date; delay(5);1 i4 K S; t2 N2 W8 M9 C+ r
lcden=1; delay(5); lcden=0;
, |7 j/ g8 F. Q( ~4 j/ d}" [8 S/ z/ G* _$ F1 r/ g9 o
, C' j: y& V1 ]0 X8 s6 @
( C j9 n' W* h0 M) b! nvoid init() //初始化
5 Q- d4 R5 U4 q+ w{
* V4 F9 U4 C5 {- u num=-1;# M, ~9 G' j& u# k- i
lcden=1; //使能信号为高电平) G- k" H8 k" Z/ p+ H4 T1 g/ A
rw=0;, e$ I! {( R& i9 u
write_com(0x38); //8位,2行
- J7 b5 g# R* N- Q, P- s8 C$ D6 Sdelay(5); write_com(0x38); //8位,2行9 z) M( E) P2 W+ Y; c }& B
delay(5); write_com(0x0c); //显示开,光标关,不闪烁*/4 E" A' I. O+ B% [0 T" x$ X
delay(1); write_com(0x06); //增量方式不移位 显竟獗暌贫 柚?
: A8 P& d: Q8 [1 T! Vdelay(1); write_com(0x80); //检测忙信号5 U4 P6 g' V# P4 y6 K
delay(1); write_com(0x01); //显示开,光标关,不闪烁7 F9 E$ B* M; E$ O
num_1=0;, u& ]$ y3 S5 G* Q2 F! p
i=0; j=0;
" ]" p' A# ^4 Y0 I. l5 Aa=0; //第一个参与运算的数
! p; o0 s9 J+ w- a+ ~b=0; //第二个参与运算的数$ i. Q7 f: ?8 ~3 d4 F: h
c=0;
; P! \% Y8 ? m. X- ?( ?flag=0; //flag表示是否有符号键按下, ) E% Y, i4 n% ~& F" Z, r. ^
fuhao=0; // fuhao表征按下的是哪个符号
) F0 Z. w- C# d6 J}
3 u: R5 d& i- e! rvoid keyscan() // 键盘扫描程序
! p) l0 V/ A" n& U{
) V: y3 Z+ q) f! N3 V P2=0xfe;
& P, B7 c" a( t4 R* i9 c$ V if(P2!=0xfe)
/ ?, Z9 o% _1 T/ i2 r {
: {6 \1 T; P5 W$ s b delay(20);// 延迟20ms: V- w0 v1 `5 v3 F: [" ~0 H( P
if(P2!=0xfe) { temp=P2&0xf0;
6 u. E3 W& W4 B; A4 r& _; h switch(temp)
- ?- m: f) J) j9 ]7 m5 e {
5 o6 \$ y5 T* z% R/ Y' k case 0xe0:num=0; break; //76 M9 n' {" v/ c) K3 G7 z
case 0xd0:num=1; break; //89 C! I) \% r1 }0 E1 R! Z
case 0xb0:num=2; break; //9% G; J: v* S) I& U; S6 L; g0 Y! U
case 0x70:num=3; break; //÷
5 B! V- e D: p, K% @1 {+ E% I }
7 I- e6 K+ `+ O } while(P2!=0xfe);" C" v6 E) ]) E. t. S; I
if(num==0||num==1||num==2)//如果按下的是'7','8'或'9* j9 {7 D- a/ r; ]9 p2 a% ]
{ $ ]( a! i6 t4 S$ P8 i) r& }" T
if(j!=0){write_com(0x01); j=0; }% ?5 | `# M) o f+ w6 ~
if(flag==0)//没有按过运算符键# @% J) R' t3 l$ c2 H) g. ?' `
{ a=a*10+table[num]; } //按下数字存储到a
& `) ]5 A G, c" y5 c else//如果按过运算符键
, @; N; a) L+ n7 D7 N* c { b=b*10+table[num]; }//按下数字存储到b8 s# Q L- O4 x
}! |+ k' D8 z. g& |7 }
else//如果按下的是'/' 除法
/ S1 d; k4 m' J" G$ L! Y+ B {
5 K$ `, [2 t* T" T6 u flag=1; //按下运算符
" ? n, v! _6 S& _* a! H fuhao=4;//4表示除号已按
; p4 I+ X* G P2 S }
4 D8 V' M3 e ^5 |8 u1 ~ i=table1[num]; //数据显示做准备
: }; a% n K5 ~$ i4 D write_date(0x30+i);//显示数据或操作符号
9 ^% }% S/ f2 q2 ] }: |4 ?" `" |7 u3 v. U9 T1 G6 ?
% H2 E0 `7 a% E' g9 m: r, g+ d5 D* ~
0 |1 a' n m8 n; V: N+ [8 n, `0 g P2=0xfd;
& g# M6 ?1 }$ E8 o if(P2!=0xfd)
) E$ e$ H7 i5 u# z( F8 D {
8 C1 l; A* `! w: I7 |, b& q/ W delay(20);7 q' k9 r6 N) J- D! W W/ d
if(P2!=0xfd){ temp=P2&0xf0;
/ V% z% ~$ O3 X$ F switch(temp)
9 E. W7 I8 k' Y3 v1 g {
\1 e5 o# S* ]! I6 h# E5 S5 I case 0xe0:num=4; break; //4; {1 k8 p$ Q' S' W' t8 a% a( Y
case 0xd0:num=5; break; //5
" Y1 J w) C6 |' H/ D: y case 0xb0:num=6; break; //6
3 L. \/ {1 G2 \7 v1 ] case 0x70:num=7; break; //×
6 j, a ~6 Y2 G/ w% t }
: d# E( p1 `9 y9 S$ S } while(P2!=0xfd);//等待按键释放/ \* F" k$ R/ j% t' T& l- p
if(num==4||num==5||num==6&&num!=7)//如果按下的是'4','5'或'6'6 C+ m+ t( K8 d3 A& i! e4 s7 b
{ 6 G; p7 K6 q2 N$ m5 N! |
if(j!=0){ write_com(0x01); j=0; }* ~ U, d; Y h! m0 K4 y
if(flag==0)//没有按过运算符键; c" x$ c5 r0 Q% d. k$ t
{ a=a*10+table[num]; }; c- U" g, I9 s8 P
else//如果按过运算符键
& _( Y w% G: e { b=b*10+table[num]; }/ i: _7 x4 \, S6 f" B5 [7 q( W1 x
}
: Q- k9 R8 t3 P5 H6 z4 h6 ]& u else//如果按下的是'×'7 x5 ]( |/ \/ U( F" m: k: n
{ flag=1;- z4 ~7 `$ d! }# d. W
fuhao=3;//3表示乘号已按
$ u. @3 }' [ Z9 \$ [0 }! }4 U }
8 g9 l+ T8 o/ l, t i=table1[num]; //数据显示做准备
y- m/ t9 U" D- v write_date(0x30+i);//显示数据或操作符号
/ X A; C; d# F }
! e, H. _0 ~$ ^2 B( ~% c% j7 e& w( Y+ }( p9 P
/ `' v% ~5 {; D. n H P2=0xfb;
# i" n$ D: V k6 C! C9 W. J" K6 Z; B if(P2!=0xfb){ delay(20);* y1 t/ D8 b9 J0 y: i
if(P2!=0xfb) { temp=P2&0xf0;
1 L. l: G" [* p4 @ switch(temp)) V# U7 i3 ^2 s x* n1 ?. [
{2 |4 L0 u4 p+ ?9 r0 D5 J
case 0xe0:num=8; break; //1
; ]: x& C/ `; v( t* C9 s( @+ c3 B case 0xd0:num=9; break; //23 k$ Y$ k3 z+ W% w: v. d1 G
case 0xb0:num=10; break; //3$ L. S( |7 {% f( T7 b( v
case 0x70:num=11; break; //-
& g9 N; O1 O; i/ a" e0 M! Z( _) ] }
6 ]& ^# j8 s% X8 T! ?1 r1 k/ S } while(P2!=0xfb);( u4 B2 v0 t% A% A$ @
if(num==8||num==9||num==10)//如果按下的是'1','2'或'3'
8 q; j: p$ ?6 J2 d& k6 P+ t3 C% a { ' m1 `; I1 O# v# W4 E: `' A
if(j!=0){ write_com(0x01); j=0; }# q# h2 }1 l( U! h4 {1 B
if(flag==0)//没有按过运算符键' \# H" N! W2 b& b1 C6 D' _
{ a=a*10+table[num]; }
) ~3 N! \5 T5 Z! A# Z( K4 b: i5 g else//如果按过运算符键
' \1 I1 Y8 `+ q* v% @! ^ { b=b*10+table[num]; }
" ?7 |* ]7 K3 j7 ` W }
( g9 _9 C& A9 o% E/ ]$ \7 y" o9 A else if(num==11)//如果按下的是'-'
0 K6 q( n" R- F8 z. y3 t {
, ]; @$ W, U3 F0 r6 L# v) L7 _ flag=1;
5 o7 q1 g# \! Q; e+ k. g% z fuhao=2;//2表示减号已按
' }3 s! O" s. U) {0 F. K7 f }
$ g0 ]; ^( Y5 C- F i=table1[num]; //数据显示做准备
. T" y" F; P7 x% \) E$ B$ z; x write_date(0x30+i);//显示数据或操作符号
) \1 h" N4 o9 N& l) { }" m1 j$ A4 S! |1 z1 ]
* r% o( p& J. E" Y* U
2 Q5 x# q% e2 e. _ P2=0xf7;" F( V' }5 r7 h' j$ X
if(P2!=0xf7){ delay(20);
4 `9 L$ b& m" O) N! B# U) j& S* [ if(P2!=0xf7){ temp=P2&0xf0;. Z- e5 B) S6 J4 R. b- {
switch(temp); {$ N# ]0 I# a8 S) U
{. C5 D" i' Z+ W4 {: V" d
case 0xe0:num=12; break; //清0键 , f; d2 }. c C2 d+ J- L' T
case 0xd0:num=13; break; //数字0 & {6 i$ m/ J7 W$ k* e
case 0xb0:num=14; break; //等于键 , [- E9 J# F6 e5 U: I' [# x
case 0x70:num=15; break; //加
" O. f- |' }- }6 d1 u/ d } 7 ?: i2 e: l& Y8 @0 g8 i4 D& h
} while(P2!=0xf7);
5 t1 {6 I8 J% m# W! h( L8 F1 |8 T' P1 v/ t. d1 Y
$ K u. S5 f; m6 Z( w" F
switch(num)3 M% n, v4 J5 U5 j
{" Z# n2 S( M2 ^. U5 g8 a
case 12:{write_com(0x01);a=0;b=0;flag=0;fuhao=0;}//按下的是"清零"
* j. l8 F F w0 P break;
3 \# V& }! K4 E6 N case 13:{ //按下的是"0"! `* ~% e0 N) M* V8 \' v7 I
if(flag==0)//没有按过运算符键+ ~% R# n ?- Y- e
{ a=a*10; write_date(0x30); P2=0; }
; ?9 r; Q6 p; Q: A1 ~ C) G else if(flag>=1)//如果按过运算符键. C; q, B% d, Q& H+ c# H
{ b=b*10; write_date(0x30); }$ y! \: t+ \5 c- k/ }
} break;
+ A: X5 X6 V( z2 j. Q case 14:{j=1; //按下等于键,根据运算符号进行不同的算术处理8 P; P3 P$ @* m" y
if(fuhao==1) //加法运算
1 G7 j T7 k1 G. X$ ] {
9 @: z. d" M4 ~ write_com(0x80+0x4f);//按下等于键,光标前进至第二行最后一个显示处
6 m0 w/ s/ p+ u( ]/ F write_com(0x04); //设置从后住前写数据,每写完一个数据,光标后退一格 1 p% G! q/ f' W% w3 z# \
c=a+b;
, V* z2 z( n" f& l, {- \ while(c!=0){write_date(0x30+c%10); c=c/10; } 4 G4 C, d9 q+ D8 g5 T! m c
write_date(0x3d); //再写"="
& i- U5 `- ], b' I7 ~1 l a=0;b=0;flag=0;fuhao=0;
# Z3 F: |$ R% {( ~2 C0 U7 D }7 y/ }+ Y6 J1 y; b) [
else if(fuhao==2) //减法运算- K X& H& u# g: X; n
{
; F" s7 r9 H( g% ` write_com(0x80+0x4f);//光标前进至第二行最后一个显示处' a7 g5 q* v2 @2 m9 I7 K% p: m
write_com(0x04); //设置从后住前写数据,每写完一个数据,光标后退一格(这个照理说顺序不对,可显示和上段一样)
5 B# ^! N6 U9 K, i0 x% d% ` if(a-b>0) c=a-b;
9 q. K% r# T! L! t6 H6 T else c=b-a;
- G6 f$ \$ }, |" r, N) f$ o# q! T( u while(c!=0) { write_date(0x30+c%10);c=c/10; } . ]6 b9 g; i& O1 {! v4 [' N7 C' H
if(a-b<0) write_date(0x2d);
2 i* o; V# g8 S5 A2 U write_date(0x3d); //再写"="
6 P+ a& n9 \# j a=0;b=0;flag=0;fuhao=0;6 f* z# r. q+ c
}
1 k1 s i9 C% A9 s8 A else if(fuhao==3) //乘法运算
" o, Z. R( _% D# ~/ h {write_com(0x80+0x4f); write_com(0x04);
- e( S& X: x6 _0 j* x: Z c=a*b;
$ `+ n+ m$ Q5 ^; q3 v, R while(c!=0) {write_date(0x30+c%10); c=c/10; }
& |7 r( u% n& l" ~, ? write_date(0x3d); a=0;b=0;flag=0;fuhao=0;
$ r+ I3 ], c8 V6 B6 ^ }
0 T9 c6 a2 d/ F: C, f! B* J else if(fuhao==4)//除法运算 5 } l0 `- x& S& V0 M7 D
{write_com(0x80+0x4f);1 ]' J) c* _2 t0 ]0 J3 F& V" w
write_com(0x04);
7 o5 a9 R% O$ N9 s+ C. c2 Q i=0;
# C0 u8 R+ i w/ K+ L. X1 d) z- ^7 r if(b!=0)9 r ?& ?6 q1 |2 e. ~
{7 ^8 v6 A; ~8 i& z; e9 p6 k0 r5 q
c=(long)(((float)a/b)*1000);
$ b/ {8 H" n* A. g while(c!=0). M( I4 d8 ~! r. ?, @ E5 @
{
7 o' y. ? ~' P( }$ [ write_date(0x30+c%10);
" s# _0 V9 F% A$ v5 v& A' M6 j1 w c=c/10;8 D3 R- @( [0 y U
i++; if(i==3) write_date(0x2e);/ D; F4 `/ r0 W4 S0 }+ z
}
: z5 {9 k* S ^ if(a/b<=0)
( ^! o7 d1 A& @: L# W# G+ r, p {
& ^/ u" U+ `, ^+ Z5 q, e3 j( j if(i<=2)
' b# b' \: z( G' a% K& e/ R {
; Y5 ]% w8 |6 k! h, P/ f. C % u5 s# V, J$ n; Y+ U2 w; i
if(i==1) write_date(0x30);
6 R: D# ]4 D3 `4 P- M write_date(0x2e); // .4 F. L7 t2 ]6 Y& b2 _, e
write_date(0x30);
* r' C$ K) \* Y( k$ C9 g% j+ O } * c! x5 g1 H+ Z1 q. H
# T, g: y" R0 x4 m1 g. d5 ]2 ~: v. t write_date(0x30); //9 w$ ?6 D9 [! [1 \9 s& Q
}
, B8 ^& O3 V: G* m" D write_date(0x3d);
2 Q8 U9 U( Y% Y. L a=0;b=0;flag=0;fuhao=0;
6 g: `0 m Y+ v- J6 N, b/ n5 _ }. n! R8 L5 ?9 X9 u
else* J, l( l$ O. P5 l9 I
{
# F/ C; \4 e- x* Y, K write_date('!');write_date('R');write_date('O');
S8 \. B/ o" ]+ A/ ]4 c8 l3 ~ write_date('R');write_date('R');write_date('E');
% A/ b. _+ e$ L/ E* P* F# t H }+ i& ]4 [4 t- ?- b) M3 R2 l
}
, ]3 z( k" o/ y6 G2 Q# O8 x9 e } break;8 K% f2 |2 D. p$ c C/ x
case 15:{write_date(0x30+table1[num]);flag=1;fuhao=1;} break; //加键 设置加标志fuhao=1;
6 A6 q5 \- {% a. u2 m* a }
# F, p7 a' w! q# w% T }//P2!=0xf7% V' t( s6 |/ N% y
}. s5 H8 |! P+ b! b* U/ l1 K/ o7 s! H
& n7 V$ \2 N2 m
; \. x' Q7 b+ V& M) k! h5 dmain()( i4 k6 n& O) c% k7 Q7 P4 ?
{8 M5 e- j! e3 d1 R- E
init(); //系统初始化4 ~2 F2 Y6 b( Z0 O$ e+ m/ r: T
while(1)
- r9 i7 p0 a W3 W {
( U/ h1 O4 H A- b% T keyscan();//键扫描0 Q4 x V! x5 P5 a; I6 a
}
4 f! ?" H/ r7 x) r}
; W$ ]) C0 g& c5 k9 R$ e& U- l8 C# F* i7 A1 ?+ s( I
3 H2 \# O; @& v. o! N" J2 X( k9 c: b
/ ?& n% C8 Q' a9 ]
下载:
' m) h; L/ B% F2 l. o6 V* n6 c9 t: A
3 q7 ^$ k7 @ }6 c D* n |
|