极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 11359|回复: 8

利用1602和1302实现定时器,望大牛给指导

[复制链接]
发表于 2013-11-28 20:38:25 | 显示全部楼层 |阅读模式
     常常听到老妈在做饭时说“开锅15分钟后叫我一下”,为何不做个定时器,来提醒老妈呢?结合前面学习的知识,再加上1302时间模块,我决定自己做一个。

一、本次实验所需器材
1、Arduino UNO板

2、1602液晶板:http://www.cnblogs.com/xiaowuyi/p/3390024.html(或者http://wikicode.net/?p=232)已经介绍过。

3、DS1302实时时钟模块:DALLAS 公司推出的涓流充电时钟芯片,内含有一个实时时钟/日历和31 字节静态RAM ,通过简单的串行接口与单片机进行通信。实时时钟/日历电路提供秒、分、时、日、周、月、年的信息,每月的天数和闰年的天数可自动调整。时钟操作可通过 AM/PM 指示决定采用24 或12 小时格式。DS1302 与单片机之间能简单地采用同步串行的方式进行通信,仅需用到三个口线:(1)RST 复位(2)I/O 数据线(3)SCLK串行时钟。

(1)DS1302主要性能指标
★ 实时时钟具有能计算2100 年之前的秒、分、时、日、星期、月、年的能力,还有闰年调整的能力
★ 31 8 位暂存数据存储RAM
★ 串行 I/O 口方式使得管脚数量最少
★ 宽范围工作电压2.0 5.5V
★ 工作电流 2.0V 时,小于300nA
★ 读/写时钟或RAM 数据时有两种传送方式单字节传送和多字节传送字符组方式
★ 8 脚DIP 封装或可选的8 脚SOIC 封装根据表面装配
★ 简单 3 线接口
★ 与 TTL 兼容Vcc=5V
★ 可选工业级温度范围-40 +85
★ 双电源管用于主电源和备份电源供应
(2)接线方法(以本实验程序为例)

VCC→+5V/3.3V

GND→GND

CLK→5

DAT→3

RST→2

4、按钮开关一个:按钮开关在连接时,需要接一个1KΩ电阻做为下拉电阻。具体关于按钮的使用可参考(http://www.geek-workshop.com/forum.php?mod=viewthread&tid=74

5、蜂鸣器一个

6、电阻:1KΩ电阻、10KΩ电阻

二、硬件连接方法
    DS1602的连接主要采用四位连接法(http://www.cnblogs.com/xiaowuyi/p/3390024.html),端口为12,11,9,8,7,6。DS1302的连接方法上面已给出,另外按钮开关、蜂鸣器等的连接具体见下图。


三、程序代码
    具体代码如下:

  1. // DS1302:  RST pin    -> Arduino Digital 2
  2. //          DAT pin   -> Arduino Digital 3
  3. //          CLK pin  -> Arduino Digital 5
  4. #include <LiquidCrystal.h>
  5. #include <DS1302.h>
  6. LiquidCrystal lcd(12, 11, 9, 8, 7, 6);
  7. DS1302 rtc(2, 3, 5);
  8. int j=0;//记录定时设定分钟数
  9. int time=0;//remine the last time
  10. int button=13;//4口控制按钮
  11. boolean onoff= LOW; //记录按钮状态
  12. boolean timefix=LOW;//记时器开关,LOW表示未定时,HIGH表示定时
  13. unsigned long buttonHoldTime = 0;//按钮按下持续时间
  14. int buttonStateOld;//按钮上一时刻状态
  15. int buttonState;//按钮本时刻状态


  16. void ting()//控制蜂鸣器发声
  17. {

  18.     int checkstate = digitalRead(button);
  19.     for(int i=0;i<80;i++)//输出一个频率的声音
  20.     {
  21.       digitalWrite(10,HIGH);//发声音
  22.       delay(1);//延时1ms
  23.       digitalWrite(10,LOW);//不发声音
  24.       delay(1);//延时ms
  25.     }
  26.     for(int i=0;i<100;i++)//输出另一个频率的声音,这里的100与前面的80一样,用来控制频率,可以自己调节
  27.     {
  28.       digitalWrite(10,HIGH);
  29.       delay(2);
  30.       digitalWrite(10,LOW);
  31.       delay(2);
  32.     }
  33. }

  34. void clockdate()//1602显示时间
  35. {
  36.         lcd.clear(); //清屏
  37.         lcd.setCursor(0,0);
  38.         lcd.print(rtc.getDateStr(FORMAT_LONG,FORMAT_BIGENDIAN, '-'));//从1302的库文件可以看出,这里有下面几种格式FORMAT_BIGENDIAN:2010-01-01;FORMAT_LITTLEENDIAN:01-01-2010
  39.         lcd.setCursor(11,0);
  40.         lcd.print(rtc.getDOWStr());
  41.         lcd.setCursor(14,0);
  42.         lcd.print("    ");
  43.         lcd.setCursor(0, 1) ;
  44.         lcd.print(rtc.getTimeStr());
  45. }

  46. void setup()
  47. {
  48.   lcd.begin(16, 2);  //初始化LCD
  49.   pinMode(10,OUTPUT);//设置数字IO脚模式,OUTPUT为输出
  50.   pinMode(button,INPUT);//设置引脚为输入模式
  51.   // 设置时钟初始值
  52.   rtc.halt(false);
  53.   rtc.writeProtect(false);

  54.   rtc.setDOW(SATURDAY);        // 设置星期
  55.   rtc.setTime(22, 56,00);     //设置时间
  56.   rtc.setDate(9, 11, 2013);   // 设置日期2013年11月9日
  57.   rtc.writeProtect(true);
  58. }

  59. void loop()
  60. {
  61.   buttonState = digitalRead(button);
  62.   delay(20);
  63.   if (buttonState==HIGH && buttonStateOld==LOW)//按钮状态发生变化
  64.   {
  65.     buttonHoldTime = millis();//用millis()时间函数来记时,该函数最长记录时间为9小时22分,由于本程序最多记录60分钟,所以可以使用
  66.     buttonStateOld =buttonState;

  67.     if (onoff==HIGH)//当进入定时设置状态时
  68.     {

  69.           if (j>59)
  70.           {
  71.               j=0;
  72.               timefix=LOW;
  73.           }
  74.           else
  75.           {
  76.               j=j+1;
  77.               timefix=HIGH;
  78.               
  79.           }
  80.           lcd.setCursor(11,0);
  81.           lcd.print(j);
  82.     }
  83.   }
  84.   else if (buttonState ==HIGH && buttonStateOld==HIGH)//判断按钮是否持续按下
  85.   {
  86.      if (millis()-buttonHoldTime>3000)//当按钮持续按下3秒种进入定时状态
  87.      {
  88.         buttonStateOld=LOW;
  89.   
  90.         if (onoff==LOW)//进入
  91.         {
  92.           j=0;
  93.           timefix=LOW;
  94.           lcd.clear(); //清屏
  95.           lcd.setCursor(0,0);
  96.           lcd.print("Fixed Time:");
  97.           lcd.setCursor(11,0);
  98.           lcd.print(j);
  99.           lcd.setCursor(13,0);
  100.           lcd.print("min");
  101.          
  102.           onoff=HIGH;
  103.         }
  104.         else//退出
  105.         {
  106.          
  107.           clockdate();
  108.   //        Serial.println(rtc.getTimeStr());
  109.           buttonHoldTime = millis();
  110.           onoff= LOW;
  111.         }
  112.         
  113.      }
  114.      else
  115.      {
  116.        buttonStateOld =buttonState;
  117.      }
  118.   }
  119.   else
  120.   {
  121.     buttonStateOld =buttonState;
  122.   }


  123.    if (onoff==LOW)
  124.    {
  125.      clockdate();
  126.       
  127.    }

  128.     if (timefix==HIGH && j>0 && onoff==LOW)
  129.     {
  130.       unsigned long delaytime=j*60000;//把分钟计算成秒

  131.       if ((millis()-buttonHoldTime)>=delaytime )
  132.       {

  133.           do
  134.           {
  135.             buttonState = digitalRead(button);
  136.             ting();
  137.           }while (buttonState==LOW);//当按下按钮后,停止蜂鸣
  138.           j=0;
  139.       }
  140.       else
  141.       {
  142.         clockdate();
  143.       }
  144.     }

  145.   delay(1000);
  146.   
  147. }
复制代码


    这个代码中,初始时间是设定好的,即2013年11月9日22点56分,因此本程序没有加入时钟时间设定功能,也可以再加上几个按钮,加上时间调节功能。另外在判断按钮按下时间这里,本程序的方法自我感觉有时笨,但也没想出更好的方法,哪位有更好的方法,请给指导一下,谢谢。

四、实现效果
    实现过程中,发现存在两个问题,一个是按钮不是很灵敏,另一个是最后再退出调时状态时,长按3秒,时间会增加1分钟。如原本设定12分钟,退出时长按3秒会依然会变成13分钟。

本帖子中包含更多资源

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

x
回复

使用道具 举报

发表于 2013-11-28 20:48:47 | 显示全部楼层
按钮防颤需要加程序。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-11-28 21:20:14 | 显示全部楼层
林定祥 发表于 2013-11-28 20:48
按钮防颤需要加程序。

应该怎么做?能详细说说吗?
回复 支持 反对

使用道具 举报

发表于 2013-11-28 21:28:10 | 显示全部楼层
mybag1 发表于 2013-11-28 21:20
应该怎么做?能详细说说吗?

判断到按钮状态变化加200毫秒后状态一致,确定变化,否则判无效。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-11-28 21:31:09 | 显示全部楼层
哦,我试试
回复 支持 反对

使用道具 举报

发表于 2013-11-28 22:47:51 | 显示全部楼层
硬件防抖也需要吧
回复 支持 反对

使用道具 举报

发表于 2013-11-29 08:25:07 | 显示全部楼层
chaqing 发表于 2013-11-28 22:47
硬件防抖也需要吧

可硬可软,自己选择.
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-11-30 20:03:37 | 显示全部楼层
怎么加法,能具体说说吗?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-11-30 20:04:41 | 显示全部楼层
这样做吗?
        if(key == 1)   
        {
            DelayMS(30);
            if(key == 0)
            {
                                LED = !LED;  
            }
        }
回复 支持 反对

使用道具 举报

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

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-10 04:28 , Processed in 0.039950 second(s), 20 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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