对于DOS下的编译器还没有delay函数(比如MSVC1.52编译器)的同仁来说,它很有用!
word Get8253Count(void)
{
typedef union {
word wData;
struct {
byte byLow;
byte byHigh;
} byData;
} WORD_BYTE_UNION;
#define IoDelay() outportb(0xeb, 0) // 自定义一个空函数, 这样的语句肯定不会被编译器优化
WORD_BYTE_UNION wCount;
disable();
outportb(0x43, 0); // Timer 8253-5, 0 - 计数器0,计数器锁存操作,工作在方式0,二进制计数
IoDelay();
wCount.byData.byLow = inportb(0x40);
IoDelay();
wCount.byData.byHigh = inportb(0x40);
enable();
wCount.wData = ~wCount.wData;
return wCount.wData;
}
/***
*void xdelay(unsigned int milliseconds)
*
*Purpose:
* Make an exactly millisecond delay
*
*Entry:
* unsigned int milliseconds - The delay time (millisecond)
*
*Exit:
* void
*
*Exceptions:
* Note:
* .This function was created by Denny at 10/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.
* .E-mail: silitex@yeah.net
*
*******************************************************************************/
void xdelay(unsigned int milliseconds)
{
typedef union {
dword dwData;
struct {
word wLow;
word wHigh;
} wData;
} DWORD_WORD_UNION;
word wBase;
DWORD_WORD_UNION dwTotal;
DWORD_WORD_UNION dwCurr;
wBase = Get8253Count();
dwTotal.dwData = (dword)wBase + (dword)milliseconds*1193;
while (TRUE)
{
dwCurr.dwData = Get8253Count();
if (dwCurr.dwData >= dwTotal.dwData)
break;
if (dwCurr.wData.wLow >= wBase)
goto delay_Continue;
if (dwTotal.wData.wHigh == 0)
break;
dwTotal.wData.wHigh--;
delay_Continue:
wBase = dwCurr.wData.wLow;
}
}