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

51单片机加法器的制作

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
51单片机加法器的制作
$ B5 M) `6 q) C- j  G2 Q
  c: \  e0 K6 f7 r

& I% i2 k% s, \' P+ b完成数码管显示,按键相加的要求
0 |. h$ ]7 H! M$ {9 v9 [此程序的电路图下载:
% @. w: t* N% ^* P% H
游客,如果您要查看本帖隐藏内容请回复

$ F" [4 f% M6 g, ]* {( T2 m& b
* n) j! K( u- K7 `5 q

4 {) X# t7 j# Y3 x6 c, m: o只需要看数码管部分即可,其他部分可忽略掉.
5 J4 z+ M& |. r, R* ~8 G! P1 X7 S/ d! r/ E
代码如下#include<reg52.h>
# \; j! X0 }) |5 v6 |! T4 T4 [3 f. S' z* b$ p3 C6 ~3 j. e( K

) C$ q0 ~+ T5 v( X5 M7 l0 E% Bsbit ADDR0 = P1^0;. h5 I) `$ P7 v) ^! B* x* G% o* z
sbit ADDR1 = P1^1;5 A- v5 R9 A- T- J
sbit ADDR2 = P1^2;
7 \: m; j7 z' t% ssbit ADDR3 = P1^3;, R' @; v6 F0 c- s
sbit ENLED = P1^4;7 U6 k9 l/ G4 r, s+ \, O5 ~
  Y$ e% m* I' s! n  a
0 h7 h" f; K( {
sbit KEY_IN_1 = P2^4;
6 O" |" f- Q. {0 t0 W  ]sbit KEY_IN_2 = P2^5;, j2 j" v. X8 k/ h; s# x
sbit KEY_IN_3 = P2^6;
: c; l6 a7 ?5 f/ s. X9 g( h9 [+ Y2 `sbit KEY_IN_4 = P2^7;7 K" h- J  M. U. R, C4 ^1 J
sbit KEY_OUT_1 = P2^3;
! I% P$ w: E5 N+ msbit KEY_OUT_2 = P2^2;
; s3 e9 _& L; e5 X0 V0 Psbit KEY_OUT_3 = P2^1;" |' _! ?6 L/ ^5 g1 f6 C- ], \; g
sbit KEY_OUT_4 = P2^0;  e! S1 W# Y* C3 ~) b
  M( P- T' }$ y

1 \/ e! k0 a: ]: h0 H5 ?( u- |unsigned char code LedChar[]={
! }$ T1 d$ R0 w; t" {% p        0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
- l$ S! H- w+ A& p: ^( ]3 ^        0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
/ A/ L0 I" r5 _( x. T* [8 F        };
2 \3 d% F4 @* \unsigned char KeySta[4][4] = { ) a% f$ b2 s1 z# [: R) B6 k. r% C
        {1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}
" }5 s; n/ g8 J9 e        };
% K- j' x2 j' \0 Munsigned char LedBuff[6] = {8 h/ d8 `& T; R% i' c& X, {; i8 h. m
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF  @/ c; M. {* F$ U4 Z4 Z, ?
        };8 m0 Y* V; e& @( O/ O2 R; G
unsigned char code KeyCodeMap[4][4] = { //矩阵按键编号到标准键盘键码的映射表
" P1 G4 u6 @, u& w$ i; C& S    { 0x31, 0x32, 0x33, 0x26 }, //数字键1、数字键2、数字键3、向上键
8 [# I1 W! j$ X3 F" A$ N4 J    { 0x34, 0x35, 0x36, 0x25 }, //数字键4、数字键5、数字键6、向左键
5 q" h% u2 o% G" @: m; _    { 0x37, 0x38, 0x39, 0x28 }, //数字键7、数字键8、数字键9、向下键
) s$ e2 s& [1 P* X6 _9 ?9 ]! }* j    { 0x30, 0x1B, 0x0D, 0x27 }  //数字键0、ESC键、  回车键、 向右键5 y. A% ?% a) \% u/ T2 M
        };; W. T6 B, D* d* E' d
void  KeyDriver();( B4 a# f$ P2 A# J& c. S& c1 A2 y
void main()
- e& Q: F* _& ?* h3 N4 |. @5 {4 x; T{
3 V. V8 e! ]: }* O0 C+ R- a& j    EA = 1;       //使能总中断
# Q; w- W+ ^7 q- x: r    ENLED = 0;    //选择数码管进行显示7 i1 m6 ~- W8 N' `, @. Z
    ADDR3 = 1;$ ?6 y* e2 ]# ^" J
    TMOD = 0x01;  //设置T0为模式16 B# `0 n. z1 P' e$ A( V# K7 M
    TH0  = 0xFC;  //为T0赋初值0xFC67,定时1ms
9 z) b4 f' i6 e6 C! ]3 R    TL0  = 0x67;- S- ~8 N+ F  F
    ET0  = 1;     //使能T0中断
