转自:@小五义
常常听到老妈在做饭时说“开锅15分钟后叫我一下”,为何不做个定时器,来提醒老妈呢?结合前面学习的知识,再加上1302韶光模块,我决定自己做一个。
一、本次实验所需器材
1、Arduino UNO板
2、1602LCD 屏幕
3、DS1302实时时钟模块:DALLAS 公司推出的涓流充电时钟芯片,内含有一个实时时钟/日历和31 字节静态RAM ,通过大略的串行接口与单片机进行通信。实时时钟/日历电路供应秒、分、时、日、周、月、年的信息,每月的天数和闰年的天数可自动调度。时钟操作可通过 AM/PM 指示决定采取24 或12 小时格式。DS1302 与单片机之间能大略地采取同步串行的办法进行通信,仅需用到三个口线:(1)RST 复位(2)I/O 数据线(3)SCLK串行时钟。
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★ 双电源管用于主电源和备份电源供应
接线方法(以本实验程序为例)VCC→+5V/3.3VGND→GNDCLK→5DAT→3RST→2
4、按钮开关一个:按钮开关在连接时,须要接一个1KΩ电阻做为下拉电阻。详细关于按钮的利用可参考(http://www.geek-workshop.com/forum.php?mod=viewthread&tid=74)
5、蜂鸣器一个
6、电阻:1KΩ电阻、10KΩ电阻
二、硬件连接方法DS1602 的连接紧张采取四位连接法。端口为12,11,9,8,7,6。DS1302 的连接方法上面已给出,其余按钮开关、蜂鸣器等的连接详细见下图。
三、程序代码
详细代码如下:
// DS1302: RST pin -> Arduino Digital 2// DAT pin -> Arduino Digital 3// CLK pin -> Arduino Digital 5#include <LiquidCrystal.h>#include <DS1302.h>LiquidCrystal lcd(12, 11, 9, 8, 7, 6);DS1302 rtc(2, 3, 5);int j=0;//记录定时设定分钟数int time=0;//remine the last timeint button=13;//13口掌握按钮boolean onoff= LOW; //记录按钮状态boolean timefix=LOW;//记时器开关,LOW表示未定时,HIGH表示定时unsigned long buttonHoldTime = 0;//按钮按下持续韶光int buttonStateOld;//按钮上一时候状态int buttonState;//按钮本时候状态void ting()//掌握蜂鸣器发声{int checkstate = digitalRead(button);for(int i=0;i<80;i++)//输出一个频率的声音{digitalWrite(10,HIGH);//发声音delay(1);//延时1msdigitalWrite(10,LOW);//不发声音delay(1);//延时ms}for(int i=0;i<100;i++)//输出另一个频率的声音,这里的100与前面的80一样,用来掌握频率,可以自己调节{digitalWrite(10,HIGH);delay(2);digitalWrite(10,LOW);delay(2);}}void clockdate()//1602显示韶光{lcd.clear(); //清屏lcd.setCursor(0,0);lcd.print(rtc.getDateStr(FORMAT_LONG,FORMAT_BIGENDIAN, '-'));//从1302的库文件可以看出,这里有下面几种格式FORMAT_BIGENDIAN:2010-01-01;FORMAT_LITTLEENDIAN:01-01-2010lcd.setCursor(11,0);lcd.print(rtc.getDOWStr());lcd.setCursor(14,0);lcd.print(" ");lcd.setCursor(0, 1) ;lcd.print(rtc.getTimeStr());}void setup(){lcd.begin(16, 2); //初始化LCDpinMode(10,OUTPUT);//设置数字IO脚模式,OUTPUT为输出pinMode(button,INPUT);//设置引脚为输入模式// 设置时钟初始值rtc.halt(false);rtc.writeProtect(false);rtc.setDOW(SATURDAY); // 设置星期rtc.setTime(22, 56,00); //设置韶光rtc.setDate(9, 11, 2013); // 设置日期2013年11月9日rtc.writeProtect(true);}void loop(){buttonState = digitalRead(button);delay(20);if (buttonState==HIGH && buttonStateOld==LOW)//按钮状态发生变革{buttonHoldTime = millis();//用millis()韶光函数来记时,该函数最长记录韶光为9小时22分,由于本程序最多记录60分钟,以是可以利用buttonStateOld =buttonState;if (onoff==HIGH)//当进入定时设置状态时{if (j>59){j=0;timefix=LOW;}else{j=j+1;timefix=HIGH;}lcd.setCursor(11,0);lcd.print(j);}}else if (buttonState ==HIGH && buttonStateOld==HIGH)//判断按钮是否持续按下{if (millis()-buttonHoldTime>3000)//当按钮持续按下3秒种进入定时状态{buttonStateOld=LOW;if (onoff==LOW)//进入{j=0;timefix=LOW;lcd.clear(); //清屏lcd.setCursor(0,0);lcd.print("Fixed Time:");lcd.setCursor(11,0);lcd.print(j);lcd.setCursor(13,0);lcd.print("min");onoff=HIGH;}else//退出{clockdate();// Serial.println(rtc.getTimeStr());buttonHoldTime = millis();onoff= LOW;}}else{buttonStateOld =buttonState;}}else{buttonStateOld =buttonState;}if (onoff==LOW){clockdate();}if (timefix==HIGH && j>0 && onoff==LOW){unsigned long delaytime=j60000;//把分钟打算成秒if ((millis()-buttonHoldTime)>=delaytime ){do{buttonState = digitalRead(button);ting();}while (buttonState==LOW);//当按下按钮后,停滞蜂鸣j=0;}else{clockdate();}}delay(1000);}
这个代码中,初始韶光是设定好的,即2013年11月9日22点56分,因此本程序没有加入时钟韶光设定功能,也可以再加上几个按钮,加上韶光调节功能。其余在判断按钮按下韶光这里,本程序的方法自我觉得有时笨,但也没想出更好的方法,哪位有更好的方法,请给辅导一下,感激。
四、实现效果实现过程中,创造存在两个问题,一个是按钮不是很灵敏,另一个是末了再退出调时状态时,长按3秒,韶光会增加1分钟。如原来设定12分钟,退出时长按3秒会依然会变成13分钟。