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

可调矩阵按键+LCD1602简单万年历程序 已制作出实物

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
可调矩阵按键+LCD1602简单万年历程序 已制作出实物
  u9 T2 V& }- B/ F5 W/ g: l用开发板上的矩阵按键 DS1302 LCD1602 写了一个简单的万年历程序) _+ z5 O! G2 @
显示 年月日 时间 星期 温度 可用矩阵按键调整(其中的几个按键  具体的看程序)
; v) e- y3 h7 L+ e" q: a程序包括了矩阵按键扫描 、 DS1302、LCD1602、DS18B20 底层文件 可以用来移植到别的程序中2 b6 p! Z# }* p1 C  s0 X, X; ]
希望对新人的学习有所帮助!$ z$ U: D5 K. u/ e0 r2 z
实物图:* R' Y% a, T$ J- A/ Y6 P% O+ |9 ^
" `  v2 X! C7 H. ?

) a, W% T, T' Y5 G% J
% M! Z6 V* K# ^2 o5 A
, ^( u, d* V( E4 u单片机主程序:
  h- R# k, I4 W$ ]! ~) r
* _" S$ B" Q  O4 X" i' x% v' i//******************************Write By F H X***********************************//% @7 u, s* Y: N- u: l1 [2 @' a
' S; w) z- U4 J. U$ f
//****************LCD1602万年历 :显示 年月日、 温度、 时间、 星期****************//
0 C4 n& q; w3 X! R' W' Y& v* L//******************************矩阵按键可调整***********************************//) A' S6 X& a: F
//*****************************LCD1602界面如下***********************************//) f5 D0 l7 P6 C3 M
//************************ ■〓〓〓〓〓〓〓〓〓〓〓■ *****************************//
" N% h: h3 M* s# I8 {: d% `3 ^- P. d//************************ ■ 2017年03月20日 15°C  ■ *****************************//
, K. n( J0 I- ]# z" B$ E//************************ ■ 12:30:00    week:1   ■ *****************************//, }. T6 E" U6 W: o' O
//************************ ■〓〓〓〓〓〓〓〓〓〓〓■ *****************************//9 {6 c  Y) o* f% R+ P& R1 L- x
& c! l; e: J! K8 T4 P, s

) Q# v# z6 x4 i+ D( `#include"function.h"1 c- X/ `$ U. q) t" R9 K

" k* q) A/ k8 }, o% G3 c# G4 L( ruchar T0RH=0;4 [# z: v" z& l
uchar T0RL=0;
. U2 Y( O1 g" ]( i4 R. jbit flag200ms=1;                          //到达200ms标志4 W7 q/ J" A, V) w" \
uchar mode=0;                             //设置变量, f) k+ q1 `& y$ n
struct STime bufTime;                     //日期时间缓冲区3 _3 D- e: p' D' [8 B1 [
uchar tflag;
7 i* m; K0 \7 y- J6 I/ gvoid Timer0Init(uint ms);
4 ]" }# E4 v3 R% ]3 v! s% V& B/ `% n6 W6 e2 J5 B: L4 `1 t
: r! c7 b$ P0 l' \% z; G8 u7 o
/**************************************************主函数***********************************************************/
7 p" P1 G! C4 W8 I8 B4 F6 w$ q/*                                                                                                                 */          4 j$ ?( I' `' ^1 E5 ~, l' N
/*******************************************************************************************************************/) _. j# \1 v9 U- L5 a7 N
void main()6 Q0 j+ j/ X# z7 v
{/ _, i. N. E6 l! ^
        uchar psec = 0xAA;                      //确保第一次读取时间能刷新显示/ _9 C) {! u: p& x9 y2 D
        EA=1;                                   //打开总中断  v9 M5 m: B5 t
        Timer0Init(1);                          //初始化定时器0 定时1ms
3 y, s3 k0 Q; n; \( Y        RESET_DS18B20();                        //复位18B20# d& e( b2 N9 u
        InitDS1302();                           //初始化DS1302. t  D  j7 l8 [; U2 D
        InitLcd1602();                          //初始化LCD1602
1 G$ r% H5 o# ?' ~0 `" q0 Z( G
5 E: j5 u2 Q" g/ |        LcdShowStr(0,0,"20");                   //固定显示内容0 c+ W. ?7 k3 \; E0 m: @& [
        Display_user();                         //显示自定义字符 年 月 日, v9 \; ?: D5 f; A) o! I
        LcdShowDat(14,0,0xDF);                  //显示°$ ?) m- c' ~- A# {6 f
        LcdShowStr(15,0,"C");               
3 ^; R$ y1 E& H* x0 j1 p- g2 ~        LcdShowStr(0,1,"  :  :  ");
1 g8 J& c( h3 \! S6 x: L        LcdShowStr(9,1,"week:");' U  \1 A$ c' x' y! Y# O9 e& u
        while(1)
6 l% K# z, [5 {        {/ v8 h: I9 j, r% q/ X5 Q+ N
                KeyDrive();. j$ t- t* T7 e2 t0 u
                if(flag200ms&&(mode==0))         //到达200ms且没有进入设置模式时6 U1 m: W+ Z. h
                {
" Q) `" W" Z4 a; X  N4 g$ q                        flag200ms=0;2 c& u. G; ^1 v& d- p; b. p
                        GetRealTime(&bufTime);              //获取当前时间
% E7 ]- E/ F: \3 _8 B/ _  \# O* k                        Display_Tem();                      //显示温度2 y1 j& N7 o- T% G5 X3 K/ M
                        if(psec!=bufTime.sec)               //检测时间有变化时刷新时间显示
0 U. d7 d: e1 D( n9 W1 ?. @6 ~* }                        {
) ?$ M6 X! ]8 \+ K( l                                Refresh_TimeShow();                 //更新显示
3 D. t& x3 b( Y# f, H) Q1 a                                psec=bufTime.sec;
, u  D8 X/ ~& D4 q1 F/ k# u8 v                        }3 \+ {+ S( O1 o* q
                }. ]. ?6 |3 X3 C- I+ Y* b
        }* g$ ^  W" g+ \& u/ |
}8 V; N, i7 I1 K! i
0 b3 L/ f- b+ M+ |  \