* l7 k+ e2 G7 L9 k% Q& r    TR0  = 1;     //启动T0, Y. B8 C: |2 ^: J2 N
    LedBuff[0] = LedChar[0];  //上电显示0! Q4 v8 p, U. t5 I6 y! j
        
$ D3 h2 f* ]( s- G% N7 \    while (1)
5 W$ O. l% R) c1 L    {
7 |8 ^( }* t% c8 P- I. `        KeyDriver();   //调用按键驱动函数, m8 m. q, P' m. |) c
    }
1 Q( ~& T: k. X) k1 D% I}
* T( N% W- g3 c2 |" m, M( ^7 A% T+ s" s1 w6 a: ^9 }* a- B
& p* Y" e. W9 z- x5 E/ H' T) R
void ShowNumber(unsigned long num)
$ J8 @4 l7 A* M4 A+ s{$ z: @9 g. J! y
        signed char i;
  f4 }5 o7 u( s        unsigned char buf[6];
1 G, c0 X2 o1 A" G1 c* L
% a1 J- `) \1 N

4 P, i+ @9 u3 C# }1 q4 W; J) T        for(i=0; i<6; i++)% k! Z9 u: e9 B) x( K+ @" A( D
        {$ E, }# ?; M& x* V+ v+ C
                buf = num % 10;
6 y3 d! b, P- M3 T; J; _/ c0 F                num = num / 10;
; A& O5 |9 L' {- w        }
$ R5 v: s& }" E* m% {# k% S
" s) a9 q( t) N

: ]! X) @) C  s        for(i=5; i>=1; i--)  \\gaoweibuxianshi ! N1 @# t5 S) }  d7 S  y  O
        {
9 x9 A6 w; M' r& Z# j8 F# I  u                if(buf == 0)0 I- R3 P- X) W
                {2 j$ x/ Z3 `+ U& ]9 F* r' t
                        LedBuff = 0xFF;: G: h2 S' V0 j; T
                }  B) |% m9 }, u! q2 n2 \( H2 a
                else3 p- x; @& O; h, ~; H  W; x" j
                        break;
& g; {! X! m0 k  u+ z+ R        }
. r# H& f+ Y3 W  V) T; j6 d        ) a1 E; e# V1 j- g( D9 e
        for(; i>=0; i--) \\
- O. q% I6 I0 D5 |3 x        {. `$ l: M7 a6 N& s% b
                LedBuff = LedChar[buf];        
5 p! _; }9 X/ o2 G+ ^  H) Z% Z6 [        }; i0 M. ]9 w$ _: _; I5 ], `

% i& k& |! e$ m1 l" Q

8 r5 E- G4 g- P/ Y* W& U: j}* K% Y0 I# Z" _
void KeyAction(unsigned char keycode)
" l; v) f8 |/ F" K0 p- {{
7 U9 I& m2 Y, ~( F& a/ R3 }, \        static unsigned long result = 0;9 m& C- z8 V8 a
        static unsigned long addend = 0;1 n: |% ]0 e" [, A0 J- l* J
        
0 h8 }/ t9 J3 X, ^; N  r# d) [        if((keycode >= 0x30) &&(keycode <= 0x39))5 C& ?$ e$ R1 O
        {6 {. i  V: Q% ?; X, [
                addend = (addend *10) + (keycode - 0x30);   
3 }! D$ O6 i! {1 w7 i% D7 s2 r                ShowNumber(addend);
7 F% E# U. U5 D: H% _9 J) ]1 g        }
/ W9 g) d4 o4 b# H% {        ; G3 {, Q6 a0 s% D
        else if(keycode == 0x26)
' b. Z: s, n" A3 e' \        {
, K: G; v1 ^: k) [2 t3 K% c: j3 B7 ~                result += addend;' [# J5 E( t1 j! y' k7 y
                addend = 0;
) ]2 b: n. R! s6 |9 w" S                ShowNumber(result);
/ R* G" z* O! L, a        }/ f* B# s; _8 e1 E2 |0 A1 P) p
        else if(keycode == 0x0D)
* F) U5 q$ p) f: S: B        {
1 l! {) V4 w5 ?# L4 |                result += addend;
) _5 R+ E! S! j. N  ]* e                addend = 0;
8 m6 [2 k9 e4 c$ j! h2 K7 A                ShowNumber(result);
* c1 Q: M% L! T3 J3 @        }
/ K5 N7 E2 ^5 U8 \  A        else if(keycode == 0x1B)
; s' k, I. I, F& t$ u: p        {
7 `0 ^6 u" ^3 w- D; e                addend = 0;
! ?3 L3 o. C/ R# `, O                result = 0;
" e& `2 e8 L3 j" S  i2 Z: t# I                ShowNumber(addend);         6 T7 \0 Z0 h6 m7 `
        }        ! x8 U5 M1 S* V( B8 |! I* r8 T8 k8 n
         6 i, d- e3 C3 t3 N
}* M+ r# N( p" {2 y+ U3 v+ s
void  KeyDriver()( F( a+ D' s1 N) F3 x0 d! f& J
{
" t: y3 j, u" p+ d4 i! {! q2 \        unsigned char i, j;5 R2 M, e# z/ y" a) Y1 D/ Y
        static        unsigned char backup [4][4] = {
% g6 v" x  O, H% t- p  i: O9 Q        {1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1}- U, |3 K" @/ j5 }- C
        };
" s0 S# m" k1 L3 M
* I2 L% A% W. Q* S4 @

; H2 ]) n, @0 b" W1 F        for(i=0; i<4; i++)
4 C! K9 u3 V8 `( Z% J( ^                {
% D0 |- a2 {2 _* X) o3 T1 r- q                        for(j=0; j<4; j++)( j7 \! V! r6 s: h2 G6 }9 |" L: Q
                        {  e' i: f3 {8 s5 L
                                if(backup[j] != KeySta[j])6 D7 r2 g$ W; b/ _& s
                                {1 i" o( Q* m$ W3 U9 W
                                        if(backup[j] == 0): [1 O. h% h7 ~# I) ^. N1 G7 A
                                        {2 w- q; a* G1 t) h! {8 N$ h
                                                KeyAction(KeyCodeMap[j]);8 Q+ Y  J( |, a; C
                                        }
9 \9 a# m# p4 j; q- O' @+ Z                                        backup[j] = KeySta[j];1 R+ s% V1 A  L5 F+ ?/ i1 Z2 f
                                }
* F5 ^- A" O/ D* ]* z6 C9 J- ^8 ?$ }+ B                        }        
& ^$ z2 T, y+ U& T# ^3 O                }2 x& Q9 z& o% }4 ~* }

% R# t; `* q; z- }
% V: x, k) G1 T  z2 N) D. }
        
