⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 timer.c

📁 DOS 下的定时器82C54测试程序,实现中断方式的测试,描述了82C54寄存器的配置和中断的配置
💻 C
字号:
#include <bios.h>
#include <stdio.h>
#include <dos.h>

#define BASE_ADR 0x300
#define IRQ_NUM 5
typedef unsigned char uchar;
typedef unsigned int uint;

void interrupt (*OldIrqIsr)(void);
void interrupt IrqIsr(void);

void ClrIrqFlag(void)
{
	outportb(BASE_ADR+0x05, 0x00);
}

void CfgIrq(void)
{
	uchar vector;
	vector = (IRQ_NUM<8) ? (IRQ_NUM+8) : (IRQ_NUM+0x68);
	OldIrqIsr = getvect(vector);
	disable();
	setvect(vector, IrqIsr);
	enable();
}

void RestoreIrq(void)
{
	uchar vector;
	vector = (IRQ_NUM<8) ? (IRQ_NUM+8) : (IRQ_NUM+0x68);
	disable();
	setvect(vector, OldIrqIsr);
	enable();
}

void AckIrq(void)
{
	#if(IRQ_NUM >= 8)
	{
		outportb(0xA0, 0x20);
		outportb(0xA0, 0x0B);
		if(!inportb(0xA0))
			outportb(0x20, 0x20);
	}
	#else
	{
		outportb(0x20, 0x20);
	}
	#endif
}

void EnableIrq(void)
{
	int mask;
	#if (IRQ_NUM < 8)
	{
		disable();
		mask = inportb(0x21);
		mask &= ~(1<<IRQ_NUM);
		outportb(0x21, mask);
		enable();
	}
	#else
	{
    	disable();
		mask = inportb(0xA1);
		mask &= ~(1<<(IRQ_NUM-8));
		outportb(0xA1, mask);
		mask = inportb(0x21);
		mask &= 0xFB;
		outportb(0x21, mask);
		enable();
	}
	#endif
}

void DisableIrq(void)
{
	int mask;
	#if (IRQ_NUM < 8)
	{
		disable();
		mask = inportb(0x21);
		mask |= (1<<IRQ_NUM);
		outportb(0x21, mask);
		enable();
	}
	#else
	{
    	disable();
		mask = inportb(0xA1);
		mask |= (1<<(IRQ_NUM-8));
		outportb(0xA1, mask);
		enable();
	}
	#endif
}

uchar IrqFlag = 0;
void interrupt IrqIsr(void)
{
	ClrIrqFlag();
	IrqFlag = 1;
	AckIrq();
}

void SetTimerMode(uchar clock, uchar mode)
{
	uchar cfg = 0;
	cfg |= (clock<<6);
	cfg |= 0x30;
	cfg |= (mode<<1);
	outportb(BASE_ADR+0x0F, cfg);
}

void SetTimerDivisor(uchar clock, uint div)
{
	outportb(BASE_ADR+0x0C+clock, (uchar)div);
	outportb(BASE_ADR+0x0C+clock, (uchar)(div>>8));
}

void SetPwmDutyCycle(uchar pwm, uchar duty)
{
	outportb(BASE_ADR+0x06, 0x20);
	outportb(BASE_ADR+0x0A, 0xFF);
	outportb(BASE_ADR+0x0C+pwm, duty);
}

void main()
{
	uchar i;
	uint count = 0;
	clrscr();
	printf("Configuring Interrupt......\n");
	ClrIrqFlag();
	EnableIrq();
	CfgIrq();
	outportb(BASE_ADR+0x04, 0x00);
	SetTimerMode(0, 3);
	SetTimerDivisor(0, 5000);
	SetTimerMode(4, 3);
	SetTimerDivisor(4, 500);
	SetPwmDutyCycle(0, 0xf0);
	outportb(BASE_ADR+0x06, 0x0B);
	outportb(BASE_ADR+0x04, 0x02);
	printf("Done!\n");
	printf("Testing Timer Interrupt......\n");
	count = 0;
	while(bioskey(1) == 0)
	{
		if(IrqFlag == 1)
		{
			IrqFlag = 0;
			gotoxy(1, 4);
			printf("IRQ%d\n", count++);
		}
	}
	SetTimerMode(0, 0);
    ClrIrqFlag();
	RestoreIrq();
	DisableIrq();
	outportb(BASE_ADR+0x06, 0x00);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -