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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
可调矩阵按键+LCD1602简单万年历程序 已制作出实物7 s( }9 _7 w6 `: _4 c) P
用开发板上的矩阵按键 DS1302 LCD1602 写了一个简单的万年历程序
4 y) R4 ]7 d" L显示 年月日 时间 星期 温度 可用矩阵按键调整(其中的几个按键  具体的看程序)
$ Q$ J# b% W, Z程序包括了矩阵按键扫描 、 DS1302、LCD1602、DS18B20 底层文件 可以用来移植到别的程序中
9 Q7 f! u) M2 c6 c7 x& |+ F& E1 S希望对新人的学习有所帮助!6 k3 J: X1 T9 N6 J8 L
实物图:
( |, N* K' s4 C
1 x6 S- k; c4 V( `$ N $ Z, I- W% E9 _# E8 f

& {/ b3 M  U% h; a" c+ D% Q5 ?6 f/ n! t) r+ M
单片机主程序:
4 I; C- g2 Y4 q5 p2 w& a
( ~" Z4 R6 J0 h//******************************Write By F H X***********************************//
7 O: Q$ }0 Z( K
0 O$ }7 ^, d/ ?% V1 n//****************LCD1602万年历 :显示 年月日、 温度、 时间、 星期****************//. d- y6 U% l  V4 ^, d& _
//******************************矩阵按键可调整***********************************//6 O  J6 d9 h: u5 I& M1 B% X
//*****************************LCD1602界面如下***********************************//
5 S4 s/ o7 U$ }% n+ P( H//************************ ■〓〓〓〓〓〓〓〓〓〓〓■ *****************************//
' n1 u# o) b1 U% l" ^//************************ ■ 2017年03月20日 15°C  ■ *****************************//
- l( ?5 E# y; J/ r4 s  m) C//************************ ■ 12:30:00    week:1   ■ *****************************//
0 B) ]4 G8 E. `5 V- S//************************ ■〓〓〓〓〓〓〓〓〓〓〓■ *****************************//9 ^7 }" m: c; o8 t7 R
6 Q: y# n! }+ b
# N, ]. R' X# R; g
#include"function.h"/ g% U3 O' D- x# i9 ^1 H& l. t
4 [! Z1 o/ c3 U: V1 `
uchar T0RH=0;
4 J: G" v" m" X# M- j" Quchar T0RL=0;8 y- @# i# P) }+ W5 n, ]! `$ v  ]
bit flag200ms=1;                          //到达200ms标志
& G1 m$ B/ W, m* O- ?+ `: muchar mode=0;                             //设置变量; Z/ d* {. }8 T8 }, o4 W( q, d
struct STime bufTime;                     //日期时间缓冲区: k; B) }/ m. D: U
uchar tflag;' P0 ]9 b6 M' t6 g5 d( f5 }: m
void Timer0Init(uint ms);9 n* n0 l' U% n+ I
6 c- b; D: p# E! z+ H( V

+ {% E& g& @) F/**************************************************主函数***********************************************************/3 G* D4 O+ b, Y% B( Q; \; [6 a
/*                                                                                                                 */         
% H) q0 j: {: Y1 |9 Z/*******************************************************************************************************************/
: c, o. j9 Y& D& x( F3 \+ xvoid main()0 b- e9 ~5 n5 m0 V; ~' d% ~
{1 I( z# B4 f+ u* ~2 Q1 [
        uchar psec = 0xAA;                      //确保第一次读取时间能刷新显示
8 V4 B& ^. C4 A! ?) ?$ f        EA=1;                                   //打开总中断5 Z5 a8 j, M# V: M! o2 j& i4 k
        Timer0Init(1);                          //初始化定时器0 定时1ms9 Z4 r' e: m. T2 Z) p8 M3 W6 f
        RESET_DS18B20();                        //复位18B20- i. {8 P. f5 b5 _$ W
        InitDS1302();                           //初始化DS1302
+ Y% w; ^5 I; d: s8 S' I0 Q        InitLcd1602();                          //初始化LCD1602
7 T. Z5 K" p6 q  D. q+ Y$ a; }- \0 E( b/ ]0 H; N7 A9 u
        LcdShowStr(0,0,"20");                   //固定显示内容8 @& q4 P- p$ n, i4 h7 [! n
        Display_user();                         //显示自定义字符 年 月 日
3 P+ T# I, X- s: N6 n$ C& x. w        LcdShowDat(14,0,0xDF);                  //显示°7 L# J0 `# h7 z8 L( T
        LcdShowStr(15,0,"C");                * \7 Z: E7 P2 F0 V
        LcdShowStr(0,1,"  :  :  ");6 q) ^$ _1 ?6 V: T2 C
        LcdShowStr(9,1,"week:");
