IO端口操作

端口操作代码

//读端口数据
UCHAR In_8(PUCHAR Port)
{
	UCHAR Value;
	__asm{
	
		mov edx,Port
		mov eax,0
		in al,dx
		mov Value,al
		nop
		nop

	}
	return Value;
}

USHORT In_16(PUSHORT Port)
{ 
	USHORT Value;
	__asm{

		mov edx, Port
		mov eax, 0
		in ax, dx
		mov Value, ax
		nop
		nop

	}
	return Value;
}

ULONG In_32(PULONG Port)
{
	ULONG Value;
	__asm{

		mov edx, Port
		mov eax, 0
		in eax, dx
		mov Value, eax
		nop
		nop

	}
	return Value;
}



//往端口写数据

void Out_8(PUCHAR Port,UCHAR Value)
{
	__asm{
	
		mov edx,Port
		mov al,Value
		out dx,al
		nop
		nop

	}
}

void Out_16(PUSHORT Port, USHORT Value)
{
	__asm{

		mov edx, Port
		mov ax, Value
		out dx, ax
		nop
		nop

	}
}

void Out_32(PULONG Port, ULONG Value)
{
	__asm{

		mov edx, Port
		mov eax, Value
		out dx, eax
		nop
		nop

	}
}

对此微软提供了对应了API
READ_PORT_UCHAR()
READ_PORT_USHORT()
READ_PORT_ULONG()

WRITE_PORT_UCHAR()
WRITE_PORT_USHORT()
WRITE_PORT_ULONG()

让PC喇叭发声

在这里插入图片描述
喇叭端口的低两位是控制开关

0x43端口 :
第0位:计数方式
0 : 代表二进制
1 : BCD 如果该8位的值是0x78h 那么值就是78
第 1 2 3位 代表时钟运行方式
第4 5位
0 0 代表寄存器已经锁存
0 1 读写8位
1 0 读写高8位
1 1 先读低8位 然后读高8位
第6 7 位的值代表选择的是哪一个计数器
0 0 代表0号计数器
0 1 代表1号计数器
1 0 代表2号计数器

在这里插入代码片
//f为输入的频率
VOID SoundOff()
{
	//读出0x61端口的值
	UCHAR Temp = READ_PORT_UCHAR((PUCHAR)0x61);
	Temp &= 0xfc;	//低两位置1 关闭喇叭开关
	WRITE_PORT_UCHAR((PUCHAR)0x61, Temp);
}
// 频率  2000
VOID Sound(ULONG f)
{
	USHORT b = 1193180 / f;
	//读出0x61端口的值
	UCHAR Temp=READ_PORT_UCHAR((PUCHAR)0x61);
	Temp |= 3;	//低两位置1 打开喇叭开关
	WRITE_PORT_UCHAR((PUCHAR)0x61,Temp);

	//配置时钟
	WRITE_PORT_UCHAR((PUCHAR)0x43,0xb6);

	//写入计数器
	WRITE_PORT_UCHAR((PUCHAR)0x42,b&0xff);
	WRITE_PORT_UCHAR((PUCHAR)0x42, (b>>8)&0xff);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值