找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6681|回复: 16
打印 上一主题 下一主题
收起左侧

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

  [复制链接]
跳转到指定楼层
楼主
用开发板上的矩阵按键 DS1302 LCD1602 写了一个简单的万年历程序
显示 年月日 时间 星期 温度 可用矩阵按键调整(其中的几个按键  具体的看程序)
程序包括了矩阵按键扫描 、 DS1302、LCD1602、DS18B20 底层文件 可以用来移植到别的程序中
希望对新人的学习有所帮助!
实物图:


原理图:


pcb图:



单片机主程序:

  1. //******************************Write By F H X***********************************//

  2. //****************LCD1602万年历 :显示 年月日、 温度、 时间、 星期****************//
  3. //******************************矩阵按键可调整***********************************//
  4. //*****************************LCD1602界面如下***********************************//
  5. //************************ ■〓〓〓〓〓〓〓〓〓〓〓■ *****************************//
  6. //************************ ■ 2017年03月20日 15°C  ■ *****************************//
  7. //************************ ■ 12:30:00    week:1   ■ *****************************//
  8. //************************ ■〓〓〓〓〓〓〓〓〓〓〓■ *****************************//


  9. #include"function.h"

  10. uchar T0RH=0;
  11. uchar T0RL=0;
  12. bit flag200ms=1;                          //到达200ms标志
  13. uchar mode=0;                             //设置变量
  14. struct STime bufTime;                     //日期时间缓冲区
  15. uchar tflag;
  16. void Timer0Init(uint ms);


  17. /**************************************************主函数***********************************************************/
  18. /*                                                                                                                 */         
  19. /*******************************************************************************************************************/
  20. void main()
  21. {
  22.         uchar psec = 0xAA;                      //确保第一次读取时间能刷新显示
  23.         EA=1;                                   //打开总中断
  24.         Timer0Init(1);                          //初始化定时器0 定时1ms
  25.         RESET_DS18B20();                        //复位18B20
  26.         InitDS1302();                           //初始化DS1302
  27.         InitLcd1602();                          //初始化LCD1602
  28.         
  29.         LcdShowStr(0,0,"20");                   //固定显示内容
  30.         Display_user();                         //显示自定义字符 年 月 日
  31.         LcdShowDat(14,0,0xDF);                  //显示°
  32.         LcdShowStr(15,0,"C");               
  33.         LcdShowStr(0,1,"  :  :  ");
  34.         LcdShowStr(9,1,"week:");
  35.         while(1)
  36.         {
  37.                 KeyDrive();
  38.                 if(flag200ms&&(mode==0))         //到达200ms且没有进入设置模式时
  39.                 {
  40.                         flag200ms=0;
  41.                         GetRealTime(&bufTime);              //获取当前时间
  42.                         Display_Tem();                      //显示温度
  43.                         if(psec!=bufTime.sec)               //检测时间有变化时刷新时间显示
  44.                         {
  45.                                 Refresh_TimeShow();                 //更新显示
  46.                                 psec=bufTime.sec;
  47.                         }
  48.                 }
  49.         }
  50. }



  51. /*********************************************定时器0初始化函数***************************************************/
  52. /*                                           形参ms 当ms=1 定时1毫秒                                             */
  53. /*****************************************************************************************************************/
  54. void Timer0Init(uint ms)
  55. {
  56.         ulong tmp;                              //16位长整型变量tmp
  57.         tmp=12000000/12;                        //用晶振频率除以12得到定时器计数频率
  58.         tmp=(tmp*ms)/1000;                      //计算出需要多少个机器周期
  59.         tmp=65536-tmp;                          //定时器的初始值
  60.         tmp=tmp+27;                             //补偿中断延时响应造成的误差
  61.         T0RH=(uchar)(tmp>>8);                   //将tmp高8位右移8位 赋值给T0RH
  62.         T0RL=(uchar)tmp;                        //将tmp低8位赋值给T0RL
  63.         TMOD&=0xF0;                             //TMOD高4位不变 低四位清零
  64.         TMOD|=0x01;                             //TMOD低四位变成0001
  65.         TH0=T0RH;                               //装载初值
  66.         TL0=T0RL;
  67.         ET0=1;                                  //开启定时器0中断         
  68.         TR0=1;                                  //开启定时器0
  69. }

  70. /*************************************************T0中断服务函数**************************************************/
  71. /*                                                                                                               */
  72. /*****************************************************************************************************************/
  73. void InterruptTimer0() interrupt 1
  74. {
  75.         static uchar tmr_ms=0;
  76.         TH0=T0RH;
  77.         TL0=T0RL;
  78.         KeyScan();
  79.         tmr_ms++;
  80.         if(tmr_ms>=200)                       //定时200ms
  81.         {
  82.                 tmr_ms=0;
  83.                 flag200ms=1;
  84.         }
  85. }
