免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1419 | 回复: 4
打印 上一主题 下一主题

不受条件影响的delay()涵数 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-12-05 14:37 |只看该作者 |倒序浏览
void DELAY(int clicks)
{
unsigned int far *clock=(unsigned int far *)0x0000046CL;   
unsigned int now;
now=*clock;
while(abs(*clock-now)<clicks){}

}


大侠们里面有点不懂.

这里说是直接读取存放时钟片数据地址获得时间间隔.

那abs(*clock-now)   为什么要abs 呢?意未着    *clock一定小于now吗?
怎么理解?请举个例子啊

论坛徽章:
0
2 [报告]
发表于 2005-12-05 14:56 |只看该作者
防止回绕吧,猜的

论坛徽章:
0
3 [报告]
发表于 2005-12-05 14:59 |只看该作者
原帖由 linuxcici 于 2005-12-5 14:37 发表
void DELAY(int clicks)
{
unsigned int far *clock=(unsigned int far *)0x0000046CL;   
unsigned int now;
now=*clock;
while(abs(*clock-now)<clicks){}

}


大侠们里面有点不懂.

这里说是直 ...

*clock是有可能小于等于now的。

论坛徽章:
0
4 [报告]
发表于 2005-12-05 15:08 |只看该作者

  1. void DELAY(int clicks)
  2. {
  3.        unsigned int far *clock=(unsigned int far *)0x0000046CL;   //这应当是一个时钟的端口地址
  4.        unsigned int now;
  5.        now=*clock;         //读入端口的值,也就是时钟的滴答数
  6.        while(abs(*clock-now)<clicks)       //将从端口读入的值和当前时间比较,直到时间差大于延时值才退出循环体,延时结束。
  7.         {
  8.         }

  9. }
复制代码


那abs(*clock-now)   为什么要abs 呢?意未着    *clock一定小于now吗?

时钟实际上只不过是一个计数器,假定用的是一个16位计数器,你可以把它初值值为零,然后让它增加,或者把它设置成65535,然后让它减少。至于增还是减,是由定时器的编程人员决定的,所以给他加上abs,对增还是减都适用。

具体情况找一本微机原理看一下,应当是8254芯片吧。

ps: 请加code标记。别人好读一些,也有利于你问题的解决。

论坛徽章:
0
5 [报告]
发表于 2005-12-05 18:40 |只看该作者
下载一本书的时候正好翻到,里面利用8253做汇编代码的性能测试,其中提到
        Finally, timer 0 is used to drive the system clock.  As programmed by the BIOS at power-up, every 65,536 (64 K) counts, or 54.925 milliseconds, timer 0 generates a rising edge on its output line.  (A millisecond is one-thousandth of a second, and is abbreviated ms).  This line is connected to the hardware interrupt 0 (IRQ0) line on the system board, so every 54.925 ms timer 0 causes hardware interrupt 0 to occur.
        The interrupt vector for IRQ0 is set by the BIOS at power-up time to point to a BIOS routine, TIMER_INT, that maintains a time-of-day count.  TIMER_INT keeps a 16-bit count of IRQ0 interrupts in the BIOS data area at address 0000:046C (all addresses are given in segmentffset hexadecimal pairs); this count turns over once an hour (less a few microseconds), and when it does, TIMER_INT updates a 16-bit hour count at address 0000:046E in the BIOS data area.  This routine is the basis for the current time and date that DOS supports via functions 2Ah (2A hexadecimal) through 2Dh and by way of the DATE and TIME commands.

看来*clock就是bios保存的每秒18.2次的那个tick计数的低16位
不过这代码好象有问题啊
应该是16位的dos编译器吧,假设clicks=2,now=65535,*clock回绕到0的时候,虽然避免了陷入长达1小时的delay,但是循环却提前结束了
另外,clock指针应该声明为volatile吧,否则编译器有可能把while优化成死循环
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP