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

51单片机加法器的制作

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
51单片机加法器的制作, i$ X4 Y2 N5 I# @

; D7 e$ r$ M$ U; `$ Q5 W, w: Q

9 E) p1 M5 I2 Q# z完成数码管显示,按键相加的要求/ ^8 E; g; O7 J
此程序的电路图下载:

( J7 v" X: c! d$ ?  U5 _4 _
游客,如果您要查看本帖隐藏内容请回复
+ Z: p8 Y/ [. w7 L- Z

) M# }! R7 Z8 g. s) r, F' E& a" p: c

8 @* g$ o$ O; x/ ^& Z只需要看数码管部分即可,其他部分可忽略掉. ) w2 D0 W8 D0 D2 i+ ^4 X) ~9 v
  P* ~5 `, s9 h$ F
代码如下#include<reg52.h>
9 X; z% y' l5 ?+ e/ y$ Q3 T- f- z  O- q" b  _: [. R, Q

2 l+ N7 Q- G* n; n, Esbit ADDR0 = P1^0;
% ], A: P) b% u* Q4 t7 c+ vsbit ADDR1 = P1^1;3 y7 p0 P$ P+ y* z, M' p( l' H
sbit ADDR2 = P1^2;
. u6 U3 L, u. c$ _4 ?  qsbit ADDR3 = P1^3;
: A7 a4 y: U7 Q" N: Lsbit ENLED = P1^4;
2 g0 W3 K: f7 E/ w- U$ X! Q8 {2 v2 v
/ W# P) p! W. t8 b( r& _4 d
/ P/ U. N' b0 d% C  W" N
sbit KEY_IN_1 = P2^4;
9 ]6 J8 J# B9 q5 r# b) m0 ]' v$ Xsbit KEY_IN_2 = P2^5;
  F' z+ c3 P) A9 Y0 gsbit KEY_IN_3 = P2^6;
; }' i; P2 O& N0 l% L* dsbit KEY_IN_4 = P2^7;
5 ]: J# F  R* y+ g8 S. d- C% ksbit KEY_OUT_1 = P2^3;
/ Q2 a; ~! D7 m5 s; csbit KEY_OUT_2 = P2^2;+ _: s2 m- j# O2 S9 H% M; }
sbit KEY_OUT_3 = P2^1;
) i) M# |/ D2 d$ ^sbit KEY_OUT_4 = P2^0;5 E! T; _$ r6 }( l! \
9 X, p& C! X- u; z0 \
: ~$ {8 R8 ]/ A
unsigned char code LedChar[]={
& f5 a) B+ U- s' o1 s        0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,  N! f8 m5 u" I+ Q* X
        0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E! x* o" T1 @) a0 P
        };
6 _0 D& R5 C" Y6 \7 ]& I: ]+ K% Yunsigned char KeySta[4][4] = { # S- o! R, B; T/ T
        {1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}