; o; r: ]. Y; Y# d1 l) a" ?6 v
1 d" E) @( p2 o' N/ n/*********************************************定时器0初始化函数***************************************************/
% F/ B1 {$ |9 }* h( Z  z; W; d/*                                           形参ms 当ms=1 定时1毫秒                                             */
1 X& W$ a: a1 l/*****************************************************************************************************************/
0 S, [6 J0 H* c; P3 Ovoid Timer0Init(uint ms)8 D4 y( {$ l3 @
{: Z  i% c+ ], H
        ulong tmp;                              //16位长整型变量tmp
; T! Y& a/ t! f# M/ `1 @! T3 `* f        tmp=12000000/12;                        //用晶振频率除以12得到定时器计数频率0 }+ W6 y. V4 n! s: p( G
        tmp=(tmp*ms)/1000;                      //计算出需要多少个机器周期# W* f* r' L! }" X( v+ E
        tmp=65536-tmp;                          //定时器的初始值$ ?6 i7 u, Y2 Z+ `
        tmp=tmp+27;                             //补偿中断延时响应造成的误差
! ^% i  V; P' W& g        T0RH=(uchar)(tmp>>8);                   //将tmp高8位右移8位 赋值给T0RH
0 H6 U0 G$ I8 |0 r7 u" ?        T0RL=(uchar)tmp;                        //将tmp低8位赋值给T0RL& ~1 k4 f/ Z( ?' s) a% u
        TMOD&=0xF0;                             //TMOD高4位不变 低四位清零  S+ j1 X. {+ d% j1 u- F, _
        TMOD|=0x01;                             //TMOD低四位变成00015 U3 m  ^% l. K) |) W
        TH0=T0RH;                               //装载初值
3 w, Z) h3 h" O! j3 H& R9 C        TL0=T0RL;
3 Z  d3 o) _$ l+ d: v* [        ET0=1;                                  //开启定时器0中断          ; z5 H; w3 U; }" z; |
        TR0=1;                                  //开启定时器0( N- ~, j5 Q1 Z9 n3 ^7 m
}
1 I+ K1 H7 w5 ?0 L/ @8 n2 ~
- Y9 H( l; c7 c) v1 m0 H1 _/*************************************************T0中断服务函数**************************************************/
4 O) O: m7 B( a" N( W& X! ^  P/*                                                                                                               */
. S6 k4 o$ C2 x" _8 n  h6 `: u1 R: B/*****************************************************************************************************************/
' j0 R6 |! h, g1 j4 dvoid InterruptTimer0() interrupt 1  n) ?. z, o8 ^
{
& g, L2 L# J* I        static uchar tmr_ms=0;
5 s$ `, t  [+ P6 p* \0 k, x( k        TH0=T0RH;: v9 w) b% b- V& B
        TL0=T0RL;
# w$ p& t1 l! q9 e: E$ a' {% F3 T/ `        KeyScan();$ z, C3 r1 Y' \; R9 N
        tmr_ms++;) S7 K4 u7 x( i, Q  l: H
        if(tmr_ms>=200)                       //定时200ms" D1 ]2 I0 ^) @6 A
        {& S" T, B! Z8 x' v* f* O4 c
                tmr_ms=0;
( Z4 p6 J1 U' S                flag200ms=1;
8 R/ Z; B; z$ ?        }
2 p* D% {5 T( w. d: O) R}
% A, T8 K# v+ ^/ g( W
: j" c% D& d2 H' C; D& k7 O按键程序:
/ s7 U% j6 \/ U9 _/ K$ [+ u) h#include"key.h", @0 W- C' t& j7 ~6 o7 D8 ]
//**********************Disigned By F H X***************************//! o, R' b- R0 y) Y6 C" a+ E
//*********************4*4矩阵键盘扫描程序**************************//" i1 B9 M$ L2 l- v7 e/ z! Z1 @7 m
//*****1 按键驱动函数 :检测按键动作 执行 mian.c 中按键动作函数*****//
. G8 n7 T% U- }# ?# b  R& D% |; E: d//*****2 按键扫描函数 :扫描按键状态 在main.c 中的中断函数被调用****//
0 p7 k9 B3 N8 E9 F9 n" d; {) F" U2 p+ [/ y9 M
" z7 s  f/ m( ]' K
/*uchar code KeyCodeMap[4][4]={             //ASCⅡ键码
& H% d) S2 K) i" {4 c     {'1','2','3',0x26},               //数字键1,数字键2,数字键3,向上键
; w6 U. S- n- B1 C     {'4','5','6',0x25},               //数字键4,数字键5,数字键6,向左键
0 l) [6 S  ~6 ]$ n     {'7','8','9',0x28},               //数字键7,数字键8,数字键9,向下键 - }6 g0 Q- e; u; V
     {'0',0x1B,0x0D,0x27}                //数字键0,  ESC键 ,回车键 ,向右键; t. p  z9 p0 x0 v  B- s/ C7 c
};*/
- |( @7 v1 e+ T3 G( W3 x/ {! I* R4 x2 i8 V7 \" s
: U* l9 z( ?( I9 V. ^1 I+ g
uchar code KeyCodeMap[4][4]={            + q4 X/ ?+ E2 x# A8 ^4 F
     {0x31,0x32,0x33,0x26},               7 d7 h3 k7 B+ D! k" p) d
     {0x34,0x35,0x36,0x25},              0 u2 u2 n/ y8 u" g; A8 F
     {0x37,0x38,0x39,0x28},             0 k/ T: y, {8 }4 ?% G. \; O
     {0x30,0x1B,0x0D,0x27}               
/ L% Z' b# m' d9 e( t7 M4 [- X};/ ~! g* t/ X6 J* W3 f, B/ V! L8 m
: x" k9 o/ w- @/ f

. b& ?2 x: S0 D8 w( @uchar KeySta[4][4]={                      //16个按键当前状态  m* h  l$ A& R0 l& D; V! R
           {1,1,1,1},) r5 Y$ }  @. p4 R
     {1,1,1,1},' P7 E$ i/ e" ?0 u+ A) m1 ?0 s7 z
     {1,1,1,1},
5 z1 {5 T1 G) J     {1,1,1,1} 6 |4 F1 |4 r8 o+ _
};                                       
4 H7 B' x" f9 Mulong pdata KeyDownTime[4][4]={           //16个按键按下时间) o3 b2 f; e8 n' x
     {0,0,0,0},
; U$ f/ F+ ~3 _  d     {0,0,0,0},
% [, k: \, w( ]+ S: t3 r3 w     {0,0,0,0},( G* q  ?9 |9 A: N* f) P; [
     {0,0,0,0} $ T2 j8 I3 c) j8 z4 j' s/ J! X7 U
};  " y8 N% b& z" \- a6 I
: M1 Y9 v* _4 o1 q# u( a

" e: H7 u: Q, D" y9 G* j2 S, N, T
0 e5 B2 E6 s5 F' t1 }9 R$ R( W

. }- E; U3 q5 A% _$ X# L/**********按键驱动函数**********/
4 [0 }# H, G" pvoid KeyDrive()
+ b& O4 {8 v% ?/ y6 L) b! t: p{
* _5 G# m5 G3 |& P. H6 i" s        uchar i,j;6 M1 {) j$ \* X, [# K% Q" y5 m  b
        static uchar backup[4][4]={             //保存上次按键状态 默认都为弹起$ t/ D( U! ^6 g3 s0 k4 d) G3 |$ Z
     {1,1,1,1},2 ]8 d0 X  @5 R9 E; y- q
     {1,1,1,1},9 b0 f+ l4 @% N4 `6 x+ T2 G
     {1,1,1,1},5 A) ^+ ?( `& e  A
     {1,1,1,1}
* b$ [0 G  V. l" \( {        };4 f& M8 F. ~& }! a
        static ulong pdata TimeTh[4][4]={       //按键按下时间阈值 超过阈值则为长按模式
$ E' i( {- b  _     {1000,1000,1000,1000},
% M  i6 Q' `; _     {1000,1000,1000,1000},
- l3 T! x1 v3 ~( n- _     {1000,1000,1000,1000},
; C% g- F. I) |$ L$ v/ c     {1000,1000,1000,1000}
# k+ b+ Q+ \  P7 G0 L        };2 S) B) f0 X7 T% m8 B" }3 k* P) ^  I
        for(i=0;i<4;i++)                        //循环扫描4×4矩阵键盘" `+ g2 d- j( M3 a
        {& S  T& W9 Q0 p% t. c# c
                for(j=0;j<4;j++)
$ J" w2 j# s. ]0 f/ z' G& H* V                {
6 w9 i& ]7 m/ {( s+ A                        if(backup[j]!=KeySta[j])      //检测按键动作
* A% f% G1 @" G2 y0 v& b+ F                        {! g! i6 Q! o7 N& r9 p
                                if(KeySta[j]==0)               //按键被按下
5 ?" w3 O3 _' M# n, k+ h2 H$ C                                {
# D* F: ]# z! W) @9 d# ]# q                                        KeyDown(KeyCodeMap[j]);      //执行按键动作函数
$ Z$ B# @% }7 u6 {  x! ]                                }) H$ ~: P1 X- _! ^  x
                                backup[j]=KeySta[j];        //保存当前按键值
' O. o+ H% z2 Y  s' P7 R: [                        }0 L# e7 b( L0 v/ p/ J$ c" f* t8 V
                        if(KeyDownTime[j]>0)             //检测按键按下时间
$ W3 m( p  u: w/ Y6 W# X& N                        {) R! L2 ~0 p  k  ^3 c
                                if(KeyDownTime[j]>=TimeTh[j])  v& F3 ?( {# v! `: m$ b
                                {' i* G3 R/ d; [0 F% i* x9 P
                                        KeyDown(KeyCodeMap[j]);      //按键按下时间大于阈值 执行按键动作函数7 U# G, u$ n; y% j1 A3 R% d3 U% N- N
                                        TimeTh[j]+=200;              //阈值自增
+ b6 V6 G' ]' s# J) y                                }
* m: H: J8 i! Q1 H% J, i                        }
7 U- N$ O# Y2 k0 C3 ^7 t5 u+ F                        else
2 Y6 }9 t$ A7 y: @4 f                        {: ?/ T$ d7 m/ v& H  l+ u
                                TimeTh[j]=1000;                //按键弹起时恢复阈值时间
8 G, v$ W! G1 ~6 w" k                        }7 S6 t) ~( ~% }% _1 a( l
                }
- R* C1 a3 C/ N  O) r8 g        }. ]0 B1 s- c3 k, r
}
1 W( k8 j& O/ W$ u" s5 \+ Y9 \& b
- Y+ d+ G2 Z4 X2 D% L) l
! M3 y/ F- c8 p; ~
/**********按键扫描函数**********/( I/ d; }4 I: F& c
void KeyScan()& h! ]0 i8 P! m4 Z
{
1 X8 ?- c* W. ~        uchar i;
/ `) }9 u3 d7 X% S6 b        static uchar keyout=0;                  //矩阵按键扫描输出索引
2 d0 I) y7 K( Y, W3 D8 B4 Z/ v        static uchar Keybuff[4][4]={            //按键扫描缓冲区
! _& C* O) M- K9 E1 c9 f+ J                {0xFF,0xFF,0xFF,0xFF},
$ }: W* g0 Q  s9 s- q    {0xFF,0xFF,0xFF,0xFF},4 ?" }2 j6 T& @* ^
    {0xFF,0xFF,0xFF,0xFF},6 w. S/ H8 a' k# a1 N) S9 H
    {0xFF,0xFF,0xFF,0xFF}
, B5 x0 L$ E% K  F$ `8 E        };
: O( P& Z0 \; f( P3 M" {                                                //逐行检测按键是否被按下 起到按键消抖作用
" L" {+ t/ h3 a$ C) T5 I) R0 w5 l  Keybuff[keyout][0]=(Keybuff[keyout][0]<<1)|KEY_IN_1;+ e, T7 C0 S! `! {
        Keybuff[keyout][1]=(Keybuff[keyout][1]<<1)|KEY_IN_2;
0 ]: b1 F" N5 f        Keybuff[keyout][2]=(Keybuff[keyout][2]<<1)|KEY_IN_3;/ O4 |, c; C3 C$ c- o: y) |
        Keybuff[keyout][3]=(Keybuff[keyout][3]<<1)|KEY_IN_4;/ a2 t% ?' @5 V+ H
        for(i=0;i<4;i++)/ ^5 K1 r4 g' y) \- k5 c$ [8 T/ {* e
        {
$ s0 T5 A( \4 T                if((Keybuff[keyout]&0x0F)==0x00)     //检测某个按键被按下
* M1 ]0 p  f  y9 j8 A9 k                {
* ?; V% F0 z' }& O                        KeySta[keyout]=0;                //改变该按键状态/ u9 j& n: |9 [, c5 u# r- Q
                        KeyDownTime[keyout]+=4;          //该按键按下时间累加! H) i7 S5 Z; i0 l
                }5 T- C/ D3 R; C) h% L' D7 ?6 a
                else if((Keybuff[keyout]&0x0F)==0x0F)//检测某个按键弹起
5 V, h6 h1 G8 _  w                {6 I& W6 _7 y: m7 A( W( m( @7 ~: ?* J& v
                        KeySta[keyout] = 1;              //改变该按键状态8 i0 w" U/ s+ S* W& J, y
      KeyDownTime[keyout] = 0;         //该按键按下时间清零7 n9 L; u, W) `5 c# o% _3 y
                }0 {5 D: I( C) M" N, x
        - r4 c8 F( ]- K) E. ?* c; J- ]0 {
% Y% I7 J# k4 G9 n" `

3 T! C9 _$ t  M…………限于本文篇幅 余下代码请从论坛下载附件…………
) t9 m5 Q: i$ U  Y6 I) R7 M+ S+ r
游客,如果您要查看本帖隐藏内容请回复

9 b# Z" N- J) O: {2 |# c
) [7 [3 h1 k7 W% q" w! l3 K. P/ @2 I  ]! x& B* b: h4 R3 J% z
* S# v+ J3 b7 {- y( m

4 u6 e" E$ T. S& \& F0 g
. a" J5 B5 C! p/ L2 u

该用户从未签到

3#
发表于 2019-12-24 21:13 | 只看该作者

该用户从未签到

4#
发表于 2020-3-4 09:09 | 只看该作者
get到了新技能,谢谢楼主5 A$ x' Q, h0 U$ p# p

该用户从未签到

6#
发表于 2021-2-20 23:51 | 只看该作者
谢谢分享 收藏
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

EDA365公众号

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

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

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

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

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