📄 timer.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 + -