一 : FullCalendar应用——拖动与实时保存
我们可以使用FullCalendar建立一个非常强大的日历程序,用户可以轻松的在FullCalendar操作日程安排,诸如新建、修改、删除等操作以及本文将要讲解的拖动、缩放日程事件。
我们将日程页面命名为drag.html,首先是要载入jQuery库,jQuery ui以及fullcalendar插件。
<script src='js/jquery-1.9.1.min.js'>
<script src='js/jquery-ui-1.10.3.custom.min.js'>
<script src='js/fullcalendar.min.js'>
然后在body中,建立日历容器div#calendar。
<div id="calendar">
FullCalendar提供了可拖动日程事件的方法,但必须依赖jquery ui的draggable插件。当拖动完毕后,eventDrop回调函数中,我们使用post方式向后台php发送ajax请求,请求的参数包括id:当前拖动事件的id唯一标识,daydiff:拖动前后的天数变更(天数偏移量),minudiff:拖动前后分钟变更(分钟偏移量),allday:是否为全天事件。然后接收后台php处理的结果,如果返回的不是1(拖动处理失败),就弹出提示信息,并且将日程事件恢复到拖动前的状态,请看代码:
$(function() {
events: 'json.php', //事件数据源
editable: true, //允许拖动
dragOpacity: {//设置拖动时事件的透明度
agenda: .5,
'':.6
},
//拖动事件
eventDrop: function(event,dayDelta,minuteDelta,allDay,revertFunc) {
$.post("do.php?action=drag",{id:event.id,daydiff:dayDelta,
minudiff:minuteDelta,allday:allDay},function(msg){
if(msg!=1){
alert(msg);
revertFunc(); //恢复原状
}
});
}
});
当拖动结束时,FullCalendar向后台do.php发送了ajax请求。和增删改操作一样,do.php接收action动作参数,首先处理post过来的内容,然后查询数据表中对应的日程事件项,根据是否为全天事件以及是否有结束时间两个条件来构造不同的SQL语句,最后更新数据表,并返回处理结果,请看代码:
...
}elseif($action=="drag"){//拖动
$id = $_POST['id'];
$daydiff = (int)$_POST['daydiff']*24*60*60;
$minudiff = (int)$_POST['minudiff']*60;
$allday = $_POST['allday'];
$query = mysql_query("select * from `calendar` where id='$id'");
$row = mysql_fetch_array($query);
if($allday=="true"){//如果是全天事件
if($row['endtime']==0){
$sql = "update `calendar` set starttime=starttime+'$daydiff' where id='$id'";
}else{
$sql = "update `calendar` set starttime=starttime+'$daydiff',endtime=endtime
+'$daydiff' where id='$id'";
}
}else{
$difftime = $daydiff + $minudiff;
if($row['endtime']==0){
$sql = "update `calendar` set starttime=starttime+'$difftime' where id='$id'";
}else{
$sql = "update `calendar` set starttime=starttime+'$difftime',endtime=endtime
+'$difftime' where id='$id'";
}
}
$result = mysql_query($sql);
if(mysql_affected_rows()==1){
echo '1';
}else{
echo '出错了!';
}
}
以上代码关键在于处理日程事件的开始时间和结束事件,这样,就实现了可以任意拖动日程事件项并实时保存,看下demo,是不是很酷哦。
关于日程事件的缩放
所谓缩放,其实就是用户可以直接在日历视图中将日程事件拉长和缩短,比如事件为一天的变成两天,10:00结束的会议变成9:30,只需在日历视图中将对应的日程事件项向右(月视图)或向下(周视图和日视图)拉长或缩短。使用FullCalendar提供的eventResize方法轻松搞定。
eventResize: function(event,dayDelta,minuteDelta,revertFunc) {
$.post("do.php?action=resize",{id:event.id,daydiff:dayDelta,minudiff:minuteDelta},function(msg){
if(msg!=1){
alert(msg);
revertFunc();
}
});
}
关于选取多天
FullCalendar提供了select方法,用户可以在新建多天日程的时候,一次性选择连贯的日期,然后弹出的新建日程中会自动补全开始日期和结束日期,这个操作只需按住开始日期,然后拖动鼠标到结束日期,松开左键即可,快去demo中操作下吧。
selectable: true, //允许用户拖动
select: function( startDate, endDate, allDay, jsEvent, view ){
var start =$.fullCalendar.formatDate(startDate,'yyyy-MM-dd');
var end =$.fullCalendar.formatDate(endDate,'yyyy-MM-dd');
$.fancybox({
'type':'ajax',
'href':'event.php?action=add&date='+start+'&end='+end
});
}
关于多用户共享
要将FullCalendar应用到项目中去,一般是针对多用户使用的,如CRM系统中会有多个用户共享日程,上级可查看下级的日程安排及工作进度,同级用户不能查看对方的日程,这些需求是在项目设计的时候就得定好,当然数据库的设计是至关重要的,这里不再多描述。
不足
唯一遗憾的是日历中没有中国农历历法,哪位大神能将中国农历历法移植到FullCalendar中,将会对FullCalendar在中国的应用做出卓越的贡献。
结束
FullCalendar系列文章讲述了FullCalendar的基本应用,API文档,读取数据库,新建、修改和删除操作,以及拖动、缩放和选取,足以满足大型项目应用场景的需求,至此关于FullCalendar的文章本站就此收官,如有FullCalendar相关问题欢迎大家留言讨论,Helloweba感谢您的关注。
声明:本文为原创文章,helloweba.com和作者拥有版权,如需转载,请注明来源于helloweba.com并保留原文链接,否则视为侵权。
二 : Arduino入门笔记(7):利用1602、1302实现时钟和定时器
转载请注明:@小五义http://www.cnblogs.com/xiaowuyi
欢迎加入讨论群 64770604
常常听到老妈在做饭时说“开锅15分钟后叫我一下”,为何不做个定时器,来提醒老妈呢?结合前面学习的知识,再加上1302时间模块,我决定自己做一个。(www.61k.com]
一、本次实验所需器材
1、Arduino UNO板
2、1602液晶板:(或者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Ω电阻做为下拉电阻。具体关于按钮的使用可参考(),端口为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 time int 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);//延时1ms digitalWrite(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-2010 lcd.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); //初始化LCD pinMode(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=j*60000;//把分钟计算成秒 if ((millis()-buttonHoldTime)>=delaytime ) { do { buttonState = digitalRead(button); ting(); }while (buttonState==LOW);//当按下按钮后,停止蜂鸣 j=0; } else { clockdate(); } } delay(1000); }扩展:ds1302 lcd1602时钟 / arduino 1602 时钟 / arduino lcd1602 时钟
这个代码中,初始时间是设定好的,即2013年11月9日22点56分,因此本程序没有加入时钟时间设定功能,也可以再加上几个按钮,加上时间调节功能。另外在判断按钮按下时间这里,本程序的方法自我感觉有时笨,但也没想出更好的方法,哪位有更好的方法,请给指导一下,谢谢。
四、实现效果
实现过程中,发现存在两个问题,一个是按钮不是很灵敏,另一个是最后再退出调时状态时,长按3秒,时间会增加1分钟。如原本设定12分钟,退出时长按3秒会依然会变成13分钟。
扩展:ds1302 lcd1602时钟 / arduino 1602 时钟 / arduino lcd1602 时钟
三 : s3c2440定时器中断实例
最近用到了2440的定时器,感觉理解得还不错,分享一下。
S3c2440 有5 个16 位的定时器。定时器0、1、2、3有脉宽调制功能(PWM)。定时器4有一个没有输出引脚的内部定时器。定时器0 有一个用于大电流设备的死区生成器。
定时器0 和1 共享一个8 位的预分频器(预定标器),定时器2,3,4 共享另一个8 位预分
频器.
定时器的时钟源为PCLK,首先经过预分频器降低频率后,进入第二个分频.可以生成5 种不同的分频信号(1/2,1/4,1/8,1/16和TCLK)
定时器启动后,TCNTn开始减一计数,当TCNTn 等于TCMPn时, TOUTn 反转, TCNTn继续减数.
当TCNTn= 0 时, TOUTn 再次反转,并触发中断(中断已经使能).
若TCON 设为自动加载, TNCTn/TCMPNn 的值被重装.
寄存器:
TCFG0: 配置两个8 位预分频器, [15:8] 此8 位决定定时器2,3,4 的预标定器值,[7:0] 此8 位决定定时器0,1的预标定器值
输出频率: = PCLK / (prescaler value +1)
TCFG1:
用于设置第二个分频.可以设置5 种不同的分频信号(1/2,1/4,1/8,1/16 和TCLK)
至此可得到
定时器工作频率=PCLK / (prescaler value + 1) /(divider value)
divider value = 2,4,8,16
TCON: 定时器控制寄存器
TCNTBn :设置一个被装载到递减计数器中的初始值。
TCMPBn: 设置一个被装载到比较寄存器中用来和递减计数
器的值作比较的初始值。
TCNTOn :通过读取其可以得到TCNTBn 的值
定时器初始化示例:
//Timer input clock Frequency = PCLK / {prescaler value+1} /{divider value}
//PCLK=50Mhz
//prescaler : 0~255
#define prescaler234 99
//divider : 1/2,1/4,1/8,1/16 选择为(0,1,2,3)
#define divider4 2
//定时器设置
void __irq timer4ISP(void) //中断函数
{
rSRCPND |=rSRCPND|(0x1<<14);
rINTPND |=rINTPND|(0x1<<14);
Uart_Printf("now in timer4 interrupt~~ ");
}
void mytimer_init(void)//初始化定时器
{
Uart_Printf("timer4init/r/n");
//设置中断入口
pISR_TIMER4 = (U32)timer4ISP;
rTCFG0&=~(0xff<<8);
rTCFG0 |=prescaler234<<8;
rTCFG1&=~(0xf<<16);
rTCFG1 |=divider4<<16;
rTCNTB4 = 31250;//16位的 count bufferregister
//rTCNTO4 = //16位的 count observation value forTime 4
rTCON |=(1<<22)|(1<<21)|(1<<20);//自动装载,启动定时器
rTCON &= ~0x200000; //定时器4开始工作
//关于中断
rSRCPND |=rSRCPND|(0x1<<14);
rINTPND |=rINTPND|(0x1<<14);
rINTMSK &=~(0x1<<14);
}
61阅读| 精彩专题| 最新文章| 热门文章| 苏ICP备13036349号-1