3 }2 S5 q8 F6 i        while(1)0 [4 H8 Z/ i  G2 F, R- I8 q2 v
        {" T/ c5 ?  w0 {' y
                KeyDrive();
+ X, i$ t! W: y4 n- k8 d% o5 @                if(flag200ms&&(mode==0))         //到达200ms且没有进入设置模式时/ u8 B6 I% g' l0 c& _
                {
8 L! ^& v0 v( U                        flag200ms=0;& [9 r3 J7 F8 `, J# r, |; q* U& ]* Q' I
                        GetRealTime(&bufTime);              //获取当前时间
" L; G6 k4 i/ M3 i  h                        Display_Tem();                      //显示温度% ?1 Q( J4 s( l0 r  n+ y+ r# x
                        if(psec!=bufTime.sec)               //检测时间有变化时刷新时间显示# Q) Q. l2 `$ ?9 w9 d
                        {
" Q( ~6 E. s5 S3 z. M                                Refresh_TimeShow();                 //更新显示( ~0 X* v' }- R9 _! Q
                                psec=bufTime.sec;8 Z0 L; v9 g( T
                        }
* \" s: R+ ?+ w6 y                }
0 {$ J2 K: K) {4 F% `        }
/ B5 ]! X, q+ b% L5 _}) s- j- W' |) R5 q& W

3 |4 J( b5 f* K! U: l) D. L! j3 A7 T# p/ a* f6 L9 d

) @& W' H! R. a! E) u/*********************************************定时器0初始化函数***************************************************/+ @* c7 E- h* p) {& T1 v" P
/*                                           形参ms 当ms=1 定时1毫秒                                             */( I, B: X  d* H6 z3 W6 ~
/*****************************************************************************************************************/  M. v8 @6 s9 ~8 M0 L2 a+ n
void Timer0Init(uint ms)/ I+ o7 u- |! q. a
{5 W# l  C4 N. V
        ulong tmp;                              //16位长整型变量tmp7 x5 q0 m; ]# i
        tmp=12000000/12;                        //用晶振频率除以12得到定时器计数频率
2 f! Q9 h( R9 j$ c, ?        tmp=(tmp*ms)/1000;                      //计算出需要多少个机器周期
0 Y9 j$ R2 ~/ ?        tmp=65536-tmp;                          //定时器的初始值
7 u) W: j$ }$ ^- ^8 s        tmp=tmp+27;                             //补偿中断延时响应造成的误差- T7 B# q5 Z/ e: a- V* L$ h
        T0RH=(uchar)(tmp>>8);                   //将tmp高8位右移8位 赋值给T0RH
5 W4 i  |8 h% B( ?        T0RL=(uchar)tmp;                        //将tmp低8位赋值给T0RL
$ o% u& p& ]) A: L0 b) _        TMOD&=0xF0;                             //TMOD高4位不变 低四位清零
2 j; w( n9 W; R2 r1 J+ o        TMOD|=0x01;                             //TMOD低四位变成0001' v; x* O: ?! ]0 N/ _; q# {
        TH0=T0RH;                               //装载初值# i) f/ z2 w  F# o" c/ g
        TL0=T0RL;6 T7 d" T8 a! Y+ O+ u
        ET0=1;                                  //开启定时器0中断          ( g) n; J" m6 }8 J/ B8 M, d- Z
        TR0=1;                                  //开启定时器0/ w$ M6 j/ W/ z/ M, i
}
( `6 v1 h. v* T$ a% W9 j% n3 ~1 i  z. s! L% p5 w6 r0 l  s
/*************************************************T0中断服务函数**************************************************/" M% Q2 {2 A$ R! w
/*                                                                                                               */! W3 r( p  \! h" b( X) }
/*****************************************************************************************************************/
+ v5 s9 o4 t+ Lvoid InterruptTimer0() interrupt 1
6 {2 a; B6 P; u8 u; Y2 r{# c3 V2 [9 Y9 {3 H: |
        static uchar tmr_ms=0;
6 e& [' a* i! e        TH0=T0RH;
6 f% n" [) X# ?- C0 {        TL0=T0RL;- d# r' G: L2 M7 Y* `/ N* _) |& e
        KeyScan();9 A" y; T" l7 c8 `& ^
        tmr_ms++;
3 Q2 R1 c( D& f* L4 z, @/ v# r        if(tmr_ms>=200)                       //定时200ms- z$ G% N8 s: d5 K
        {4 p* i; \; ]# D3 ^
                tmr_ms=0;
1 P" l# h6 V  w! N                flag200ms=1;0 K1 l, N/ o- Z9 H# o" {. n
        }
+ f" G4 o7 m3 _2 T, h" L}
7 B% j; o$ b8 {9 w) l; @; P, J
( a3 R7 {6 M( d# \0 g) J按键程序:, y5 U7 C9 [% K" e
#include"key.h"
: ^0 Q& ~" |! e) q5 }& W  K//**********************Disigned By F H X***************************//( z: R, T0 {. W$ K3 u0 b
//*********************4*4矩阵键盘扫描程序**************************//# E$ b) I# U, m/ p" T, ]
//*****1 按键驱动函数 :检测按键动作 执行 mian.c 中按键动作函数*****//& k) N0 Y9 q; q# T
//*****2 按键扫描函数 :扫描按键状态 在main.c 中的中断函数被调用****//; b. V+ i% |. }4 g9 T& e
- B' o3 p# ?1 _- z: t

% T* r; f1 j# U/ u3 M& d/*uchar code KeyCodeMap[4][4]={             //ASCⅡ键码2 ]; g, x1 B% c+ n2 b- e
     {'1','2','3',0x26},               //数字键1,数字键2,数字键3,向上键
6 R& e# B. k" x! s. M     {'4','5','6',0x25},               //数字键4,数字键5,数字键6,向左键
7 V- J$ o  f8 J7 C! a8 d% S* }     {'7','8','9',0x28},               //数字键7,数字键8,数字键9,向下键 " G. z$ L( K% }# `6 X- @6 t8 ~
     {'0',0x1B,0x0D,0x27}                //数字键0,  ESC键 ,回车键 ,向右键
- w' K! J/ O: H$ j+ p; U* f/ l};*/& ?4 V/ C* B) K8 {& L; o, U
4 I8 V7 {! p0 {4 M% b$ B- b
1 I7 x4 r5 {3 p$ @4 b- I3 c8 S
uchar code KeyCodeMap[4][4]={            - l! G% @4 O  i
     {0x31,0x32,0x33,0x26},               ! n1 g% W+ T2 r' J- _" A7 q
     {0x34,0x35,0x36,0x25},              ) r+ p- }0 C% ?  l+ h: `# q
     {0x37,0x38,0x39,0x28},             1 r; b9 n8 O% u! @0 }2 k0 [
     {0x30,0x1B,0x0D,0x27}               
8 r  Y+ S( X/ p  J6 k5 F" m$ w};* r" i5 Q) ]' b. S6 C
/ I+ G# o4 B- E' z% u% d& D

+ Z" s) s6 {* O* Juchar KeySta[4][4]={                      //16个按键当前状态
3 d, s# Q" `) Y9 ]$ c2 x2 s           {1,1,1,1},
, s- h" G1 B7 l: U3 p; V     {1,1,1,1},# l/ ?0 T* [4 N
     {1,1,1,1},5 s4 R/ W  x' Y! k5 f' r
     {1,1,1,1} 2 M' u! f& M1 P, l7 S3 {& Q
};                                        / h5 a# R) T/ T) \) m- U' _
ulong pdata KeyDownTime[4][4]={           //16个按键按下时间
# H- B  G) m3 I     {0,0,0,0},8 H) y3 \8 Y% u4 Z  R" U9 E$ X( _
     {0,0,0,0},) o5 D9 A) A8 w. g
     {0,0,0,0},
% I0 `: s. M( C     {0,0,0,0}
$ [! B6 g6 z: `" \$ y};  - w+ p4 u( b9 q

' e3 R2 l9 @, c$ E" L, m3 I. t
3 D. W4 _  ~) G6 F1 J
! T8 p- h" t/ ^- p# ~) |! L
" b0 ?7 V  a' r7 A1 A" t
/**********按键驱动函数**********/
5 H% q0 X0 }( N( @void KeyDrive()- u$ [$ W) M' T4 h: F/ U! E
{
' Z7 E( f! L5 |5 ~) }# E" q% Z        uchar i,j;  P  ^* i( }1 a1 j  l" f7 g
        static uchar backup[4][4]={             //保存上次按键状态 默认都为弹起; ?" F; T( i1 d" |$ J1 Z$ S1 y% @
     {1,1,1,1},5 k  I1 W" p' \( t# u$ g
     {1,1,1,1},% Z3 c, l$ N2 s$ t5 M6 R5 x
     {1,1,1,1},0 Y3 |* f. K4 B$ d& A* s4 h6 T
     {1,1,1,1}
# v/ q/ ]2 f7 J: X        };
4 |+ Q& {. s, q/ w, ^) ]# K1 o* i- S        static ulong pdata TimeTh[4][4]={       //按键按下时间阈值 超过阈值则为长按模式' O1 j0 S+ g# D- n5 L
     {1000,1000,1000,1000},
3 n# n5 G/ G1 y; p+ r4 `, J- G     {1000,1000,1000,1000},
, w8 @) W) K4 I% a; x+ z     {1000,1000,1000,1000},
( k- E) v) U3 I     {1000,1000,1000,1000}
4 I+ b' R8 D% M7 k! l. M        };( t0 i/ T+ l  i4 c  ]  q) c
        for(i=0;i<4;i++)                        //循环扫描4×4矩阵键盘, i1 @. i, c" T/ p
        {+ Q7 _9 f7 G$ e# u
                for(j=0;j<4;j++)
5 H! N7 v, V% q- f# v* h* w3 Y2 C                {
& W/ |# t7 x! C, H) |! s4 W4 ]                        if(backup[j]!=KeySta[j])      //检测按键动作! q6 t# e8 q+ ~1 g
                        {
% {. S- t; A3 f1 t& Z' _' ^                                if(KeySta[j]==0)               //按键被按下
7 L/ I5 c6 Z( R9 z2 w$ W0 a2 [) t) }                                {
& @) N9 f, c# @9 R& ^                                        KeyDown(KeyCodeMap[j]);      //执行按键动作函数
# \/ B. v9 |( ^; Q5 q( ^5 p7 {# S/ X                                }. X9 I) g. P& m0 l3 @
                                backup[j]=KeySta[j];        //保存当前按键值
9 W- j6 n  b; v4 ?- k                        }
9 f+ m" y% U$ S: ~/ `: k+ K                        if(KeyDownTime[j]>0)             //检测按键按下时间
6 V2 C0 |  V% |. c% u1 l                        {
; {; r3 j" {7 {$ l, s% y                                if(KeyDownTime[j]>=TimeTh[j])' _0 x/ m( p- s( [& y
                                {
; b. R4 [$ G1 ~, \; W# x$ m                                        KeyDown(KeyCodeMap[j]);      //按键按下时间大于阈值 执行按键动作函数% ?. ?: f  _- Z3 {# d
                                        TimeTh[j]+=200;              //阈值自增! q! m. [" u* n5 Z. U7 h- G" U
                                }
& l4 g" p& N0 x( c                        }
: a0 V9 @) W: M# D# {# M% a6 K                        else
  {0 Y  C% K/ g$ P( ^# \; e& @                        {
; `( E: |2 ^5 P) }5 F6 T! d# @' @                                TimeTh[j]=1000;                //按键弹起时恢复阈值时间
" N1 X6 b7 ~3 p                        }
8 o8 U' W6 E9 ^2 A/ R3 A* u& y                }* n: u8 y- }$ ^) T
        }
; S' d( k. f) n5 @}; y1 x2 u( h- v: k' Y2 y1 j+ m. r- y

3 F- ]/ u# [+ K" `5 ]' v
% t$ M0 x! \9 l* B- o. H
/**********按键扫描函数**********/
- t2 T: c' M, x, v$ d9 Uvoid KeyScan()
9 U9 r1 i% e: }  J" v{
% y* C* b1 v& g: y        uchar i;
! J* Q2 u  z7 B% I/ t7 d        static uchar keyout=0;                  //矩阵按键扫描输出索引# t2 w& u; _" ^! X( ]* l" o
        static uchar Keybuff[4][4]={            //按键扫描缓冲区9 F) D4 N" |6 Z4 d' |1 m$ s
                {0xFF,0xFF,0xFF,0xFF},
3 a$ X, {, ?3 S. @- v  b+ [/ L5 ?3 D# v    {0xFF,0xFF,0xFF,0xFF},- K/ N: n  \7 q. L( M
    {0xFF,0xFF,0xFF,0xFF},, O& J' ]8 T8 L( J
    {0xFF,0xFF,0xFF,0xFF}
) j$ r: E3 _+ n* i8 K) C( j: j        };
. W* r; t. u" X7 h7 z/ H2 q                                                //逐行检测按键是否被按下 起到按键消抖作用
; A1 _$ ]- |/ R+ t% N5 [7 X  Keybuff[keyout][0]=(Keybuff[keyout][0]<<1)|KEY_IN_1;
; X! H3 \1 H, K! `  {+ H        Keybuff[keyout][1]=(Keybuff[keyout][1]<<1)|KEY_IN_2;
! I. ?4 W4 Q! |0 y) A7 R" Z        Keybuff[keyout][2]=(Keybuff[keyout][2]<<1)|KEY_IN_3;( ], d& z( e: j& m& |# ]; n
        Keybuff[keyout][3]=(Keybuff[keyout][3]<<1)|KEY_IN_4;& Z: B- D1 r' P0 ^% a) X% }
        for(i=0;i<4;i++)
/ U3 X" {! p0 ]9 L$ W8 n        {
, r. J6 Q; f) k$ n$ A4 R  h                if((Keybuff[keyout]&0x0F)==0x00)     //检测某个按键被按下& z4 U: i% f; e/ N. J* v4 X4 k
                {
; a! e$ [  a5 B                        KeySta[keyout]=0;                //改变该按键状态
- q$ e; |% K' s+ K                        KeyDownTime[keyout]+=4;          //该按键按下时间累加- E5 s9 A1 ?$ Q( h9 w7 ~+ u
                }
1 q0 ?" M+ Z# q                else if((Keybuff[keyout]&0x0F)==0x0F)//检测某个按键弹起$ X4 c( n# S( Y7 x& |5 \9 E3 V6 w: z
                {
3 F. C0 E  F* T1 m7 k  O- X# y5 b% F                        KeySta[keyout] = 1;              //改变该按键状态
1 c6 y: D) J: e% L. k7 x( d$ d      KeyDownTime[keyout] = 0;         //该按键按下时间清零5 s" I8 [: M( m6 _+ v; p* }; L* p
                }
, N2 e& J# b8 x) F5 o        
5 ~$ a% ]+ v" w3 w1 j0 F+ f' O, y7 }  x1 Z  f
- Q/ X4 A# ~+ m4 N8 Z8 q
…………限于本文篇幅 余下代码请从论坛下载附件…………
& m6 X5 f0 Y5 l5 P
游客,如果您要查看本帖隐藏内容请回复
% K9 T7 }! }0 M5 Q- d' Y
: Z  R& Q8 l0 N  j" M* S
' v* R; g  d" a9 ]$ b2 F' ?
8 U6 a0 D( ~: M. {3 m* }& R: t& g

$ s6 d0 w: F3 M+ x+ Y
- J' R, P3 t6 m1 A

该用户从未签到

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

该用户从未签到

4#
发表于 2020-3-4 09:09 | 只看该作者
get到了新技能,谢谢楼主. e; j  h9 N+ }) {# {7 ?1 |: [

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-6-23 19:38 , Processed in 0.109375 second(s), 26 queries , Gzip On.

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

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

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