前言
同学毕设做信号辨识,需要严格设计时钟信号,对于信号的精确产生有很高的需求,因此使用matlab的timer对象来实现该需求,本着学一个技术就要学精的原则,深入了解了matlab timer背后的实现原理,现将学习成果分享给大家。
主体
任务描述如下:
1多次执行回调函数:
显示这个事件和在计时器开始运作,运行,和结束时的日期/时间产出。计时器回调函数会以2秒的间隔执行三次。回调函数传递的前两条语句是定时器对象和事件结构的句柄。
事件结构有两个成员:类型定义了回调函数的来源,数据则是一个包含事件什么时候发生的日期时间的向量。
t = timer;
t.StartFcn = @(~,thisEvent)disp([thisEvent.Type ' executed '...
datestr(thisEvent.Data.time,'dd-mmm-yyyy HH:MM:SS.FFF')]);
t.TimerFcn = @(~,thisEvent)disp([thisEvent.Type ' executed '...
datestr(thisEvent.Data.time,'dd-mmm-yyyy HH:MM:SS.FFF')]);
t.StopFcn = @(~,thisEvent)disp([thisEvent.Type ' executed '...
datestr(thisEvent.Data.time,'dd-mmm-yyyy HH:MM:SS.FFF')]);
t.Period = 2;
t.TasksToExecute = 3;
t.ExecutionMode = 'fixedRate';
start(t)
输出如下:
StartFcn executed 25-May-2018 20:12:16.344
TimerFcn executed 25-May-2018 20:12:19.345
TimerFcn executed 25-May-2018 20:12:21.345
TimerFcn executed 25-May-2018 20:12:23.345
StopFcn executed 25-May-2018 20:12:23.351
同样记得删除这个定时器:
delete(t)
2定义一个通用的回调函数
创建一个定时器对象来提示你在接下来的8小时中每10分钟学习30秒。
在一个名为createErgoTimer.m的文件里面创建一个返回定时器的函数。
在这个文件里包含着三个局部函数来处理定时器开始,执行和结束任务。
代码如下:
function t = createErgoTimer()
secondsBreak = 30;
secondsBreakInterval = 600;
secondsPerHour = 60^2;
secondsWorkTime = 8*secondsPerHour;
t = timer;
t.UserData = secondsBreak;
t.StartFcn = @ergoTimerStart;
t.TimerFcn = @takeBreak;
t.StopFcn = @ergoTimerCleanup;
t.Period = secondsBreakInterval+secondsBreak;
t.StartDelay = t.Period-secondsBreak;
t.TasksToExecute = ceil(secondsWorkTime/t.Period);
t.ExecutionMode = 'fixedSpacing';
end
使用起始延迟函数允许定时器在没有指引你立即休息的情况下启动计时器。
将执行模式设置为固定空间,因此在一个时间函数执行完后将是一个固定的耗散周期10分钟30秒。这会允许你在下个10分钟的间隔之间有30秒的休息时间。
在之间新建的createErgo.m文件中,增加一个本地函数来处理对应与定时器开始的任务。作为默认,定时器对象将它自己和事件数据传递给回调函数。这个函数忽略事件数据
function ergoTimerStart(mTimer,~)
secondsPerMinute = 60;
secondsPerHour = 60*secondsPerMinute;
str1 = 'Starting Ergonomic Break Timer. ';
str2 = sprintf('For the next %d hours you will be notified',...
round(mTimer.TasksToExecute*(mTimer.Period + ...
mTimer.UserData)/secondsPerHour));
str3 = sprintf(' to take a %d second break every %d minutes.',...
mTimer.UserData, (mTimer.Period - ...
mTimer.UserData)/secondsPerMinute);
disp([str1 str2 str3])
end
增加一个局部函数来处理和执行和任务相关的定时器。定义的定时任务回调函数应该告诉你应该休息30秒。
function takeBreak(mTimer,~)
disp('Take a 30 second break.')
end
增加一个局部函数来处理和计时器停止相关的任务。
function ergoTimerCleanup(mTimer,~)
disp('Stopping Ergonomic Break Timer.')
delete(mTimer)
end
从内存中删除计时器任务。
在命令行输入createErgoTimer函数来创建和开始一个定时器。
t = createErgoTimer;
start(t)
运行结果
Starting Ergonomic Break Timer.
For the next 8 hours you will be notified to take a 30 second break every 10 minutes.
Take a 30 second break.
周期休息定时器。
开始周期休息定时器。在接下来的八个小时中每10分钟你会被提醒一次休息30秒。
你可以让这个定时器运行八小时也可以手动停止它。包括在内存里面消除这个定时器。
stop(t)
停止周期间隔定时器。
参考:
mathwork官方文档