! I$ C2 E( R9 ]! Y        };5 C5 f2 l9 P' r# _
unsigned char LedBuff[6] = {+ V5 n( R: v# o0 |. M/ K
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF2 [; d  |' S3 O( k+ f  f, y
        };5 b. M1 ~) x3 h9 _4 a+ j& [5 ~, l  M% i
unsigned char code KeyCodeMap[4][4] = { //矩阵按键编号到标准键盘键码的映射表' u1 ]: ~" Y. H
    { 0x31, 0x32, 0x33, 0x26 }, //数字键1、数字键2、数字键3、向上键
; k6 [+ P) {. a1 D( [    { 0x34, 0x35, 0x36, 0x25 }, //数字键4、数字键5、数字键6、向左键
$ _( W$ D4 y, g# x3 n" P* ?, }    { 0x37, 0x38, 0x39, 0x28 }, //数字键7、数字键8、数字键9、向下键# ?$ Q' A4 A" ^' A8 i. Y4 G
    { 0x30, 0x1B, 0x0D, 0x27 }  //数字键0、ESC键、  回车键、 向右键
, x0 k& h9 t; K' z% [" O; Q        };
( X$ k8 h! H9 C3 V+ X+ `6 W8 |. tvoid  KeyDriver();4 C' b$ h8 b+ f0 o2 t
void main()
, R9 ]+ Q1 b8 z  p2 {{
1 Y2 b% J, w4 `: W" R9 k    EA = 1;       //使能总中断& }* p: b' k5 r1 H. x+ D
    ENLED = 0;    //选择数码管进行显示# e7 J/ L. I9 C5 a
    ADDR3 = 1;
8 I( o% U' O( _3 @2 u- U* }  N9 A1 z    TMOD = 0x01;  //设置T0为模式1
+ y1 M1 {5 N* d7 [* q3 c    TH0  = 0xFC;  //为T0赋初值0xFC67,定时1ms( i% H8 S% Q8 {: `
    TL0  = 0x67;
  _  M& E; _; u9 V. o' h3 |6 d    ET0  = 1;     //使能T0中断
9 H2 `- e# O  f& Y1 e( _. b2 _    TR0  = 1;     //启动T0- \& V% N) B7 P7 K
    LedBuff[0] = LedChar[0];  //上电显示0; z7 m, [' ~- c
        . J; x. d# \. B; m2 ?
    while (1)6 D) W5 |7 k+ p5 p7 L; M8 n. @
    {# y$ v6 N4 g; G2 C) H; `/ K
        KeyDriver();   //调用按键驱动函数  O" H# r1 h' b  @. ~1 y& x/ G
    }4 g. b( T/ P% ]5 E1 x4 ?
}
3 K8 Y4 T' {7 {2 G) h9 J* d; Y# x# L* ?

; M) K- x2 n4 L0 svoid ShowNumber(unsigned long num)( e7 I/ H9 c7 D- l( W7 R6 m
{$ ~. @& n0 ~* t- ~) S
        signed char i;
/ L3 E" y, u2 y$ e7 r& W7 L3 V& ~        unsigned char buf[6];
' Y2 E3 B/ Q! l5 ]
3 Q6 |9 o) v% r0 l' T- U+ x. E& M

' C; F% _( c4 H        for(i=0; i<6; i++)
0 m4 |' s" R' e. u* v( Q- n' W        {5 c6 I- Q2 I' u" m
                buf = num % 10;, b. }; t7 ~* x6 c0 C% \
                num = num / 10;: [$ o5 D/ V0 E$ g; Y# r6 K
        }
4 Q/ f' J$ f0 {! ]* X8 v, v+ X# i3 u
3 n+ [+ U$ I: e5 l" D
        for(i=5; i>=1; i--)  \\gaoweibuxianshi
9 X6 F1 `  U2 v% U" I5 E6 i        {
0 C, v) j7 t( }" M- ], _                if(buf == 0)
2 O2 J' q9 T; p                {
6 B0 g% A& V* v" Q  m, I                        LedBuff = 0xFF;4 b/ I* B8 m# b$ _$ U
                }
; X! [' a- x5 _  d5 `5 ]% h                else
) f6 J# h0 ?; i                        break;' l  t( b; ]# n6 }
        }1 V# k  D' O1 f. P  S* L! f6 n" K
        $ h. j8 w7 |$ Z
        for(; i>=0; i--) \\1 Z" d9 f6 q  E2 a9 O, F8 z
        {( I4 w0 D  f5 Y* Y, a
                LedBuff = LedChar[buf];        % ]. H+ Y2 Y, m
        }
/ I# K) N7 B4 r/ y  Q2 h  X* y# S& t* z  ]9 _, c( q0 |, }
0 r6 J9 ]1 j  i4 g2 l2 A& L
}- x0 C& Z: M# J
void KeyAction(unsigned char keycode)
( E) D' g( m. i8 b) s3 `{  }2 n! |* V; g9 F7 b% A
        static unsigned long result = 0;7 M: Y8 Z% n* S/ E5 ^4 S
        static unsigned long addend = 0;
5 K- P- _  @0 t* C        9 P) x* c. }* U8 N4 i6 w
        if((keycode >= 0x30) &&(keycode <= 0x39))
0 W& j" [2 v. v0 X) D/ Y  j: p; _        {& d- O0 r1 F$ V( S7 S2 G$ Y! K: m
                addend = (addend *10) + (keycode - 0x30);   
) X4 J" k& @1 d9 Z+ p* b: r# \                ShowNumber(addend);
$ ^: i6 D) ~* n% S$ m0 z2 W        }
. b% U5 s0 G/ r$ m% d5 e9 E( ?        2 X! Q; z/ p) b8 t
        else if(keycode == 0x26)" X7 e& }# H0 v0 Q; E( P8 ^
        {
2 F( Z5 a' ]/ q  Q* y: i8 X7 l                result += addend;3 b0 y7 [, m! b0 Z
                addend = 0;
( f# S1 D0 a$ Y# s: x$ J7 V                ShowNumber(result);
$ ?- Y0 r2 m# u4 U  k' p1 `        }2 e$ M; P9 c( R! z3 l0 I
        else if(keycode == 0x0D)
4 O8 @6 G9 Q! D  O3 o        {) L, J" _* d3 Q5 k8 l
                result += addend;2 F- [9 |% C- M) o' I
                addend = 0;
2 b+ Z6 r+ B' v) D0 k& ]                ShowNumber(result);
( N" Q+ ]0 I, O: O, k$ r' [+ x        }
; W8 |- I* k8 I        else if(keycode == 0x1B)
# W9 P, L5 a# E. g! @+ q. e" C) f        {
' m% l; e% o& j                addend = 0;
2 k$ m. m$ ?! H# X& c                result = 0;
0 Q# P. {  W& L                ShowNumber(addend);         3 a+ }/ k" d3 a8 r$ r
        }        
) i8 @3 C3 C% ?' ~* I" I         
( c# ]6 j# [! f7 u1 I3 \}$ C# x! A- |1 W+ `" F
void  KeyDriver()
0 V) Y4 k+ ?1 v, v/ Q{( Q& _3 H2 v1 L; ]5 c  d/ \9 ^
        unsigned char i, j;* D+ S' l' o6 I! q) E; M2 B
        static        unsigned char backup [4][4] = {& v) }. g2 V$ r7 Z6 S# p2 K
        {1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}2 _) j+ Z* i* l, f9 M3 f% Y6 _
        };4 M1 o/ d* [+ `3 Z; h& ^  f
8 r) \! g. ^. P0 I4 O$ Z
# ?8 N. u2 l, Y8 w  A$ Z
        for(i=0; i<4; i++)
' B8 i& ?7 u" j- R6 L0 C/ R# @" m                {
- ?2 i) E) _* P- E" y% L                        for(j=0; j<4; j++)
1 s) {! a, G0 \                        {
, ?7 {. r; t7 r                                if(backup[j] != KeySta[j])( [# \- |  F$ O! o; N
                                {! \9 L6 ~; m5 e# X" g2 Z6 L
                                        if(backup[j] == 0)
. p8 `, f3 F6 I0 M7 k/ N) T                                        {
) M: W& z: m4 P* k7 @4 i4 \* Q                                                KeyAction(KeyCodeMap[j]);. v8 N6 b  z$ L( v& {; }- I
                                        }
) ]- K9 k9 z( f% Z! s+ R                                        backup[j] = KeySta[j];$ M( U1 \1 F9 d4 V( x' d! X% L
                                }0 U% a) R% g( _/ f4 n3 i. i$ i+ V
                        }        6 l& a  F! q6 _' F" \
                }
0 X- [: B- r' U- d' `
# A/ b/ ?6 G0 u3 G2 X# B7 |- \2 f
/ ?- {. J# Z* }! R! V4 M, `
        
0 J# X8 [4 Z: z2 J# C; S+ ]- A}
: t; x3 _+ N, U& r4 _$ d- v' i2 P6 t4 R' B
9 D# [8 T9 `  x% t* g9 ~
/* 按键扫描函数,需在定时中断中调用,推荐调用间隔1ms */$ [/ ]  N+ d4 `" u; B0 j; t
void KeyScan()
2 ^' a! B1 l/ _' m0 r{
$ A" h' c- ~* A1 ]+ \    unsigned char i;) o' S3 T* g8 L7 S  C' U4 }+ d- r( U- m+ B
    static unsigned char keyout = 0;   //矩阵按键扫描输出索引/ I: q6 [: o( `3 h
    static unsigned char keybuf[4][4] = {  //矩阵按键扫描缓冲区4 p7 J5 ~; P$ `2 _
        {0xFF, 0xFF, 0xFF, 0xFF},  {0xFF, 0xFF, 0xFF, 0xFF},
* J! v" d; c# A        {0xFF, 0xFF, 0xFF, 0xFF},  {0xFF, 0xFF, 0xFF, 0xFF}) h/ M- v5 g6 z. r
    };
! L! y& A0 D; {4 I: K" D/ y4 H  w. {$ B6 d1 _' l! J( D) Y
; k! N. X7 C) ]+ O8 h) ~- z* L
    //将一行的4个按键值移入缓冲区: ?+ ~3 y8 F- [2 z. E* `; o8 ^* G
    keybuf[keyout][0] = (keybuf[keyout][0] << 1) | KEY_IN_1;
