js 定义函数返回值一个无返回值函数,具有unsigned int 参数,实现可调时间的软件延时

中国领先的IT技术网站
51CTO旗下网站
Arduino函数速查中文版
《Arduino开发从零开始学:学电子的都玩这个》附录Arduino函数速查中文版,本附录中特意给出一个速查手册,希望能帮到读者。本节为大家介绍Arduino函数速查中文版。
作者:宋楠/韩广义来源:清华大学出版社| 18:52
附录& Arduino函数速查中文版
Arduino函数可以帮助我们方便地调用主板提供的一些既有功能,由于Arduino函数的中文资料很少,我们在这个附录中特意给出一个速查手册,希望能帮到读者。
1.millis()
这是一个不断更新时间值的函数。它返回Arduino板从开始运行到现在的时间,单位是毫秒(1秒=1000毫秒)。这个时间不会停止,但计时溢出时(大概需要50天时间),会归零从新开始计时。
函数原型:
unsigned&long&millis&(void)&
参数:无。
函数返回值为unsigned long型,如果用int型保存时间将得到错误结果。
2.micros()
这是一个不断更新时间值的函数。它返回Arduino板从开始运行到现在的时间,单位是微秒。mills()函数返回以毫秒表示的时间,而micros()函数返回以微秒表示的时间。micros()在计时溢出后同样会归零从新开始计时。mills()函数会在程序运行50天后溢出,而micros()函数在程序运行70分钟后溢出。
函数原型:
unsigned&long&&micros(void)&
参数:无。
1毫秒=1000微秒,1秒=1000000微秒。
3.delay(ms)
这是一个延时函数,表示延长多少时间(毫秒),没有返回值。
函数原型:
void&delay&(unsigned&long&ms)&
参数:ms表示延迟的毫秒数。
4.delayMicroseconds(us)
这是一个延时函数,表示延长多少时间(微秒),没有返回值。如果延时有几千微秒的话,建议用delay()函数。
函数原型:
void&delayMicroseconds&(unsigned&int&us)&
参数:延长的微秒数,目前参数最大支持16383微妙(不过以后的版本中可能会变化)。
喜欢的朋友可以添加我们的微信账号:
51CTO读书频道二维码
51CTO读书频道活动讨论群:
【责任编辑: TEL:(010)】&&&&&&
大家都在看猜你喜欢
热点热点头条头条热点
24H热文一周话题本月最赞
讲师:427140人学习过
讲师:112118人学习过
讲师:119828人学习过
精选博文论坛热帖下载排行
本书对前沿而又成熟的系统分析技术和方法进行了讨论,包括CMM与过程改进、J2EE与NET平台、中间件及相关技术、应用服务器、Web 服务、数据...
订阅51CTO邮刊延时时间计算_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
延时时间计算
阅读已结束,下载文档到电脑
想免费下载更多文档?
定制HR最喜欢的简历
下载文档到电脑,方便使用
还剩8页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢《Linux Device Drivers》 第七章 时间、延时及延缓操作——note
时间: 22:44:51
&&&& 阅读:205
&&&& 评论:
&&&& 收藏:0
标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&
度量时间差
内核通过定时器中断来跟踪时间流时钟中断由系统定时硬件以周期性的间隔产生,这个间隔由内核根据HZ的值设定,在常见的x86 PC平台上,默认定义为1000&linux/param.h&&linux/timex.h&jiffies_64unsigned long jiffies使用jiffies计数器
&linux/jiffies.h&
int time_after(unsigned long a, unsigned long b);int time_before(unsigned long a, unsigned long b);int time_after_eq(unsigned long a, unsigned long b);int time_before_eq(unsigned long a, unsigned long b);
通常只需要包含&linux/sched.h&diff = (long)t2 -(long)t1msec = diff * 1000 / HZ&linux/times.h
unsigned long timespec_to_jiffies(struct timespec *value);void jiffies_to_timespec(unsigned long jiffies, struct timespec *value);unsigned long timeval_to_jiffies(struct timeval *value);void jiffies_to_timeval(unsigned long jiffies, struct timeval *value);
u64 get_jiffies_64(void);&linux/types.h&proc/interrupts
处理器特定的寄存器
最有名的计数器寄存器就是TSC&asm/msr.h&
rdtsc(low32, high32);rdtscl(low32);rdtscl1(var64);
&linux/timex.h&
cycles_t get_cycles(void);
define rdtscl(dest) __asm__ __volatile__(“mfs0 %0,$9; nop” : “=r” (dest))
获取当前时间
内核提供将墙钟时间转换为jiffies值的函数&linux/time.h&
unsigned long mktime(unsigned int year, unsigned int mon, unsigned int day, unsigned int hour, unsigned int min, unsigned int sec);void do_gettimeofday(struct timeval *tv);struct timespec current_kernel_time(void);
while (time_before(jiffies, j1)) cpu_relax();
让出处理器
在不需要CPU时主动释放CPU&linux/sched.h&while (time_before(jiffies, j1)) schedule();
&linux/wait.h&
long wait_event_timeout(wait_queue_head_t q, condition c, long timeout);long wait_event_interruptible_timeout(wait_queue_head_t q, condition c, long timeout);timeout值表示的是要等的jiffies值,而不是绝对时间值如果超时到期,两个函数返回0;如果进程由其他事件唤醒,则返回剩余的延迟实现
&linux/sched.h&
signed long schedule_timeout(signed long timeout);set_current_state(TASK_INTERRUPTIBLE);schedule_timeout(delay);
&linux/delay.h&
void ndelay(unsigned long nsecs);void udelay(unsigned long usecs);void mdelay(unsigned long msecs);这三个延迟函数均是忙等待函数unsigned long msleep_interruptible(unsigned int millisecs);void ssleep(unsigned int seconds);
内核定时器
一个内核定时器是一个数据结构,它告诉内核在用户定义的时间点使用用户定义的参数来执行一个用户定义的函数内核定时器常常是作为“软件中断”的结果而运行的如果处于进程上下文之外,则必须遵守如下规则
不允许访问用户空间current指针在原子模式下是没有任何意义的,也是不可用的不能执行休眠或调度
&asm/hardirq.h&
in_interrupt()in_atomic()
任务可以将自己注册以在稍后的时间重新运行即使在单处理器系统上,定时器也会是竞态的潜在来源定时器API
&linux/timer.h&
struct timer_list
uvoid (*function)(unsigned long);
void init_timer(struct timer_list *time);struct timer_list TIMER_INITIALIZER(_function, _expires, _data);void add_timer(struct timer_list *timer);int del_timer(struct timer_list *timer);expires字段表示期望定时器执行的jiffies值int mod_timer(struct timer_list *timer, unsigned long expires);int del_timer_sync(struct timer_list *timer);int timer_pending(const struct timer_list *timer);
内核定时器的实现
内核定时器的实现要满足如下需求及假定
定时器的管理必须尽可能做到轻量级其设计必须在活动定时器大量增加时具有很好的伸缩性大部分定时器会在最多几秒或者几分钟内到期,而很少存在长期延迟的定时器定时器应该在注册它的同一CPU上运行
不管何时内核代码注册了一个定时器,其操作最终会由internal_add_timer(定义在kernel/timer.c)执行级联表的工作方式如下
如果定时器在接下来的0~255的jiffiew中到期,由该定时器就会被添加到256个链表中的一个(取决于expires字段的低8位值)如果定时器在较远的未来到期(但在16384个jiffies之前),则该定时器会被添加到64个链表之一(取决于expires字段的9~14位)对更远将来的定时器,相同的技巧用于15~20位、21~26位以及27~31位如果定时器的expires字段代表了更远的未来,则利用延迟0xfffffff做散列运算,而在过去时间内到期的定时器会在下一个定时器滴答时被调度
当__run_times被激发时,它会执行当前定时器滴答上的所有挂起的定时器
中断管理中大量使用了这种机制始终在中断期间运行,始终会在调度它的同一CPU运行,接收一个unsigned long参数不能要求tasklet在某个给定时间执行&linux/interrupt.h&
struct tasklet_struct
void (*func)(unsigned long);
void tasklet_init(struct tasklet_struct *t, void (*func)(unsigned long), unsigned long data);DECLARE_TASKLET(name, func, data);DECLARE_TASKLET_DISABLED(name, func, data);
有意思的特性
一个tasklet可以稍后被禁止或者重新启用;只有启用的次数和禁止的次数相同时,tasklet才会被执行和定时器类似,tasklet可以注册自己本身tasklet可被调度以在通常的优先级或者高优先级执行如果系统负荷不重,则tasklet会立即得到执行,但始终不会晚于下一个定时器滴答一个tasklet可以和其他tasklet并发,但对自身来讲是严格串行处理的
void tasklet_disable(struct tasklet_struct *t);void tasklet_disable_nosync(struct tasklet_struct *t);void tasklet_enable(struct tasklet_struct *t);void tasklet_schedule(struct tasklet_struct *t);void tasklet_hi_schedule(struct tasklet_struct *t);void tasklet_kill(struct tasklet_struct *t);tasklet的实现在kernel/softirq.c中
与tasklet区别
tasklet在软件中断上下文中运行,因此,所有的tasklet代码都必须是原子的。相反,工作队列函数在一个特殊内核进程的上下文中运行,因此它们具有更好的灵活性。尤其是,工作队列函数可以休眠tasklet始终运行在被初始提交的同一处理器上,但这只是工作队列的默认方式内核代码可以请求工作队列函数的执行延迟给定的时间间隔
工作队列函数可具有更长的延迟并且不必原子化&linux/workqueue.h&
struct workqueue_structstruct workqueue_struct *create_workqueue(const char *name);struct workqueue_struct *create_singlethread_workqueue(const char *name);struct work_structDECLARE_WORK(name, void (*function)(void*), void *data);INIT_WORK(struct work_struct *work, void (*function)(void *), void *data);PREPARE_WORK(struct work_struct *work, void (*function)(void *), void *data);int queue_work(struct workqueue_struct *queue, struct work_struct *work);int queue_delayed_work(struct workqueue_struct *queue, struct work_struct *work, unsigned long delay);以上两个函数返回值为非零时意味着给定的work_struct结构已经等待在该队列中int cancel_delayed_work(struct work_struct *work);
该入口项在开始执行前被取消,则返回非零值
void flush_workqueue(struct workqueue_struct *queue);void destroy_workqueue(struct workqueue_struct *queue);
int schedule_work(struct work_struct *work);void flush_scheduled_work(void)
小结:1. Linux基于时钟中断跟踪,系统时间流。
&&&&&&&&&& 2.定时器、任务必须遵循在原子上下文,定时器可以指定将来的调度时间,任务无法指定执行的时间。
&&&&&&&&&& 3.工作队列,调度的函数可以休眠。
标签:&&&&&&&&&&&&&&&&&&&&&&&&&&&原文:http://blog.csdn.net/luopingfeng/article/details/
教程昨日排行
&&国之画&&&& &&&&&&
&& &&&&&&&&&&&&&&
鲁ICP备号-4
打开技术之扣,分享程序人生!51单片机精确延时实现方法 -解决方案-华强电子网
51单片机精确延时实现方法 -解决方案-华强电子网
51单片机的几种精确延时实现延时通常有两种方法:一种是硬件延时,要用到定时器/计数器,这种方法可以提高CPU的工作效率,也能做到精确延时;另一种是软件延时,这种方法主要采用循环体进行。   1 使用定时器/计数器实现精确延时   单片机系统一般常选用11.059 2 MHz、12 MHz或6 MHz晶振。第一种更容易产生各种标准的波特率,后两种的一个机器周期分别为1 μs和2 μs,便于精确延时。
51单片机的几种精确延时实现延时通常有两种方法:一种是硬件延时,要用到定时器/计数器,这种方法可以提高CPU的工作效率,也能做到精确延时;另一种是软件延时,这种方法主要采用循环体进行。   1 使用定时器/计数器实现精确延时   单片机系统一般常选用11.059 2 MHz、12 MHz或6 MHz晶振。第一种更容易产生各种标准的波特率,后两种的一个机器周期分别为1 μs和2 μs,便于精确延时。本程序中假设使用频率为12 MHz的晶振。最长的延时时间可达216=65 536 μs。若定时器工作在方式2,则可实现极短时间的精确延时;如使用其他定时方式,则要考虑重装定时初值的时间(重装定时器初值占用2个机器周期)。   在实际应用中,定时常采用中断方式,如进行适当的循环可实现几秒甚至更长时间的延时。使用定时器/计数器延时从程序的执行效率和稳定性两方面考虑都是最佳的方案。但应该注意,C51编写的中断服务程序编译后会自动加上PUSH ACC、PUSH PSW、POP PSW和POP ACC语句,执行时占用了4个机器周期;如程序中还有计数值加1语句,则又会占用1个机器周期。这些语句所消耗的时间在计算定时初值时要考虑进去,从初值中减去以达到最小误差的目的。   2 软件延时与时间计算   在很多情况下,定时器/计数器经常被用作其他用途,这时候就只能用软件方法延时。下面介绍几种软件延时的方法。   2.1 短暂延时   可以在C文件中通过使用带_NOP_( )语句的函数实现,定义一系列不同的延时函数,如Delay10us( )、Delay25us( )、Delay40us( )等存放在一个自定义的C文件中,需要时在主程序中直接调用。如延时10 μs的延时函数可编写如下:   void Delay10us( ) {   _NOP_( );   _NOP_( );   _NOP_( );   _NOP_( );   _NOP_( );   _NOP_( );   }   Delay10us( )函数中共用了6个_NOP_( )语句,每个语句执行时间为1 μs。主函数调用Delay10us( )时,先执行一个LCALL指令(2 μs),然后执行6个_NOP_( )语句(6 μs),最后执行了一个RET指令(2 μs),所以执行上述函数时共需要10 μs。 可以把这一函数当作基本延时函数,在其他函数中调用,即嵌套调用\[4\],以实现较长时间的延时;但需要注意,如在Delay40us( )中直接调用4次Delay10us( )函数,得到的延时时间将是42 μs,而不是40 μs。这是因为执行Delay40us( )时,先执行了一次LCALL指令(2 μs),然后开始执行第一个Delay10us( ),执行完最后一个Delay10us( )时,直接返回到主程序。依此类推,如果是两层嵌套调用,如在Delay80us( )中两次调用Delay40us( ),则也要先执行一次LCALL指令(2 μs),然后执行两次Delay40us( )函数(84 μs),所以,实际延时时间为86 μs。简言之,只有最内层的函数执行RET指令。该指令直接返回到上级函数或主函数。如在Delay80μs( )中直接调用8次Delay10us( ),此时的延时时间为82 μs。通过修改基本延时函数和适当的组合调用,上述方法可以实现不同时间的延时。   2.2 在C51中嵌套汇编程序段实现延时   在C51中通过预处理指令#pragma asm和#pragma endasm可以嵌套汇编语言语句。用户编写的汇编语言紧跟在#pragma asm之后,在#pragma endasm之前结束。   如:#pragma asm   …   汇编语言程序段   …   #pragma endasm   延时函数可设置入口参数,可将参数定义为unsigned char、int或long型。根据参数与返回值的传递规则,这时参数和函数返回值位于R7、R7R6、R7R6R5中。在应用时应注意以下几点:   ◆ #pragma asm、#pragma endasm不允许嵌套使用;   ◆ 在程序的开头应加上预处理指令#pragma asm,在该指令之前只能有注释或其他预处理指令;   ◆ 当使用asm语句时,编译系统并不输出目标模块,而只输出汇编源文件;   ◆ asm只能用小写字母,如果把asm写成大写,编译系统就把它作为普通变量;   ◆ #pragma asm、#pragma endasm和 asm只能在函数内使用。   将汇编语言与C51结合起来,充分发挥各自的优势,无疑是单片机开发人员的最佳选择。   2.3 使用示波器确定延时时间   利用示波器来测定延时程序执行时间。方法如下:编写一个实现延时的函数,在该函数的开始置某个I/O口线如P1.0为高电平,在函数的最后清P1.0为低电平。在主程序中循环调用该延时函数,通过示波器测量P1.0引脚上的高电平时间即可确定延时函数的执行时间。方法如下:   sbit T_point = P1^0;   void Dly1ms(void) {   unsigned int i,j;   while (1) {   T_point = 1;   for(i=0;i《2;i++){   for(j=0;j《124;j++){;}   }   T_point = 0;   for(i=0;i《1;i++){   for(j=0;j《124;j++){;}   }   }   }   void main (void) {   Dly1ms();   }   把P1.0接入示波器,运行上面的程序,可以看到P1.0输出的波形为周期是3 ms的方波。其中,高电平为2 ms,低电平为1 ms,即for循环结构“for(j=0;j《124;j++) {;}”的执行时间为1 ms。通过改变循环次数,可得到不同时间的延时。当然,也可以不用for循环而用别的语句实现延时。这里讨论的只是确定延时的方法。   2.4 使用反汇编工具计算延时时间   用Keil C51中的反汇编工具计算延时时间,在反汇编窗口中可用源程序和汇编程序的混合代码或汇编代码显示目标应用程序。为了说明这种方法,还使用“for (i=0;i   C:0x000FE4CLRA//1T   C:0x0010FEMOVR6,A//1T   C:0x0011EEMOVA,R6//1T   C:0x0012C3CLRC//1T   C:0x00139FSUBBA,DlyT //1T   C:0xJNCC:0019//2T   C:0x00160E INCR6//1T   C:0xSJMPC:0011//2T   可以看出,0x000F~0x0017一共8条语句,分析语句可以发现并不是每条语句都执行DlyT次。核心循环只有0x7共6条语句,总共8个机器周期,第1次循环先执行“CLR A”和“MOV R6,A”两条语句,需要2个机器周期,每循环1次需要8个机器周期,但最后1次循环需要5个机器周期。DlyT次核心循环语句消耗(2+DlyT&TI8+5)个机器周期,当系统采用12 MHz时,精度为7 μs。   当采用while (DlyT--)循环体时,DlyT的值存放在R7中。相对应的汇编代码如下:   C:0x000FAE07MOVR6, R7//1T   C:0x00111F DECR7//1T   C:0x0012EE MOVA,R6//1T   C:0x001370FAJNZC:000F//2T   循环语句执行的时间为(DlyT+1)&TI5个机器周期,即这种循环结构的延时精度为5 μs。   通过实验发现,如将while (DlyT--)改为while (--DlyT),经过反汇编后得到如下代码:   C:0x0014DFFE DJNZR7,C:0014//2T   可以看出,这时代码只有1句,共占用2个机器周期,精度达到2 μs,循环体耗时DlyT&TI2个机器周期;但这时应该注意,DlyT初始值不能为0。   注意:计算时间时还应加上函数调用和函数返回各2个机器周期时间。
型号/产品名
深圳市鑫蓝丰电子有限公司
深圳市硅虎电子有限公司
广州红升电子科技有限公司
广州红升电子科技有限公司
深圳市福田区赛格电子市场科利源电子商柜

我要回帖

更多关于 js定义有返回值的函数 的文章

 

随机推荐