|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
单片机计算器设计 内附原理图和PCB 程序 仿真
3 I) L% i" b2 V; h+ r: w& P% q; k* R3 o/ ^" W
1 P+ v9 O- _1 P/ W( X, O
下面是计算器的proteus仿真原理图:
( ^/ `+ m e' g! e) h& }; i4 F
& z9 `1 q% p3 U: j
0 t. V' J; u* P7 Y7 Q% h
单片机做的计算器的ad画的原理图:
/ |$ o# K" P0 ^; Z8 e% ? $ \, G1 g4 v( l! p# I1 h0 a" c' w
% R' v6 P+ f! q# g: D( V, N单片机计算器的pcb:
$ K& j% [7 r6 r
) Z% O; C5 z6 m4 e- h! O4 R2 d" Y ^ L4 n/ O9 `& Q& y
计算器的单片机源程序:
( S1 q# ]* ^+ H8 f* h3 i#include //头文件0 }5 H+ U# ^3 f4 f
#define uint unsigned int , J5 N$ k# d3 q! Q, c
#define uchar unsigned char
! Z7 z9 U& A s
- G' m% I& h% Q) R# ~0 B& M9 T% W- P- s! }, s- G
sbit lcden=P1^1; //LCD1602控制引脚% k) Z; p/ T6 V: Q) [/ ~
sbit rs=P1^0;' K/ t2 Y# i0 w, S: c
sbit rw=P1^2;& n) s0 @/ r L( _5 S- C
sbit busy=P0^7;//LCD忙! k+ y: v2 ^7 J# J5 U
/ P$ Q) {) [. {" o+ o) _: Z! z- J5 _& P, a8 _5 h; ~
char i,j,temp,num,num_1;
?/ ?8 g9 T$ r9 J1 {long a,b,c; //a,第一个数 b,第二个数 c,得数( C% R. i, ^6 q8 D% Q
float a_c,b_c;) G0 L! y1 ]$ |( Y2 ^
uchar flag,fuhao;//flag表示是否有运算符键按下,fuhao表征按下的是哪个运算符
6 b3 P) N' A7 P/ \$ L//flag=1表示运算符键按下,flag=0表示运算符键没有按下;
7 a% V& K9 u. I2 a, ^- q' x//fuhao=1为加法,fuhao=2为减法,fuhao=3为乘法,fuhao=4为除法。
" u- B5 ^2 ^9 w; \8 _4 R; S2 C8 t+ i3 I
$ A4 _! {) ~, l1 k: O) G) `
uchar code table[]={//运算数字输入数组# ~( K+ X1 L& }8 r& g( ?
7,8,9,0,8 h0 `8 ]# C2 ?6 J6 S( s( M( u4 U
4,5,6,0,
! U+ F- v, R' q+ n6 w1,2,3,0,4 B( w% L6 k2 ^% C0 d5 G' l# c
0,0,0,0};" x% K9 o0 r* D- l. G$ g
uchar code table1[]={ //经处理后进行键输入显示准备的数组2 e( K' B6 C+ R+ {8 M7 t7 C
7,8,9,0x2f-0x30, //7,8,9,÷
; _( a9 Y: p! O( d4 ^4,5,6,0x2a-0x30, //4, 5, 6,×
. b- R: W- e% L# Y4 q% W8 e8 B1,2,3,0x2d-0x30, //1, 2, 3,-
1 G; U6 f0 k/ s" q: Q7 g0x01-0x30,0,0x3d-0x30,0x2b-0x30//C,0,=,+5 S# L8 H! \( o* N: |* `
};; G2 K3 d4 c! Q+ u/ J" T% n
void delay(uchar z) // 延迟函数% Z( v- }* e; e1 n% x
{$ I; v0 T# {& d5 C% n2 ?( f3 S
uchar y;& }6 g+ m9 i$ P% \. t
for(z;z>0;z--), y/ _ |# L: J; l
for(y=0;y<110;y++);
5 I0 N7 p2 ^7 }}& o! @, B7 o7 u: x1 i5 c! R& n5 v
void write_com(uchar com) // 写指令函数
: |( z7 d# U6 i% j* c+ k{5 n |1 Q& o/ k; \, b/ M- O
rs=0;. D; Q' _' _% Y' K( M
P0=com; //com指令付给P0口/ g* F: U h& R( i4 k2 E+ ^
delay(5);lcden=1;delay(5); lcden=0;
, Q/ U6 B+ V3 @6 A0 J}5 V, `: M! L0 i6 ~: @
; K2 t( |! F, ]) H- ~# e# y* j7 s/ n
% ~6 i$ @- O7 n6 P& x+ G+ O Ivoid write_date(uchar date) // 写数据函数
2 r9 M( ?4 V+ ^{
% K5 K+ {% I2 r! E: t2 [8 \ rs=1; P0=date; delay(5);
; g/ v6 h9 g$ r7 {2 [2 S8 {4 ?5 p lcden=1; delay(5); lcden=0;6 u% J. M k. ?% E) M
}
- |# E$ R6 C& o0 Q( R/ V& |. y
, d$ G6 L3 d2 \* ?( Y, u; a6 B9 w* q9 q# |. v( S6 r
void init() //初始化( |! Z7 _7 G1 L* i4 _9 e8 b, X1 Z
{
# u$ h% @& i5 F! c5 l+ K num=-1; h! w: \" D- C& R
lcden=1; //使能信号为高电平/ w! f+ q; r3 _) }3 N9 l% d
rw=0;7 n: Y) x( z9 e
write_com(0x38); //8位,2行
0 ?* f/ U, K5 ^. @$ Z1 k, o; udelay(5); write_com(0x38); //8位,2行7 H) S+ a4 {0 g, R. v+ z1 V6 ~) c; T1 H3 ]
delay(5); write_com(0x0c); //显示开,光标关,不闪烁*/
! Y- g z( S6 }$ G! l4 zdelay(1); write_com(0x06); //增量方式不移位 显竟獗暌贫 柚?/ f6 Q" e9 r) {$ e0 i
delay(1); write_com(0x80); //检测忙信号
9 _: X- s% g6 Q2 }' q2 Udelay(1); write_com(0x01); //显示开,光标关,不闪烁
]* ?- \) Y$ J* p4 }; M9 G" k0 gnum_1=0;! s. c" m* [! R5 h5 ~$ b
i=0; j=0;
; [8 j; ? F! { C$ i% ~a=0; //第一个参与运算的数
+ P% R& }+ v* W% [b=0; //第二个参与运算的数6 u' z% Z4 I1 @; f1 p# s
c=0;! x7 P5 P, ? E2 e2 s8 _0 D
flag=0; //flag表示是否有符号键按下, ' G9 A, K8 ]5 q# {6 \$ l
fuhao=0; // fuhao表征按下的是哪个符号
1 V' S) }* `1 `+ X, a j}
1 D" ` r- _( ]0 ?1 w, a) \void keyscan() // 键盘扫描程序% `8 m: [+ o8 n( ^9 U9 `% ?
{7 b7 _ \! }' U. M( q& j8 @0 ~" `
P2=0xfe; 7 B' Z. |- ~, n0 M
if(P2!=0xfe)
! j( v) p% \& F/ p9 y' m) v# P3 c {
% q$ D; v3 J* ]* J; w( M delay(20);// 延迟20ms7 ^+ ~2 b' E) w% q+ Z& x/ v
if(P2!=0xfe) { temp=P2&0xf0;; r7 H& e8 F! ?
switch(temp)( B ]$ B% E2 ]
{1 E, B! E* }7 G5 t5 X) x( L4 o, q# r! F
case 0xe0:num=0; break; //7
7 H+ ~ m7 z# A6 S3 N B case 0xd0:num=1; break; //8
O( F+ w$ E3 l9 Z case 0xb0:num=2; break; //9# N: P5 ?4 ^# S: a
case 0x70:num=3; break; //÷1 Q) c) a, @1 R1 m1 E7 q' ?, l- s, _
}
" w) Q- z& e+ p } while(P2!=0xfe);
% }. f7 k+ U: ?# j5 |# g if(num==0||num==1||num==2)//如果按下的是'7','8'或'9
$ Y: |. P: w3 R+ Q+ f b { 5 }& K% }3 f+ G3 s% ?/ T7 f6 C
if(j!=0){write_com(0x01); j=0; }" Z7 _' l, i+ Z& u; r. Y i/ e
if(flag==0)//没有按过运算符键
4 |1 @: k# h5 S( ?. B; E { a=a*10+table[num]; } //按下数字存储到a
5 s, w1 _; y8 n$ n, O else//如果按过运算符键4 `# h2 S( B6 Q3 S" s( ?0 h
{ b=b*10+table[num]; }//按下数字存储到b
' F2 R1 q" o1 l4 g/ C" C }
/ C1 i5 |- ]* G% s else//如果按下的是'/' 除法
. z! k! x5 m) |3 u4 D/ M {
# M, K; Z- j8 O flag=1; //按下运算符* l) o/ _' `8 q) J+ L5 ~
fuhao=4;//4表示除号已按& J" ?# o" U' w" F3 `
}+ ~* o d" A t$ J
i=table1[num]; //数据显示做准备
; ]9 }8 E9 v; Y+ h" B write_date(0x30+i);//显示数据或操作符号+ h, ~+ |7 z+ N: @. G$ _4 H0 }
}; {$ d9 F% e) X+ U
$ r" n4 l/ B4 M) C, O! L3 o
$ U+ b: }4 D$ A- {- ~3 Q) ~$ i P2=0xfd;6 H& Z; l6 s3 I- i9 Q4 G: i
if(P2!=0xfd)) v: c, G4 F$ e7 Y- j
{
6 k2 p1 I) S& U4 u: f delay(20);
/ p9 h1 J- [( Y3 u& U) Z if(P2!=0xfd){ temp=P2&0xf0;& q: ]4 P+ n$ J' e8 K
switch(temp)* J9 U8 y% U9 T
{
- W4 n) f. k3 D" h8 V+ e* l case 0xe0:num=4; break; //4: Y# {; h: f$ k" L% F; a
case 0xd0:num=5; break; //5& C$ C8 g: n: X
case 0xb0:num=6; break; //6# Y8 I& i6 Q- Y# c1 |7 Z
case 0x70:num=7; break; //×
3 G& S' c7 T& \% I" _. ?, R }
! ~+ @- b8 t Q+ i- B4 L2 @# g } while(P2!=0xfd);//等待按键释放
9 U! U# t8 e7 X/ S if(num==4||num==5||num==6&&num!=7)//如果按下的是'4','5'或'6'
8 N3 P- d" Z! ?, r { , ~0 s2 V4 Z% Y! [" U |& l$ ^
if(j!=0){ write_com(0x01); j=0; }7 \" M" d8 A4 M3 E
if(flag==0)//没有按过运算符键
2 H. A8 b. _% ^- }- ] { a=a*10+table[num]; }: [! g" o: n8 g; S
else//如果按过运算符键& K: H5 h0 X6 f! D. B" d6 `
{ b=b*10+table[num]; }: `/ y+ ~) @1 O8 w4 R
}
; K, l% P+ h( O3 S$ M else//如果按下的是'×'; j. h) O0 R& i) U6 f
{ flag=1;8 F' J- g7 S7 V
fuhao=3;//3表示乘号已按4 x9 \4 i+ O+ x
}
U1 k! }, N' S i=table1[num]; //数据显示做准备. k( C) A! o0 y w
write_date(0x30+i);//显示数据或操作符号# L, I# a: r, b1 |. H5 ~% K
}
4 s! |5 r1 E7 o* M. c9 |
1 z% ?% f8 ?' a7 z) \# R/ |
6 y7 [( C+ U# e- u- c. C P2=0xfb;
6 `1 B: k3 c3 O, v# b if(P2!=0xfb){ delay(20);
# z+ a+ |; I7 h1 U: b+ Q$ u9 j0 ^% C if(P2!=0xfb) { temp=P2&0xf0;
1 H) A* m4 ^- p" _1 T switch(temp)
t) G6 Z+ Y+ y. V. ^ {- J! V$ ^: G8 g9 _6 F- ^
case 0xe0:num=8; break; //1
+ e5 Q% j" P0 F* I2 t* F" n" O case 0xd0:num=9; break; //2* ^( J$ [& F1 m- H2 W
case 0xb0:num=10; break; //3: ^7 G, \+ C+ Q% S! U' L& Y- L
case 0x70:num=11; break; //-
, N( {6 N/ ?. a$ O' K: B7 Z" O }& m/ j& x4 R% m
} while(P2!=0xfb);5 S# l; }6 a- o5 `" b( W. G1 X6 c
if(num==8||num==9||num==10)//如果按下的是'1','2'或'3'
& ~' v; K0 D* \) _) h { 3 W7 y3 e; r( b) F& [% z
if(j!=0){ write_com(0x01); j=0; }
9 p0 r- A7 |. b. |) W if(flag==0)//没有按过运算符键' C$ N5 o- u/ _' z. s% G
{ a=a*10+table[num]; }# Y9 J5 X' x9 o8 y
else//如果按过运算符键
/ i; y) l. {7 l1 e9 j! x { b=b*10+table[num]; }
N0 h5 I+ P! `* a" U" \% n }
9 R! P, R) Z1 e& f1 w( v2 n! c else if(num==11)//如果按下的是'-'
4 B' _( }4 l. V8 J! v8 |' L9 j {4 O) @* ]9 R/ n3 _6 @2 S0 i# i$ Y
flag=1;
+ S7 N f) v6 W' D [3 `$ { fuhao=2;//2表示减号已按
j h; }4 B# o5 |0 a" h p5 U8 R }3 v/ |5 j& N' o, g, `- B: ^8 e4 p
i=table1[num]; //数据显示做准备, H+ D6 [8 V' s; B' R
write_date(0x30+i);//显示数据或操作符号5 j# |+ ~* l# P1 e- Z) p w" E3 O' N
}1 K. u! ~9 [" C5 I8 H$ d
0 d* W3 b3 D. ]# a$ P1 L' a3 M/ Q4 K' b
P2=0xf7;
8 ^+ m" F* I: z6 f! z0 M7 t! R3 @' U if(P2!=0xf7){ delay(20);
0 a7 z7 n# l& d if(P2!=0xf7){ temp=P2&0xf0;2 S5 a+ y& ^5 E. {2 h; u' V, _
switch(temp)
1 f# D& n$ e* W. m/ [. v+ l {
8 g @# {3 s5 g2 h n/ G case 0xe0:num=12; break; //清0键 6 ?7 i0 |* y; Q$ B1 P
case 0xd0:num=13; break; //数字0 & o1 t: f- W+ V7 h1 U& ?
case 0xb0:num=14; break; //等于键 ' i' X" b) o4 d3 g; W# ^$ B1 O9 Y
case 0x70:num=15; break; //加
; [0 P! i0 `9 i; u } " z2 d; p' e; A' l6 A
} while(P2!=0xf7);
% N' Z. [: H. k7 U$ e$ h" G. r0 Q5 l; ]( H" l
8 d: G& S8 Z, ]6 Q: ~ switch(num)
+ l ]( P3 ]% X, s+ h {+ t4 L& X* r4 V: j/ j
case 12:{write_com(0x01);a=0;b=0;flag=0;fuhao=0;}//按下的是"清零"
! r) z! j" e2 b9 f break;7 J3 k- y3 r( k) I) F0 w
case 13:{ //按下的是"0"
' Y1 y0 V/ l6 {1 g if(flag==0)//没有按过运算符键( ^8 |' E1 m! G2 D! D; f7 Y8 @
{ a=a*10; write_date(0x30); P2=0; }& ?, }0 u& Q' h. r0 a! [
else if(flag>=1)//如果按过运算符键8 g5 o# B7 a- L
{ b=b*10; write_date(0x30); } A% m) @0 X1 ^* o
} break;
, @3 h# m/ C4 c- ?7 w3 U, Y* V case 14:{j=1; //按下等于键,根据运算符号进行不同的算术处理% C9 K& D( j4 I* R( c% C
if(fuhao==1) //加法运算
_+ o9 j: ?+ M8 m6 S8 |' v" _ {; L8 e# E( o: m$ a9 Z
write_com(0x80+0x4f);//按下等于键,光标前进至第二行最后一个显示处
1 X9 t7 F; o% e6 }) d( U write_com(0x04); //设置从后住前写数据,每写完一个数据,光标后退一格 ! M7 `$ V' ^; Z1 p3 `4 N
c=a+b;1 k! [0 d% I8 R& e
while(c!=0){write_date(0x30+c%10); c=c/10; } 4 N1 Z- n) D0 J& O/ }
write_date(0x3d); //再写"="
# `# B0 x1 f1 { a=0;b=0;flag=0;fuhao=0;
3 j- Z' v* m: J" `" @+ ]* P* S+ q }
1 ~# ^0 ]3 ?( Z" w else if(fuhao==2) //减法运算
2 ~' w" G) D% y% \% F {% w) w. G1 p9 `) C4 V
write_com(0x80+0x4f);//光标前进至第二行最后一个显示处: Q, n1 m1 t* L0 T) m6 k7 S
write_com(0x04); //设置从后住前写数据,每写完一个数据,光标后退一格(这个照理说顺序不对,可显示和上段一样)
& Q/ |8 Z1 A( |* u7 p2 C- f if(a-b>0) c=a-b;
7 x( s0 @7 Q) b3 d else c=b-a;
4 v# N6 b! E8 c" M' \( Z' _ while(c!=0) { write_date(0x30+c%10);c=c/10; } 7 u% L" c1 _# N* P K
if(a-b<0) write_date(0x2d);/ j% ~6 c5 X0 l" w4 x
write_date(0x3d); //再写"=" / m4 E" O, r8 R4 V% k; _
a=0;b=0;flag=0;fuhao=0;
3 Q6 c( o: b1 o O. a' d/ s" b }
% D1 R8 v- a( ^* P else if(fuhao==3) //乘法运算
9 i7 P7 G! k% D% x6 E) P* b {write_com(0x80+0x4f); write_com(0x04);
& i# i8 @; s* t" p% Q1 z9 C6 B c=a*b; Y. R! B3 v" T5 {+ |$ }' u( d
while(c!=0) {write_date(0x30+c%10); c=c/10; }
3 m" o& ~. a. s2 S+ H write_date(0x3d); a=0;b=0;flag=0;fuhao=0;
" y# [ [' F* ^' g5 R! I }
* L) ?9 o7 ~6 Z" m; K: o8 L2 d else if(fuhao==4)//除法运算
3 ^+ y3 Z! X( q+ a2 E% L+ O {write_com(0x80+0x4f);! `4 p% Z& N- ]8 P, H. q1 L V
write_com(0x04);$ S2 x; d, _; g! [. j4 h) J
i=0;
; K$ v; |& u- n4 i if(b!=0)
4 e/ k( g) q) N7 w {4 K, \8 p) _, T
c=(long)(((float)a/b)*1000);9 B/ ~4 q- p* G+ Z
while(c!=0)
! p3 O0 J$ j( D6 A" p3 Q7 { { 7 U* X4 ?$ G5 k: g" [' I& u
write_date(0x30+c%10);
- x. L3 }$ R( p4 W c=c/10;
' l7 m' Y5 ~, X2 l& z i++; if(i==3) write_date(0x2e);, m i9 J7 r* O* `6 ^" t2 x
}
" `5 C1 ^ |8 y6 U# A! C2 J if(a/b<=0)
6 A4 N5 G7 D& ^% S {8 }5 P3 P( Z) m s
if(i<=2)' ?4 f! k. r0 P. i& f
{ ; t& w# Y$ R5 k- N, H3 [/ A
7 Z# F& Z* \2 n7 G
if(i==1) write_date(0x30);; I' @* m J# ]
write_date(0x2e); // .
& G" \ Y! w2 b6 @ write_date(0x30);
% z/ ^/ ]8 C8 W- Q' D& t2 i }
8 U1 e2 l) F1 x0 |; D1 B& D: Q0 X4 U F % k( Y6 I3 v$ I3 z$ W* K. X. |
write_date(0x30); //
5 s& w. {, z4 _! V- t) C }
9 R0 Q* ^$ M/ Z% w write_date(0x3d); ) D9 P2 T8 D4 m6 O& o# Y/ n
a=0;b=0;flag=0;fuhao=0;
7 p& p; C8 |, ^$ `# H }
; y! o" H5 }% [ else7 J1 U6 h. ^4 W+ }% D
{
7 J; n3 l+ q `, W$ l- F) x9 u6 J write_date('!');write_date('R');write_date('O');
& N2 G: }; S1 M% W( | write_date('R');write_date('R');write_date('E');4 y& Z+ z% q0 Z1 X/ a, z6 B2 `( s
}
' G w2 x( W5 \: G0 n }- w% ]7 i0 N( \3 P$ ~: L! v) x& q
} break;
; b) O8 U* r$ W$ N( r ` case 15:{write_date(0x30+table1[num]);flag=1;fuhao=1;} break; //加键 设置加标志fuhao=1;* W4 U- j- w! R7 ]6 G0 G8 I
}
5 {+ C% g5 O. L }//P2!=0xf7
$ P, V, P; Y# f* G}8 r* I& w/ q! R% L! f+ i
5 ?! s+ k; |- t6 w! U2 d5 L3 u2 e. K
main()5 J1 ]' v9 A# W+ f+ x3 h' ?
{ x' s& e! O: d. d* v' T8 Z
init(); //系统初始化8 e! @ N4 E% @ ?+ W
while(1)
% x! k0 e2 V3 x L. Z( v {
r( C% d- g) y# V& V keyscan();//键扫描
0 G. Z' @: C0 J, c4 H }( l- ^# j8 o; O1 {3 V8 E. v q
}8 |# U' l- ^( O3 _7 i! t9 ~' }% V
$ {/ A. q. Z4 q6 w0 t7 C M. P f0 n. X1 Z% a
1 A2 o7 \6 Y" u# j5 r3 N0 M0 h3 n5 m8 I5 q
下载:
& r0 z- b6 b! w& d
T5 w8 u% Y4 R$ @' L1 n( W1 e3 k v* h* @( @& r
|
|