DOS下面關於精確延時1ms的函式(理論上可以非常精確延時到10微妙級別)
阿新 • • 發佈:2019-02-15
在微軟的MSC7.0以及MSVC1.52下面都沒有Borland C++的精確延時函式:delay(經過測試可以非常精確的延時到1ms)
同時看了一下計時器的相關內容,自己寫了一個精確延時函式,但不敢保證在所有的電腦上都可以精確延時
原始碼:
/***
*void xdelay(unsigned int ms)
*
*Purpose:
* Make an exactly millisecond delay
*
*Entry:
* unsigned int ms - The delay time (millisecond)
*
*Exit:
* void
*
*Exceptions:
* Note:
* .This function was created by Denny at Jun/26/2008
* .Dongguan Siliten Electronics CO., LTD.
* .The timer frequency is 1193180Hz
* .The timer counter is 16bits, so only elapsed 55ms for/
* counter a circle.
*
*******************************************************************************/
void xdelay(unsigned int ms)
{
unsigned int base_counter;
unsigned int circle;
unsigned int counter;
unsigned int last_counter;
unsigned long end;
unsigned long cur;
disable();
//outportb(0x43, 0x30);
base_counter = inportb(0x40);
base_counter += inportb(0x40)<<8;
enable();
circle = 0;
last_counter = 0;
end = (unsigned long)ms*1193;
cur = 0;
while (end > cur)
{
disable();
counter = inportb(0x40);
counter += inportb(0x40)<<8;
enable();
counter = base_counter - counter;
if (counter-last_counter > 50) // Illegal data
{
last_counter = counter;
continue;
}
if ( (counter < last_counter) && (last_counter > 65000) && (counter < (65536-65000)) )
circle++;
cur = ((unsigned long)circle<<16) + counter;
//printf("base:%u|cir:%u|cnt:%u|last:%u|end:%lu|cur:%lu/n", base_counter, circle, counter, last_counter, end, cur);
last_counter = counter;
}
}
下面是測試程式:
ClrScr();
for (i = 0; i < 5; i++)
{
printf("delay(1000):%d/r/n", i);
for (j = 0; j < 1; j++)
delay(1000);
}
for (i = 0; i < 5; i++)
{
printf("delay(100):%d/r/n", i);
for (j = 0; j < 10; j++)
delay(100);
}
for (i = 0; i < 5; i++)
{
printf("delay(10):%d/r/n", i);
for (j = 0; j < 100; j++)
delay(10);
}
for (i = 0; i < 5; i++)
{
printf("delay(1):%d/r/n", i);
for (j = 0; j < 1000; j++)
delay(1);
}
同時看了一下計時器的相關內容,自己寫了一個精確延時函式,但不敢保證在所有的電腦上都可以精確延時
原始碼:
/***
*void xdelay(unsigned int ms)
*
*Purpose:
* Make an exactly millisecond delay
*
*Entry:
* unsigned int ms - The delay time (millisecond)
*
*Exit:
* void
*
*Exceptions:
* Note:
* .This function was created by Denny at Jun/26/2008
* .Dongguan Siliten Electronics CO., LTD.
* .The timer frequency is 1193180Hz
* .The timer counter is 16bits, so only elapsed 55ms for/
* counter a circle.
*
*******************************************************************************/
void xdelay(unsigned int ms)
{
unsigned int base_counter;
unsigned int circle;
unsigned int counter;
unsigned int last_counter;
unsigned long end;
unsigned long cur;
disable();
//outportb(0x43, 0x30);
base_counter = inportb(0x40);
base_counter += inportb(0x40)<<8;
enable();
circle = 0;
last_counter = 0;
end = (unsigned long)ms*1193;
cur = 0;
while (end > cur)
{
disable();
counter = inportb(0x40);
counter += inportb(0x40)<<8;
enable();
counter = base_counter - counter;
if (counter-last_counter > 50) // Illegal data
{
last_counter = counter;
continue;
}
if ( (counter < last_counter) && (last_counter > 65000) && (counter < (65536-65000)) )
circle++;
cur = ((unsigned long)circle<<16) + counter;
//printf("base:%u|cir:%u|cnt:%u|last:%u|end:%lu|cur:%lu/n", base_counter, circle, counter, last_counter, end, cur);
last_counter = counter;
}
}
下面是測試程式:
ClrScr();
for (i = 0; i < 5; i++)
{
printf("delay(1000):%d/r/n", i);
for (j = 0; j < 1; j++)
delay(1000);
}
for (i = 0; i < 5; i++)
{
printf("delay(100):%d/r/n", i);
for (j = 0; j < 10; j++)
delay(100);
}
for (i = 0; i < 5; i++)
{
printf("delay(10):%d/r/n", i);
for (j = 0; j < 100; j++)
delay(10);
}
for (i = 0; i < 5; i++)
{
printf("delay(1):%d/r/n", i);
for (j = 0; j < 1000; j++)
delay(1);
}