找回密码
 注册
关于网站域名变更的通知
查看: 615|回复: 1
打印 上一主题 下一主题

51单片机加法器的制作

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2019-1-16 06:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
51单片机加法器的制作
, @$ b; t9 E9 I6 n; M0 l- E% I; d$ @2 h5 E% W6 [1 W
2 z: v2 i- M$ c+ M
完成数码管显示,按键相加的要求
( R- J& T' {& h4 w  F: ?此程序的电路图下载:

  d) ]6 V0 V3 J% u
游客,如果您要查看本帖隐藏内容请回复

0 e% R) S0 r6 c, C
! a# \& X' N2 x" Z; f, H9 D
4 w2 F: N" @: i
只需要看数码管部分即可,其他部分可忽略掉. 1 P# p% ^8 f8 v

# A3 x" V4 r5 n8 N" D
代码如下#include<reg52.h>
" u" I- ^- n% h& I0 f, f) I8 l  n6 S0 a9 t! h$ Y0 d' g3 _
) Z8 o' T6 E( T
sbit ADDR0 = P1^0;  o' P6 j, L/ c( E' B
sbit ADDR1 = P1^1;
; V/ h* L3 P8 a' {sbit ADDR2 = P1^2;
8 R' C+ B/ d( q3 b6 Csbit ADDR3 = P1^3;
* D5 ^9 x! S/ }7 |+ \) ysbit ENLED = P1^4;$ c* ~  w9 f6 v7 q# X: t
& p* h# L. i# Z- Q% Z; q+ }

) B/ Q9 L" @  g! osbit KEY_IN_1 = P2^4;6 U9 ]7 ^4 Y$ f2 h* N5 O) }- Y  S" \/ w
sbit KEY_IN_2 = P2^5;
) ~* Y6 m5 ^7 p) csbit KEY_IN_3 = P2^6;1 ~# B. ]8 E3 J5 b  h2 P( U/ X) v8 \5 S# \% n
sbit KEY_IN_4 = P2^7;; {" I* W. p4 O! V9 j3 c) {
sbit KEY_OUT_1 = P2^3;$ S+ A. R+ t+ \8 }- J) ]9 J
sbit KEY_OUT_2 = P2^2;
. Z, F( U" f1 ~9 v+ |' rsbit KEY_OUT_3 = P2^1;" E' y2 _& `4 d0 f) m; t- X: z8 t
sbit KEY_OUT_4 = P2^0;* y2 b3 ]% O2 Z! n% ]
2 Z4 R% c) f4 L5 `
8 Y" ?/ b9 t& a! [4 B* ~: k
unsigned char code LedChar[]={
* Z& B+ \0 `: L8 P$ G        0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,. U" U: Y/ n; T! ]
        0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
7 P9 z! J$ p+ e! w3 }        };
! r. L# Z9 x" B6 N5 k( f  dunsigned char KeySta[4][4] = { 9 F! i) _# f; k" c" m
        {1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}
# [6 n  v6 T- o1 q* ^        };
- O, K! j9 W" |' [3 ^/ H! ?. }1 Gunsigned char LedBuff[6] = {
/ A+ f9 D9 r3 a" q, A' w1 A6 \        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF; y) u2 Q& s# d& h! S2 S' a  }1 }+ I
        };( l- R. t% P6 @
unsigned char code KeyCodeMap[4][4] = { //矩阵按键编号到标准键盘键码的映射表: W/ o. c" F, |4 [
    { 0x31, 0x32, 0x33, 0x26 }, //数字键1、数字键2、数字键3、向上键
  `7 a/ q2 S2 c# I* G    { 0x34, 0x35, 0x36, 0x25 }, //数字键4、数字键5、数字键6、向左键
& e; N# Y( V! K, \: \0 x    { 0x37, 0x38, 0x39, 0x28 }, //数字键7、数字键8、数字键9、向下键& V. ?; A9 ~* {+ J% }& @1 G1 g
    { 0x30, 0x1B, 0x0D, 0x27 }  //数字键0、ESC键、  回车键、 向右键1 f/ N4 X) G- z3 x: B
        };
5 a  E0 d8 @7 F& Lvoid  KeyDriver();9 }3 J0 K0 P2 x' a5 m% D7 A
void main()
; X6 l: r& `9 Z+ n* F" B( F, _{2 q: z8 w: f  P4 l. r" H
    EA = 1;       //使能总中断3 c& o7 n# c9 z+ b/ q& _% V5 m
    ENLED = 0;    //选择数码管进行显示
! B/ h* }' Q0 b& B    ADDR3 = 1;4 q' d+ y+ `# W
    TMOD = 0x01;  //设置T0为模式1
5 D/ h' l6 g5 p  J" C    TH0  = 0xFC;  //为T0赋初值0xFC67,定时1ms
) C7 R* s. P% S. g3 X7 g    TL0  = 0x67;
$ C3 q0 w& Y" H    ET0  = 1;     //使能T0中断9 Y& i6 G: y( k0 O. q* q$ e
    TR0  = 1;     //启动T0
. X3 `0 M1 _, I6 m1 \/ M( A    LedBuff[0] = LedChar[0];  //上电显示08 i5 F- f5 S+ \( _$ L
        9 I) ^  |$ V( H; I) g# C- x6 A
    while (1)
* r0 a; W( ?* x' P    {
2 e" s- |+ ?: R8 \, j6 W        KeyDriver();   //调用按键驱动函数
$ `2 @5 ]4 O7 @( p: k+ }    }
: @( G  V& b' C$ n! }6 H8 `+ J}
8 [0 q4 h* b2 U8 O) u2 Q+ n2 I/ O+ W, q2 v7 b! U- ^0 @

  v& E$ X# z5 U# t. J" xvoid ShowNumber(unsigned long num). S% Q( d$ ]3 X6 `8 g3 X
{; S5 C/ j) h" {  ~: ~+ M" d
        signed char i;
, t0 O7 u' d7 ~        unsigned char buf[6];
! v: j  P1 M# m1 F- J% Y7 R+ f% P0 @6 C! u8 V, T; p
& ~/ b7 Q0 j) u% f
        for(i=0; i<6; i++)  J! p* E$ _9 O
        {  e) N; U: z  W8 e1 J) H
                buf = num % 10;; L: q. r8 W6 f; z; C1 k1 P
                num = num / 10;2 D0 c+ x% X1 N' o* N1 J
        }
' S8 r- \! i" Y- ^3 K% m- B# G$ S% o# k% y; O: M5 F, w
7 }5 J5 g$ m# a2 P6 U3 H
        for(i=5; i>=1; i--)  \\gaoweibuxianshi . e9 @5 x% C+ D8 ~$ ?# B
        {( n* J6 I# {4 U) {- W
                if(buf == 0)4 q, |  N3 K% O8 M. l6 G
                {" q! _3 g9 ~, C
                        LedBuff = 0xFF;
+ k( b8 T1 V$ h                }
' }  T% j3 ~. Z1 k; W                else' ]  i+ _) \  P; }- P
                        break;
* D- O& |$ h8 P        }- n9 n; a1 S/ M
        
9 a1 B9 n7 i% Y7 {! ?- J. w        for(; i>=0; i--) \\
( B# c+ g8 P4 |+ f: F1 M- j        {
5 B9 }' g8 L( |( c1 x( |                LedBuff = LedChar[buf];        
/ M, }4 E4 Q1 }* k* ?        }2 ]7 k3 H8 b5 p4 ?* |

) }8 d; _/ Q! d% l2 A: o6 c

' R' |& j0 H3 V( G; ^- b# U}. h8 v9 n: G. t. f& p! I4 r
void KeyAction(unsigned char keycode)
! A: M6 l, g" K' s) N: {{5 y0 f  L0 J. P' k6 \; j
        static unsigned long result = 0;
2 P3 Z" D% \2 ?! p- ~        static unsigned long addend = 0;
+ @( |: Q/ _# o5 I: f3 @" S$ f        
, D7 x2 h' n+ |# m        if((keycode >= 0x30) &&(keycode <= 0x39))
1 g2 {+ @8 J2 G2 ^5 o8 |/ h" N        {0 D  N. ~+ X) w# r0 H' @0 t% M
                addend = (addend *10) + (keycode - 0x30);   ; O1 M% `  j& p) f
                ShowNumber(addend);
, c5 B( D, P  h        }5 h8 H( _9 y3 \/ a+ {
        
# V" x, C  a& |# E# Z) \1 }- L4 U        else if(keycode == 0x26)1 u; A7 ]' |) _# k
        {4 H/ `# U( k" P& L9 h# g
                result += addend;
8 E7 @/ E3 o* |1 z7 ?, F% G% J1 g                addend = 0;
6 m" O* L2 f) L' a                ShowNumber(result);
1 x( O" K2 [" K$ z% ~" k        }
3 t" b, j+ ?6 J" w! J# I. v        else if(keycode == 0x0D)- V! g% X4 M7 \
        {
5 q: c" H" M, H1 d( Z8 i                result += addend;' c2 b- r1 E3 c, W: J
                addend = 0;
4 Q' b* h- D" u* X% y                ShowNumber(result);2 m! ^2 y0 W9 N  ^/ @4 x
        }
& X+ g/ v4 y" {; |& O. ^8 m: c$ c        else if(keycode == 0x1B)
9 C% Q) M* N, F$ ?4 g8 ~% B        {
+ U" F/ O. _9 R) {* x' T+ U9 v                addend = 0;. @* I6 G4 m9 D8 G
                result = 0;( R" A. s' h& @2 Y
                ShowNumber(addend);         
2 k& ?  d. M. ?1 w' |        }        * k8 i- i; n& f. l' v
         6 c% F- @2 @! {2 P- ~8 a( v+ w# g
}
+ r, ~. A% E, V. \; g  [4 Gvoid  KeyDriver()
# q" U- b! D) P+ \3 t- e& E{- c2 j8 y2 ?9 h0 d
        unsigned char i, j;" K; d. c9 L; `- e5 k
        static        unsigned char backup [4][4] = {
) M. I( o, r4 [* f+ S; K8 Y        {1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}
. T* Q. U/ G$ k4 [$ l3 @% {* }! t        };
; c. z$ l: H+ l8 l4 s0 L0 ]5 Z: g
5 L5 o- v# E3 j& d
& M8 N$ f5 \( R2 [3 e7 V: K/ O
        for(i=0; i<4; i++)
: G& M* A; a3 \                {& H2 T3 ?+ t. n2 R; Q
                        for(j=0; j<4; j++)
) [, u, `4 H5 i$ ^                        {* m3 V8 z$ b; o- `
                                if(backup[j] != KeySta[j])8 R) y/ J3 c' J+ B
                                {: p5 L6 x* h' Z
                                        if(backup[j] == 0)
5 t, S7 l& ~( K. K$ ^% U" {/ a                                        {. B: V* ~$ D* \
                                                KeyAction(KeyCodeMap[j]);
" k* S" @. c8 c8 K2 b                                        }
6 p* V) {' \  ~5 |5 I# F2 [                                        backup[j] = KeySta[j];& d0 _. C7 e- M7 j# ?( B3 M. y, ^
                                }
/ ~. T; _8 l6 K3 d; Z                        }        3 k* L3 }9 R' B+ n" O' E* m
                }2 M6 k* e6 {+ E' Z* g- F  U

" s' b8 b# P& q9 T

8 S9 }; Z, e- n6 R2 h. `        / V( M. d9 }$ [# L
}
* {) f2 `* |1 b, h1 }+ K" n( R- f) C! |/ U% m
+ \$ _+ F  R# i! i
/* 按键扫描函数,需在定时中断中调用,推荐调用间隔1ms */
7 X1 V0 F* Q% ~void KeyScan()! r$ A! d8 d  j# r" @' P4 u, f
{# B: i! r' H: e5 e) x# P, H
    unsigned char i;
! [/ _! V% A! Q* ?3 W* o$ X    static unsigned char keyout = 0;   //矩阵按键扫描输出索引; G7 j/ d1 B& Y- K- Y
    static unsigned char keybuf[4][4] = {  //矩阵按键扫描缓冲区" W* e* q( r/ S; l- T) b
        {0xFF, 0xFF, 0xFF, 0xFF},  {0xFF, 0xFF, 0xFF, 0xFF},! v8 U2 h4 \/ }# e1 b8 S  o
        {0xFF, 0xFF, 0xFF, 0xFF},  {0xFF, 0xFF, 0xFF, 0xFF}
% M3 r) p8 F, n    };
# {; ?* O, E3 P5 N' Z
" Z& {1 d, |! U1 @9 t

* C; A& D0 a9 F/ _; O2 \) j2 m    //将一行的4个按键值移入缓冲区
$ k/ m. O* a8 t$ H3 n    keybuf[keyout][0] = (keybuf[keyout][0] << 1) | KEY_IN_1;
- ~# X+ G3 P4 _# ]; a    keybuf[keyout][1] = (keybuf[keyout][1] << 1) | KEY_IN_2;
/ A* X2 _7 M2 E! N2 w0 \1 f    keybuf[keyout][2] = (keybuf[keyout][2] << 1) | KEY_IN_3;2 ^1 |! W: d! _6 _9 b' k
    keybuf[keyout][3] = (keybuf[keyout][3] << 1) | KEY_IN_4;  I* Q4 a0 [( f; h# G
    //消抖后更新按键状态0 A; h6 y# Z6 G+ u
    for (i=0; i<4; i++)  //每行4个按键,所以循环4次: y  z3 V& y4 S: E" ^/ w
    {
+ o7 w# S* A- l0 Q% Z        if ((keybuf[keyout] & 0x0F) == 0x00)8 ?( P- V2 H; C" E. o
        {   //连续4次扫描值为0,即4*4ms内都是按下状态时,可认为按键已稳定的按下
, ~7 _; S! T0 R2 e: H( g            KeySta[keyout] = 0;; S- v5 Q) n/ ^( b/ U6 ~+ s
        }
# j& m! s5 P3 l7 }        else if ((keybuf[keyout] & 0x0F) == 0x0F). ?4 G9 U, w: a  Y/ e' Z' R4 g
        {   //连续4次扫描值为1,即4*4ms内都是弹起状态时,可认为按键已稳定的弹起
  r, z9 I1 Q& }4 s            KeySta[keyout] = 1;
* ~7 E. O) O7 |* |' b        }6 D* a3 I4 y( ^. }
    }
- B8 w6 ], h4 {! ?  n    //执行下一次的扫描输出4 |. I3 S9 L5 M( m
    keyout++;                //输出索引递增( N7 E8 e1 }! K5 s1 B: c
    keyout = keyout & 0x03;  //索引值加到4即归零1 |/ s0 z0 w. L9 V2 W8 K! S5 i
    switch (keyout)          //根据索引,释放当前输出引脚,拉低下次的输出引脚
1 g- N' B( n7 Z/ v; X    {
: @$ T: d2 q3 A6 v$ X" B" p) {        case 0: KEY_OUT_4 = 1; KEY_OUT_1 = 0; break;
8 j7 Q$ e6 w2 B: `& x6 @0 y        case 1: KEY_OUT_1 = 1; KEY_OUT_2 = 0; break;
0 |; J# X$ c  J7 z1 g- L+ @7 S" ~- |        case 2: KEY_OUT_2 = 1; KEY_OUT_3 = 0; break;( E' I4 |$ X0 l
        case 3: KEY_OUT_3 = 1; KEY_OUT_4 = 0; break;# I. c$ S$ H2 k% e# h/ D% [/ L
        default: break;
5 m4 T/ |/ x! z1 H6 T( k# f- _, G    }
! q' I4 c* r0 {9 G8 E}4 w3 X9 T5 k" _, N
/* 数码管动态扫描刷新函数,需在定时中断中调用 */1 i6 M% ~& i- I+ G4 D
void LedScan()
$ D9 X) V1 L% j{
$ K1 |* T5 y% m5 p% E5 }7 n    static unsigned char i = 0;  //动态扫描的索引
& Z+ _/ C2 E' ?+ f, h: w& j/ C7 \% C' j# f5 J* C+ u3 Z
3 {2 r) d4 \; n. N1 D
    P0 = 0xFF;   //显示消隐% H0 h8 f; q- ?
    switch (i), i* S4 k, Y* J3 `1 X
    {0 ?( |1 I: o2 U2 B' C3 m+ m: F
        case 0: ADDR2=0; ADDR1=0; ADDR0=0; i++; P0=LedBuff[0]; break;8 K* U9 g! _# ?( y/ F( v* d
        case 1: ADDR2=0; ADDR1=0; ADDR0=1; i++; P0=LedBuff[1]; break;
- S3 A" G  n- I. H( C2 Z        case 2: ADDR2=0; ADDR1=1; ADDR0=0; i++; P0=LedBuff[2]; break;
2 T/ E$ [. E4 A8 a1 u; ?$ ]$ N  i        case 3: ADDR2=0; ADDR1=1; ADDR0=1; i++; P0=LedBuff[3]; break;
0 t6 u9 t3 v. {  W. D        case 4: ADDR2=1; ADDR1=0; ADDR0=0; i++; P0=LedBuff[4]; break;
: B6 b1 K! S- X        case 5: ADDR2=1; ADDR1=0; ADDR0=1; i=0; P0=LedBuff[5]; break;4 f0 o7 w: O- Y; I# W
        default: break;
, k. C- S6 d) J+ i" }    }* w$ l+ @/ {4 i- _
}
, I' V# G3 R# K5 t' E* \9 e4 h0 }1 t: E. b/ F' |& ]
0 z- y: y/ a8 t& U5 x( D4 m: F! u
/* T0中断服务函数,用于数码管显示扫描与按键扫描 */1 s6 T5 e7 {$ n/ U* r. P' V
void InterruptTimer0() interrupt 1
! l- Z. c# c& q; x( z# L3 a{
  l) b% N4 O" `. j6 Y9 q6 P. I        TH0 = 0xFC;
4 o& }) u& @' f3 T        TL0 = 0x67;  W; [3 g1 L) p$ r2 h$ c4 w" F
        LedScan();
! I1 ]! m' \" V        KeyScan();
3 y5 z3 I5 a* E6 n}  _% a7 h5 O9 H" n

3 s0 Q" G# i7 T
% D; x& {- b+ U6 Z: e. A7 O* u, a' W

该用户从未签到

2#
发表于 2019-1-16 22:04 | 只看该作者
谢谢楼主分享
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-8-3 15:20 , Processed in 0.125000 second(s), 26 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表