! M* w5 p  o% z/ `4 T}
9 O$ x5 L$ T3 t' C
3 R4 E1 J& k1 V: j; T# L+ S8 [6 \  j
7 c2 p3 a' G! k8 k# c4 @
/* 按键扫描函数,需在定时中断中调用,推荐调用间隔1ms */
8 ]5 _! c. e4 ~; Evoid KeyScan()0 Y0 T& V# z7 p/ U1 P0 A9 ]
{1 ]% d3 v4 |; `# f; ]" }
    unsigned char i;: }, P% b% T# t& T9 i
    static unsigned char keyout = 0;   //矩阵按键扫描输出索引% @+ u/ y* q+ F5 r( U8 Z
    static unsigned char keybuf[4][4] = {  //矩阵按键扫描缓冲区
) x0 g0 A- D9 M, C        {0xFF, 0xFF, 0xFF, 0xFF},  {0xFF, 0xFF, 0xFF, 0xFF},
2 ^$ k- [) ^& H, n* N, F% e        {0xFF, 0xFF, 0xFF, 0xFF},  {0xFF, 0xFF, 0xFF, 0xFF}) \* }# O, y. l8 X' D3 M& H
    };
5 r. d. i8 A( g( z+ e1 B
! j  N8 _  N  W3 s7 P3 W3 g3 o1 f
' i% z% w% ~$ M/ U
    //将一行的4个按键值移入缓冲区
5 h# S- T' q( F/ G1 l    keybuf[keyout][0] = (keybuf[keyout][0] << 1) | KEY_IN_1;
1 F8 w# i4 \. R3 p( k$ w    keybuf[keyout][1] = (keybuf[keyout][1] << 1) | KEY_IN_2;
; x" s# J* r! H7 o5 ?$ M    keybuf[keyout][2] = (keybuf[keyout][2] << 1) | KEY_IN_3;
6 m- E# k$ d3 m. ^8 G' D8 h    keybuf[keyout][3] = (keybuf[keyout][3] << 1) | KEY_IN_4;* e8 l1 g! {3 V3 a& k6 {9 w* J% ~7 `
    //消抖后更新按键状态
+ e5 t( t& v' ^& h9 G6 [    for (i=0; i<4; i++)  //每行4个按键,所以循环4次* {3 f$ u* |2 Y
    {
2 I- G  @  [$ K* `" `        if ((keybuf[keyout] & 0x0F) == 0x00)
7 H* X" M% I# @+ ~; t        {   //连续4次扫描值为0,即4*4ms内都是按下状态时,可认为按键已稳定的按下8 u, [1 T0 ^; y3 X
            KeySta[keyout] = 0;( a- ]& t# ^* R( A, w$ b" h2 {7 U
        }1 K0 o- s5 E- n
        else if ((keybuf[keyout] & 0x0F) == 0x0F)
$ h) }. }6 O7 x" K3 v3 t! H( U        {   //连续4次扫描值为1,即4*4ms内都是弹起状态时,可认为按键已稳定的弹起8 M9 l' ?/ w- `+ g0 O8 [
            KeySta[keyout] = 1;+ |* b$ A9 q- N4 Y
        }2 Z4 }; D* ^+ z0 _# O+ Z9 R
    }% [; n' X' X: O: J" b4 \
    //执行下一次的扫描输出
: {# s9 p: @! E+ L    keyout++;                //输出索引递增
! e& Y0 P7 V! o) l    keyout = keyout & 0x03;  //索引值加到4即归零, i3 O* Z8 o, m, h  M
    switch (keyout)          //根据索引,释放当前输出引脚,拉低下次的输出引脚
9 [# P1 P" |$ u  k    {8 f5 d) u. R. Q" c
        case 0: KEY_OUT_4 = 1; KEY_OUT_1 = 0; break;
* {+ o* y  r! h3 s        case 1: KEY_OUT_1 = 1; KEY_OUT_2 = 0; break;
- I$ m, N6 P1 O% Q" t        case 2: KEY_OUT_2 = 1; KEY_OUT_3 = 0; break;
5 C7 h/ l4 m: D  w& ]- ~/ T        case 3: KEY_OUT_3 = 1; KEY_OUT_4 = 0; break;4 C& R) H" ^5 _/ ?! J: ]
        default: break;, W7 i! H; M' U+ Z/ W# l
    }4 o4 p9 D- k: |
}
6 L. n: b1 F/ n' O& @+ @+ b5 o% s/* 数码管动态扫描刷新函数,需在定时中断中调用 */
: e' }) X9 X8 N1 _void LedScan()
+ s* m1 R$ J( Z2 W* b! o; U) l{( m) _9 n$ k) L0 Z5 _' b
    static unsigned char i = 0;  //动态扫描的索引/ p) X+ F+ N# n6 Y/ Z3 S' E+ K

