|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
单片机计算器设计 内附原理图和PCB 程序 仿真
( q$ N, Q N% s& g8 [/ w1 m8 t3 n+ `
/ k) m# A1 e4 P" g! M R& n下面是计算器的proteus仿真原理图:
# k' D% |" `1 ?0 i l' ?
$ D5 {) H* @# r/ {0 g R
! R4 S/ ^2 v& }; K单片机做的计算器的ad画的原理图:
2 Y7 u# o1 m- ^* T4 _- V X4 \3 B5 v' z& c4 ?) c
9 ^5 {4 l, i% }0 P7 D m单片机计算器的pcb:
" l7 W0 Z; j) }: @* X
; \( B/ A/ y& x% i( g0 T4 r
U4 e0 J/ u1 U3 P+ N/ D2 C1 ?计算器的单片机源程序:
9 E9 |9 h/ N- q# v#include //头文件
/ p# Q9 O' i0 V& ~#define uint unsigned int 5 k0 Q3 V% d r- B: Q3 W
#define uchar unsigned char w; |% b- |9 V& G+ ?4 f) I
& e( \6 v" B9 O# E* @6 Z/ \
# u, P/ ~% ~7 { |# @% {sbit lcden=P1^1; //LCD1602控制引脚
" l1 |& P+ T/ p% ^2 w2 A/ Qsbit rs=P1^0;
, ~' u$ K5 @) a. w' C }sbit rw=P1^2;( C9 q* T7 L. X1 w6 p. t
sbit busy=P0^7;//LCD忙
% n; k& }% V& ~3 m/ S) k$ X
$ I3 v' Z3 s- {: C& u/ \
3 ~, H6 O2 X$ X/ d# l) Uchar i,j,temp,num,num_1;( Q+ F/ u2 C! R6 {: l6 H8 n
long a,b,c; //a,第一个数 b,第二个数 c,得数4 r v& |8 V7 y$ r
float a_c,b_c;
0 v* U+ s# U, l- U9 A/ puchar flag,fuhao;//flag表示是否有运算符键按下,fuhao表征按下的是哪个运算符# Y0 \# A5 m1 a$ D
//flag=1表示运算符键按下,flag=0表示运算符键没有按下;. b$ R& h) [: ]) @2 E1 c9 d/ J' c
//fuhao=1为加法,fuhao=2为减法,fuhao=3为乘法,fuhao=4为除法。) g* A& q% q& w. [# _' N
5 e- H! e; G% ]+ m
- a* P+ O$ x9 R
uchar code table[]={//运算数字输入数组
: J- W, ^: ?& p# C$ ]/ W7,8,9,0,) L- m& a* \+ l% e2 N2 F/ L8 G
4,5,6,0," ~+ d7 }6 ]4 ]9 H- O5 C
1,2,3,0,3 o( w# N* j2 S1 u% ]
0,0,0,0};( k3 F3 G d2 a/ s# _# W
uchar code table1[]={ //经处理后进行键输入显示准备的数组
' }! @! r+ y- w, C: g7 d7,8,9,0x2f-0x30, //7,8,9,÷
* Z+ Z/ z3 l$ p* P7 c, m, W$ ^+ s4,5,6,0x2a-0x30, //4, 5, 6,×1 j9 K6 \5 T, e) E& R3 J
1,2,3,0x2d-0x30, //1, 2, 3,- Z8 n( E4 Z0 h$ y) }% _$ @# Y
0x01-0x30,0,0x3d-0x30,0x2b-0x30//C,0,=,+% V* S. A$ X6 j, c0 Q7 m9 X
};
$ O1 ]$ c! ]& S6 Gvoid delay(uchar z) // 延迟函数
7 r6 h0 L3 D) J5 v5 B) e4 s{! ~& n1 f$ f2 o2 k' `. K
uchar y;
. u6 o0 n: D) l5 [5 efor(z;z>0;z--)
! S n! F* v0 b( @ for(y=0;y<110;y++);
, A& u5 u6 Z2 b}2 r# ]9 G9 Z6 _7 m9 t, I; u
void write_com(uchar com) // 写指令函数
/ J! z# F4 W- y5 b5 r4 z& v5 D+ V{
! r s7 w, O- G) |/ b7 {: b rs=0;
- a q3 B8 W1 b. k! C P0=com; //com指令付给P0口 @- H0 Q' r3 F U( x3 c( b. a
delay(5);lcden=1;delay(5); lcden=0;' b) K6 K9 f4 E7 c
}! ]8 v# W$ K, v( g" }& S& N% z0 q, W
4 e; {8 T6 n4 C
: X2 [ h. _) t+ |3 e
void write_date(uchar date) // 写数据函数
" t: e! Q+ R. f. s{
2 G T9 P3 w, ~) W+ d9 a/ B rs=1; P0=date; delay(5);! w9 Z% G% n! m$ ]+ g
lcden=1; delay(5); lcden=0;3 B) X2 I2 j" W" L7 M5 D' [/ W
}
6 V) s- G* H: |4 N9 m( g& O& B
( P9 q; l6 y$ z8 d; g# v
+ R% k( r4 p9 O0 W% j+ b, ]void init() //初始化) ^" F% X* l7 x. j9 H! n
{: \8 }8 P f N! z% |
num=-1;
$ C- k9 I3 t' \- g9 e# Alcden=1; //使能信号为高电平0 C) Z4 G* V. C" S
rw=0;( p, U2 S3 }5 f u
write_com(0x38); //8位,2行( ^( a" H8 C! S. d$ Z [$ n- m* P) M
delay(5); write_com(0x38); //8位,2行5 F% h, [" s4 C1 H0 M" f; U/ Q
delay(5); write_com(0x0c); //显示开,光标关,不闪烁*/' O7 p( x8 @$ H/ ]. t @! P
delay(1); write_com(0x06); //增量方式不移位 显竟獗暌贫 柚?- O' Y" {; g* ^: o' I# g
delay(1); write_com(0x80); //检测忙信号 b* N& ]3 n3 d( c/ o
delay(1); write_com(0x01); //显示开,光标关,不闪烁
0 w) _4 L5 s' B# V0 Z- b Fnum_1=0;
# |6 `& E6 `, J0 u; K" X9 ^i=0; j=0;
+ u" g" e8 w1 S6 G4 O& na=0; //第一个参与运算的数9 M. @4 P4 [5 R/ N8 P( N- p/ I
b=0; //第二个参与运算的数
) V+ g, O" }/ |3 N3 N: y# \7 H9 Jc=0;: I$ |/ A7 c! `0 J! J7 Q/ V# b4 \( S. M
flag=0; //flag表示是否有符号键按下, 2 a% f! p2 c4 K# y# b, x. \+ d
fuhao=0; // fuhao表征按下的是哪个符号
8 ~- i x/ J2 q# v( _9 [) _) s}7 r9 `& D7 @ U: z' l# E
void keyscan() // 键盘扫描程序3 H( O* ?! |0 O) f( Z3 I
{
- P0 Z4 I, S4 J6 l P2=0xfe; $ q, x: {8 \7 k& g# W9 ^1 J6 k
if(P2!=0xfe)
. F- U' L5 M+ D- i" ^6 t' n( c9 y {
& t( @% I8 V. E, U/ O' i delay(20);// 延迟20ms
) p7 V3 R8 Y" v; u K% A" R) H% M if(P2!=0xfe) { temp=P2&0xf0;
# L( i0 ^4 Y( }& c( R/ q& f2 J8 P1 r switch(temp)) { y. W1 U; i4 c0 D
{
9 h% O: M. E$ P) u! Z! k case 0xe0:num=0; break; //7
7 U2 u* s6 S4 Z- e% F7 S& w case 0xd0:num=1; break; //8, B' \! c- H- ]! [1 N
case 0xb0:num=2; break; //9
* W2 ~( S7 \9 T6 [# w case 0x70:num=3; break; //÷
% Q. b, l: i! T }% U1 l& v+ K2 T2 V
} while(P2!=0xfe);
; s! N" _: u" k/ F J' f% f5 ^ if(num==0||num==1||num==2)//如果按下的是'7','8'或'9
: {3 X3 s6 G1 u' `& b1 w { . r: ~) p* g7 }: k G$ G7 F& c& ~
if(j!=0){write_com(0x01); j=0; }. ^; b- b0 k$ K) |$ O
if(flag==0)//没有按过运算符键
7 p/ b$ V2 N; ~1 y$ T8 S k { a=a*10+table[num]; } //按下数字存储到a2 D; w8 D/ G; k: R( }
else//如果按过运算符键. v& k& d8 C2 T4 ~, {/ B
{ b=b*10+table[num]; }//按下数字存储到b
, m# y: ?/ x7 f. T: L9 i2 e }# F3 i3 v3 N4 o. r) x
else//如果按下的是'/' 除法, \. k" Q; U! I1 }. E
{
, h9 P' M8 `. q9 x' N! L$ \" v flag=1; //按下运算符
% H& y" c2 i$ q' C3 }$ v7 V5 r U fuhao=4;//4表示除号已按- ? u4 h$ l( ^
}6 B3 {3 N* a1 u0 U
i=table1[num]; //数据显示做准备1 b! d. H) [+ O# c9 P
write_date(0x30+i);//显示数据或操作符号
?7 \9 t) ]! A" y, d& u/ [ }
* b% c% ^7 P+ T% U; N' W' J! A/ Z, @% G# @( M# S4 U" {9 ~
1 j+ q6 d$ C; _) z# C9 m
P2=0xfd;9 |5 a. N- Y v% f% a5 j. O/ g9 V
if(P2!=0xfd)
& H2 d) F& I/ L {0 [1 ?7 `. R. C5 u* E
delay(20);4 ], n: w2 y) `
if(P2!=0xfd){ temp=P2&0xf0;
. e. P, z2 a5 {! I- ? switch(temp)
% Q2 u' I' @) j) E4 t& N, N; y {
$ a4 O6 C2 I, n5 P: I- V! m case 0xe0:num=4; break; //4
; b+ U P' n$ w. s" C6 v case 0xd0:num=5; break; //5
1 {9 f( K9 p3 D$ X0 ^ case 0xb0:num=6; break; //61 v, e! D" u) H- A$ G
case 0x70:num=7; break; //×6 m9 e3 Z7 V4 B/ M f% r) P" T8 P
}0 i6 s6 w/ B* y6 F3 Z3 F& u" ]
} while(P2!=0xfd);//等待按键释放! f) ^+ b. {1 K* L7 I3 h
if(num==4||num==5||num==6&&num!=7)//如果按下的是'4','5'或'6'5 D* \( \: t* q: _1 F
{
X7 |3 `- }' K if(j!=0){ write_com(0x01); j=0; }
( X& f- s( |/ s if(flag==0)//没有按过运算符键
; O- o' j" D5 H { a=a*10+table[num]; }/ ^) _/ y8 T4 d
else//如果按过运算符键
. ]* R1 a& H; I* y0 e { b=b*10+table[num]; }
1 d. H* t2 ] V4 K }0 A% p. Y; U5 ~9 l) K% s8 {
else//如果按下的是'×'" h2 \! i& z* i6 w; O) T0 Z: ]
{ flag=1;
% D) O2 l" R; i7 {0 e fuhao=3;//3表示乘号已按
& A. u5 }5 a- A0 l( m A* @: n* L+ n }
/ [0 ~$ m* A& j6 _" T i=table1[num]; //数据显示做准备8 c( t( }# t# S8 M$ Y/ k0 Q' v8 m# Q
write_date(0x30+i);//显示数据或操作符号1 D& T" O+ \4 Q$ U& y3 s- f! S1 ~6 n
}
; N p/ F! ^6 S# y- E9 P) d9 m$ ?8 L' }$ y
% s; t6 a% [+ v: G2 p P2=0xfb;9 t/ Q7 d0 j1 U
if(P2!=0xfb){ delay(20);) w6 V$ W! L1 g$ P# X
if(P2!=0xfb) { temp=P2&0xf0;
, I6 o. I' K h" |4 b, U switch(temp)3 a+ M* f: a5 V% ?
{! J- ?6 e( n! [# G* i
case 0xe0:num=8; break; //1
# C1 d, v) o; `% @8 g& S1 G, [ case 0xd0:num=9; break; //2
" R5 g* p$ }; t0 V9 J/ G case 0xb0:num=10; break; //3
! E/ x6 b) N) \- X$ [/ b case 0x70:num=11; break; //-1 A" B3 X4 n1 s2 V3 A& L3 Q/ S
}) S) F* F0 r/ D1 T4 N: R
} while(P2!=0xfb);2 h+ P1 H) k! H4 P9 c7 \3 ~
if(num==8||num==9||num==10)//如果按下的是'1','2'或'3'; R* F1 s' J* c- T% a2 \
{
6 w+ _) W0 `! H8 V6 i3 ^ if(j!=0){ write_com(0x01); j=0; }
! V. W. s( w7 o- W$ v9 a, o if(flag==0)//没有按过运算符键
$ P7 Z# o& C7 y+ ~1 G T- `) U! s1 n { a=a*10+table[num]; }6 h' E( i9 o* }% L1 C
else//如果按过运算符键. e# b* E) Y9 D
{ b=b*10+table[num]; }
0 { P: }/ m, R6 d! V1 k( P }* ~' X. G Z; }
else if(num==11)//如果按下的是'-'
+ z) w3 `/ h6 B# c8 [3 f8 l9 r: \ {
6 @" w3 K- p e2 [: s' ?, o flag=1;
5 b; v3 B0 k+ [( f2 k fuhao=2;//2表示减号已按; \' A6 r( T2 }- b
}
8 G+ k6 [% g, X; P0 ]6 @% c. o i=table1[num]; //数据显示做准备
K5 L+ K8 F+ R+ y write_date(0x30+i);//显示数据或操作符号, {/ i- o! v! F5 k! b
}
' [4 v0 [ ^% ? k k/ f
$ g; s9 U: U& `- C X# I
1 x* v6 }7 c" U0 ~& T) ?2 z" ?) c P2=0xf7;
/ `; N" X" a. I if(P2!=0xf7){ delay(20);! \/ V6 o1 k! e& Y7 K4 ~
if(P2!=0xf7){ temp=P2&0xf0;
3 @; {7 U4 q8 L7 z switch(temp)
@" j( a4 A# M' b' ^ h {
' ~7 p! p% L7 R case 0xe0:num=12; break; //清0键
/ J* q4 P) i" H! d" o case 0xd0:num=13; break; //数字0
8 P+ O. U+ x& I+ K4 G% K3 M case 0xb0:num=14; break; //等于键 ; c" L4 y x8 Q: {* X' y
case 0x70:num=15; break; //加7 r2 j/ r/ Z0 l) r
}
4 c5 N, J R5 j6 n3 e9 x } while(P2!=0xf7);. q& b% @/ t# Y7 w, {6 e
( `! a( p- n- O8 s
3 A. j$ c' i9 ]7 p- ^ switch(num)2 G0 b' |/ }4 e* G) y+ F
{7 {4 b! l2 s" ]. V- _
case 12:{write_com(0x01);a=0;b=0;flag=0;fuhao=0;}//按下的是"清零"
* a0 t9 t3 Q8 @' w break;
7 V. A1 ]+ ?9 I1 j case 13:{ //按下的是"0") _, B. L" w: g0 I& |1 T
if(flag==0)//没有按过运算符键; S. U9 h8 Y( e m2 ^
{ a=a*10; write_date(0x30); P2=0; }3 ~! E% C% C% V- h- M& r+ h
else if(flag>=1)//如果按过运算符键6 @: @! q# N6 N: F0 A+ i. [
{ b=b*10; write_date(0x30); }1 n: B8 s% i8 D2 Q4 \3 K5 f( t2 v
} break;+ M4 m5 E7 |' V5 U# B$ L
case 14:{j=1; //按下等于键,根据运算符号进行不同的算术处理. e- p- s; Y. `+ n
if(fuhao==1) //加法运算: V7 K; Y4 t$ b2 k! r" ?
{ r" ^; x/ {1 O" Q, O/ p1 N
write_com(0x80+0x4f);//按下等于键,光标前进至第二行最后一个显示处 , I$ G; z! Z3 x( |% q
write_com(0x04); //设置从后住前写数据,每写完一个数据,光标后退一格
2 `/ j" E& }* b) i6 m9 S9 F c=a+b;
2 r) Y9 o' V$ d8 F while(c!=0){write_date(0x30+c%10); c=c/10; } % l% Z; s7 W" |# B) d' a- S
write_date(0x3d); //再写"="
/ `& H. C: T" x. A! w a=0;b=0;flag=0;fuhao=0;# ^' H( \4 @" V
}
/ I' S( y: Y. T# z, o else if(fuhao==2) //减法运算
2 m& j) L h& S9 j3 W9 f; P {
3 H/ f5 e/ t: X, [6 F$ y! |6 f: c write_com(0x80+0x4f);//光标前进至第二行最后一个显示处2 j, R- B6 {9 K6 j6 N
write_com(0x04); //设置从后住前写数据,每写完一个数据,光标后退一格(这个照理说顺序不对,可显示和上段一样)3 X' ~: n" y% L; a
if(a-b>0) c=a-b;
+ z/ v. y" R& v }: X else c=b-a;
% _$ J) r0 d V4 J5 E. Q% S while(c!=0) { write_date(0x30+c%10);c=c/10; } 6 [0 c, [: ^2 C. [, W! b
if(a-b<0) write_date(0x2d);
" z- E' R% N u' z/ M write_date(0x3d); //再写"=" 6 d) p, a2 P* l R# z* @. o
a=0;b=0;flag=0;fuhao=0;6 [( ~6 j5 z3 v4 J; [" x4 I+ I
}
6 o$ b* N$ _) q* Z' G) ] else if(fuhao==3) //乘法运算
) v& x5 j P. X {write_com(0x80+0x4f); write_com(0x04);
6 S! ?! o4 b% _% T c=a*b;
+ ?; y% g; b- S4 E2 O* `$ n- f5 H while(c!=0) {write_date(0x30+c%10); c=c/10; }
- C3 R) U5 @' ~& x& W( t write_date(0x3d); a=0;b=0;flag=0;fuhao=0;" G N% q! T7 N$ h' W7 d3 \9 W
}
; q# N( E. f" A$ `+ P else if(fuhao==4)//除法运算 + l! D# A- ~# f
{write_com(0x80+0x4f);
' k! }1 k* V3 T5 y write_com(0x04);; [5 W9 Y z* j0 \4 l
i=0;% c6 q) p' E4 X
if(b!=0)1 @# \) O I! Z* y5 w9 l% o
{. H. r% ^% P' t& j: g
c=(long)(((float)a/b)*1000);
+ F& Q5 y; W9 I) t" q9 E* n while(c!=0)7 ~. K6 H9 u0 L% w( C
{ 3 Z9 s, p3 M: h+ r
write_date(0x30+c%10);3 t/ E8 ?8 I `2 E0 ~
c=c/10;
2 b$ n4 l. R) I) L i++; if(i==3) write_date(0x2e);, Y7 r: {- Y6 q
}
/ l1 C$ P; L- ~, a2 {' K; R! R if(a/b<=0)
6 y! e! M7 F2 Y {4 C: A6 m+ y/ t4 L% y
if(i<=2)
6 t; v; G7 J6 O" Y2 L6 R- A% B { $ m- W1 A: A& w5 Q
/ m& x9 D' ^) z5 ^: u! l
if(i==1) write_date(0x30);$ D3 W3 o( n! P4 U3 o
write_date(0x2e); // .& t( [8 d7 n: Q u* R0 N4 n4 ~
write_date(0x30);
) o6 u& Y- m* X ^8 Q A7 \% l L }
, s( z' p# P) D/ f
0 d a2 w( Z4 g {. T/ t write_date(0x30); //
6 G0 ]6 \" l6 ]& Z5 i }$ z6 K" e! V" ?* n
write_date(0x3d); 5 A; O) ]! ~5 b, S6 _0 q) C
a=0;b=0;flag=0;fuhao=0;
; F# ^1 W) T9 q# p; ^! m: c: c; W }
5 `( P' c$ @' L3 D else0 u3 h) j! s5 m: x$ V
{
8 w' R) _/ V3 A+ j write_date('!');write_date('R');write_date('O');
- R, y* l* p# |! b write_date('R');write_date('R');write_date('E');
7 ~2 Q: }, g: @ R/ G( L }
$ G3 K' H( R6 C( `; n9 O4 j& { }
. q8 c3 v1 u" O, [* j } break;
4 }+ F/ N" c4 r1 _, r6 ] case 15:{write_date(0x30+table1[num]);flag=1;fuhao=1;} break; //加键 设置加标志fuhao=1;! ?# o6 E% g% {0 ^& Q* i; d
}
! _5 z) T' f$ i& w6 a }//P2!=0xf7( @" `1 ], p, ~( R+ n2 q& s
}
) G4 P9 j2 c" F# J6 w. S
7 I6 l1 N7 L' w8 d3 k- P& c
. @: ?) m4 \4 N" Lmain()
. m3 G! P# I7 N{2 L8 C4 f7 w, r8 Y7 }
init(); //系统初始化
6 ^" M3 u7 u, m. R( [ while(1)% x7 D! [% Y3 U4 U T8 E5 E7 J2 O
{# X' D* G0 `& @/ @& }( U
keyscan();//键扫描# ~7 o: y6 T# k0 ]/ b/ Z0 v4 m% N5 f \
}
l' F5 w4 Q) p7 ~1 x+ f}2 B( `! L H" [1 r( Y) R8 p+ ^
2 d9 s3 N+ A: }) ^
- [9 A" z8 |- C1 S
r1 J4 [6 ~- I a/ f8 |8 g
( G+ E1 o9 S( ^4 a8 C. q4 k M( d下载:0 u6 _' ?- O1 n& {
% D @4 \- _2 {3 z( K, ]# s1 D" s0 {, ^8 l% M4 E
|
|