复制代码

按键程序:
  1. #include"key.h"
  2. //**********************Disigned By F H X***************************//
  3. //*********************4*4矩阵键盘扫描程序**************************//
  4. //*****1 按键驱动函数 :检测按键动作 执行 mian.c 中按键动作函数*****//
  5. //*****2 按键扫描函数 :扫描按键状态 在main.c 中的中断函数被调用****//

  6. /*uchar code KeyCodeMap[4][4]={             //ASCⅡ键码
  7.      {'1','2','3',0x26},               //数字键1,数字键2,数字键3,向上键
  8.      {'4','5','6',0x25},               //数字键4,数字键5,数字键6,向左键
  9.      {'7','8','9',0x28},               //数字键7,数字键8,数字键9,向下键
  10.      {'0',0x1B,0x0D,0x27}                //数字键0,  ESC键 ,回车键 ,向右键
  11. };*/

  12. uchar code KeyCodeMap[4][4]={            
  13.      {0x31,0x32,0x33,0x26},               
  14.      {0x34,0x35,0x36,0x25},              
  15.      {0x37,0x38,0x39,0x28},            
  16.      {0x30,0x1B,0x0D,0x27}               
  17. };

  18. uchar KeySta[4][4]={                      //16个按键当前状态
  19.            {1,1,1,1},
  20.      {1,1,1,1},
  21.      {1,1,1,1},
  22.      {1,1,1,1}
  23. };                                       
  24. ulong pdata KeyDownTime[4][4]={           //16个按键按下时间
  25.      {0,0,0,0},
  26.      {0,0,0,0},
  27.      {0,0,0,0},
  28.      {0,0,0,0}
  29. };  


  30. /**********按键驱动函数**********/
  31. void KeyDrive()
  32. {
  33.         uchar i,j;
  34.         static uchar backup[4][4]={             //保存上次按键状态 默认都为弹起
  35.      {1,1,1,1},
  36.      {1,1,1,1},
  37.      {1,1,1,1},
  38.      {1,1,1,1}
  39.         };
  40.         static ulong pdata TimeTh[4][4]={       //按键按下时间阈值 超过阈值则为长按模式
  41.      {1000,1000,1000,1000},
  42.      {1000,1000,1000,1000},
  43.      {1000,1000,1000,1000},
  44.      {1000,1000,1000,1000}
  45.         };
  46.         for(i=0;i<4;i++)                        //循环扫描4×4矩阵键盘
  47.         {
  48.                 for(j=0;j<4;j++)
  49.                 {
  50.                         if(backup[i][j]!=KeySta[i][j])      //检测按键动作
  51.                         {
  52.                                 if(KeySta[i][j]==0)               //按键被按下
  53.                                 {
  54.                                         KeyDown(KeyCodeMap[i][j]);      //执行按键动作函数
  55.                                 }
  56.                                 backup[i][j]=KeySta[i][j];        //保存当前按键值
  57.                         }
  58.                         if(KeyDownTime[i][j]>0)             //检测按键按下时间
  59.                         {
  60.                                 if(KeyDownTime[i][j]>=TimeTh[i][j])
  61.                                 {
  62.                                         KeyDown(KeyCodeMap[i][j]);      //按键按下时间大于阈值 执行按键动作函数
  63.                                         TimeTh[i][j]+=200;              //阈值自增
  64.                                 }
  65.                         }
  66.                         else
  67.                         {
  68.                                 TimeTh[i][j]=1000;                //按键弹起时恢复阈值时间
  69.                         }
  70.                 }
  71.         }
  72. }

  73. /**********按键扫描函数**********/
  74. void KeyScan()
  75. {
  76.         uchar i;
  77.         static uchar keyout=0;                  //矩阵按键扫描输出索引
  78.         static uchar Keybuff[4][4]={            //按键扫描缓冲区
  79.                 {0xFF,0xFF,0xFF,0xFF},
  80.     {0xFF,0xFF,0xFF,0xFF},
  81.     {0xFF,0xFF,0xFF,0xFF},
  82.     {0xFF,0xFF,0xFF,0xFF}
  83.         };
  84.                                                 //逐行检测按键是否被按下 起到按键消抖作用
  85.   Keybuff[keyout][0]=(Keybuff[keyout][0]<<1)|KEY_IN_1;
  86.         Keybuff[keyout][1]=(Keybuff[keyout][1]<<1)|KEY_IN_2;
  87.         Keybuff[keyout][2]=(Keybuff[keyout][2]<<1)|KEY_IN_3;
  88.         Keybuff[keyout][3]=(Keybuff[keyout][3]<<1)|KEY_IN_4;
  89.         for(i=0;i<4;i++)
  90.         {
  91.                 if((Keybuff[keyout][i]&0x0F)==0x00)     //检测某个按键被按下
  92.                 {
  93.                         KeySta[keyout][i]=0;                //改变该按键状态
  94.                         KeyDownTime[keyout][i]+=4;          //该按键按下时间累加
  95.                 }
  96.                 else if((Keybuff[keyout][i]&0x0F)==0x0F)//检测某个按键弹起
  97.                 {
  98.                         KeySta[keyout][i] = 1;              //改变该按键状态
  99.       KeyDownTime[keyout][i] = 0;         //该按键按下时间清零
  100.                 }
  101.         

  102. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码



资料下载:
按键可调万年历.rar (318.62 KB, 下载次数: 141)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏6 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:77707 发表于 2017-4-4 17:45 | 只看该作者
这个好,资料详实,便于模仿。
回复

使用道具 举报

板凳
ID:150346 发表于 2017-4-4 17:54 | 只看该作者
原理图PCB图和程序有些差别 大家注意一下
回复

使用道具 举报

地板
ID:186071 发表于 2017-4-4 17:56 | 只看该作者

 这个好,资料详实,便于模仿。
回复

使用道具 举报

5#
ID:186102 发表于 2017-4-4 19:52 | 只看该作者
这个好,资料详实,便于模仿。
回复

使用道具 举报

6#
ID:82765 发表于 2017-4-4 20:03 | 只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

7#
ID:150346 发表于 2017-4-4 20:08 | 只看该作者
cjjcjj1 发表于 2017-4-4 20:03
PCB和原理图都是 PDF 格式,楼主能否提供 PCB 源文件呢

这个也不复杂 自己试着画一下
如果没有器件封装库 可以到我另一个帖子下载

最全AD器件库封装库!!超大资源!
http://www.51hei.com/bbs/dpj-79889-1.html
(出处: 51黑电子论坛)
回复

使用道具 举报

8#
ID:167337 发表于 2017-4-5 15:07 | 只看该作者
谢谢楼主分析好资源,正需要来学习!
回复

使用道具 举报

9#
ID:185915 发表于 2017-5-14 12:27 | 只看该作者
正好要做这个 楼主很给力
回复

使用道具 举报

10#
ID:185915 发表于 2017-5-14 12:30 | 只看该作者

谢谢楼主分析好资源,正需要来学习!
回复

使用道具 举报

11#
ID:257452 发表于 2017-12-6 22:16 | 只看该作者
请问有没有那个仿真图呢?
回复

使用道具 举报

12#
ID:122146 发表于 2018-3-31 08:44 | 只看该作者
谢谢楼主分享资源,正需要来学习!
回复

使用道具 举报

13#
ID:301164 发表于 2018-4-2 21:56 | 只看该作者
您这个非常棒   完美解决了我的问题  谢谢您了
回复

使用道具 举报

14#
ID:237239 发表于 2018-5-15 20:32 | 只看该作者
正在做这个东西。。。。。悔恨没看到楼主的帖子,浪费那么多时间码代码
回复

使用道具 举报

15#
ID:273605 发表于 2018-5-16 06:59 | 只看该作者
最近要用1602,参考一下~~!
回复

使用道具 举报

16#
ID:670600 发表于 2019-12-22 18:45 | 只看该作者
博主,我是新人,可以发一下程序吗?谢谢!1063847577@qq.com
回复

使用道具 举报

17#
ID:670990 发表于 2019-12-24 15:33 来自手机 | 只看该作者
楼主实物图怎么插的
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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