+ v# [; W+ D" y/ |9 p

6 N- j' t8 R2 X4 {' B( m    P0 = 0xFF;   //显示消隐
2 P$ B8 A7 @! n- D6 t9 i    switch (i)
0 I) o% s, R0 r/ \" W5 K    {
% c, |' ~0 V+ l" p! W8 u0 ~        case 0: ADDR2=0; ADDR1=0; ADDR0=0; i++; P0=LedBuff[0]; break;9 {% o! w8 @& A0 q2 A1 S8 Q
        case 1: ADDR2=0; ADDR1=0; ADDR0=1; i++; P0=LedBuff[1]; break;
- w( n" i% s2 g        case 2: ADDR2=0; ADDR1=1; ADDR0=0; i++; P0=LedBuff[2]; break;' W2 Y7 D; [" M: j4 m9 I% M! d
        case 3: ADDR2=0; ADDR1=1; ADDR0=1; i++; P0=LedBuff[3]; break;
' n- U3 W7 B3 H: }/ `! N        case 4: ADDR2=1; ADDR1=0; ADDR0=0; i++; P0=LedBuff[4]; break;/ a  {; H$ t& V, H3 {$ [  ?
        case 5: ADDR2=1; ADDR1=0; ADDR0=1; i=0; P0=LedBuff[5]; break;
+ `  u% v5 u% b# h2 J, \" V: q        default: break;8 G. m+ d3 D4 S
    }
; \  v- Y0 z/ s}
+ ^( Z. C0 V& t0 |" y9 c& P1 W5 t+ F5 j% f. E

; m0 b* T. p8 m2 {7 G9 h/* T0中断服务函数,用于数码管显示扫描与按键扫描 */3 l$ M# ?2 G5 D! c
void InterruptTimer0() interrupt 1
6 q* x) W' K$ t( X0 E3 C{
) J8 X: N2 Y3 s7 e8 G        TH0 = 0xFC;! i8 S6 l6 h- q( s" {* X" M+ m* l
        TL0 = 0x67;3 c; D0 B0 y; b2 C* q
        LedScan();6 }" i3 g* q) }) x- y. y: N
        KeyScan();, g+ Z* {- Y- x
}* M6 Y4 h4 m# @. u( `$ F4 M
: B, }, a! l6 W- O6 K6 K: {
3 Y  d/ ?  U6 y" ^

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-9-11 08:41 , Processed in 0.125000 second(s), 26 queries , Gzip On.

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

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

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