- i, \& u9 Q6 O  m4 v: O    keybuf[keyout][1] = (keybuf[keyout][1] << 1) | KEY_IN_2;, u0 c7 `( U) Y/ K5 o) U
    keybuf[keyout][2] = (keybuf[keyout][2] << 1) | KEY_IN_3;
6 Q" i8 B7 c4 p    keybuf[keyout][3] = (keybuf[keyout][3] << 1) | KEY_IN_4;$ W6 E5 T  c% a9 G7 s% O
    //消抖后更新按键状态
- W" t8 O- D  a1 s2 r0 y    for (i=0; i<4; i++)  //每行4个按键,所以循环4次7 H) I1 n+ X& i9 E. \
    {
5 e+ O# U" l: A  R7 P3 M: |; ]  \        if ((keybuf[keyout] & 0x0F) == 0x00)7 D) W7 R  {) J4 d
        {   //连续4次扫描值为0,即4*4ms内都是按下状态时,可认为按键已稳定的按下/ k8 z. H  h5 V& a8 i6 k
            KeySta[keyout] = 0;$ Q( U7 u+ `4 T9 g$ j" s3 `
        }. n: n- E# ~# s, R. B( q$ `
        else if ((keybuf[keyout] & 0x0F) == 0x0F)
; E% K& [+ v9 K2 Z# U8 N0 O6 K/ D        {   //连续4次扫描值为1,即4*4ms内都是弹起状态时,可认为按键已稳定的弹起/ a4 e% b, \. ?: c
            KeySta[keyout] = 1;4 |0 M) I6 P$ c, U
        }2 n, |: q1 f$ d% X& p) i  N3 a% i/ v
    }% T, s5 c/ [9 f# P/ H
    //执行下一次的扫描输出7 ~/ }, M% y* c3 t: ?) U; N
    keyout++;                //输出索引递增
- c+ T, E& y% \1 B; M1 \    keyout = keyout & 0x03;  //索引值加到4即归零
) F8 G; b2 I8 F& F; E    switch (keyout)          //根据索引,释放当前输出引脚,拉低下次的输出引脚
: t! D; |) q( X8 c  h5 N' P! t/ r    {
& S7 G$ p, S" y  V        case 0: KEY_OUT_4 = 1; KEY_OUT_1 = 0; break;* I# @/ ]( r: U( v$ F2 q
        case 1: KEY_OUT_1 = 1; KEY_OUT_2 = 0; break;
) h* W& ]' G" ]+ S( s3 H1 u/ o: ]        case 2: KEY_OUT_2 = 1; KEY_OUT_3 = 0; break;
8 p; g; Q# d. ?0 [1 i        case 3: KEY_OUT_3 = 1; KEY_OUT_4 = 0; break;
$ ]) D* E' Y( H5 Q$ m% x        default: break;  B9 B, K4 j' `$ j* t# Q; ?
    }. Y# q# u1 q4 f. E
}4 A! C( j4 Y4 e! z3 K) }6 y
/* 数码管动态扫描刷新函数,需在定时中断中调用 */% [; @. D* q( U+ q/ Q2 \
void LedScan()
% d, Q/ ]  d) D% o" Q{
9 D$ \0 G1 `# _: A( M    static unsigned char i = 0;  //动态扫描的索引- S* k1 G' u$ A+ f9 I& B% Z
9 j5 S  U) P- u4 H6 ?+ P
7 G/ y6 }1 o, F% ]5 _3 l  q
    P0 = 0xFF;   //显示消隐
) s3 i: w2 P4 I' p& x1 W5 S3 S7 H4 |    switch (i)
  {( X) [6 X: H; L. N    {$ [  q' y; v& ]! |* T& L1 Y
        case 0: ADDR2=0; ADDR1=0; ADDR0=0; i++; P0=LedBuff[0]; break;
) O+ F. f8 B' P: R5 E        case 1: ADDR2=0; ADDR1=0; ADDR0=1; i++; P0=LedBuff[1]; break;0 s2 A9 c$ {) ~
        case 2: ADDR2=0; ADDR1=1; ADDR0=0; i++; P0=LedBuff[2]; break;5 i2 V- U7 S, B3 M) ~
        case 3: ADDR2=0; ADDR1=1; ADDR0=1; i++; P0=LedBuff[3]; break;
0 X  l4 N7 T6 d) V2 y: k6 {# w. s        case 4: ADDR2=1; ADDR1=0; ADDR0=0; i++; P0=LedBuff[4]; break;" A  Y' r6 _- E7 b& b6 _* K- M
        case 5: ADDR2=1; ADDR1=0; ADDR0=1; i=0; P0=LedBuff[5]; break;
6 n4 K: X$ J$ t* d' ^5 N; c: a        default: break;1 I2 J- c0 H& K; e2 J! O
    }6 g! P+ o) O4 _# R
}9 ]% H3 |! H2 c, v9 ^* y& [6 z
& W9 N5 K# u$ z  y, G+ P

: A' p" e: r, Q/* T0中断服务函数,用于数码管显示扫描与按键扫描 */6 {  p# E! U3 O+ L! h# u
void InterruptTimer0() interrupt 1
) E4 f0 _$ z; R. l{7 l; I( M2 {: v* Q& I4 ?9 @8 z: [
        TH0 = 0xFC;
+ j; a# r# U- [( K4 u: ?; k1 J        TL0 = 0x67;
) z* c/ J% P9 ?! J, P. N- k        LedScan();6 |4 g+ n, n% K
        KeyScan();  ]" U$ J9 T' t! X( d3 c
}* N9 i+ J  }6 c* s6 T4 {
9 Q; g# L, n& T" Q8 r
: K1 o! O$ M  q% r

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-7-19 05:59 , Processed in 0.125000 second(s), 26 queries , Gzip On.

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

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

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