一、简介
公司要做一个项目,需要用到蜂鸣器,然后我调用windows的API中的beep函数,发现竟然没有作用???之后查阅资料发现过去的beep是用主板的Speaker发声,直接操作硬件端口。现在的Windows可能出于安全考虑,beep已经不用主板的Speaker了,改用声卡输出。但是项目用的嵌入式电脑,根本没有喇叭,只能用主板的Speaker发声。
二、使用WinIO控制主板Speaker发声
WinIO动态调用
//初始化函数
typedef bool(__stdcall *InitializeWinIoType)();
//读取端口的数值
typedef bool(__stdcall *GetPortValType)(unsigned short PortAddr, unsigned long* pPortVal, unsigned short Size);
//写入端口的数值
typedef bool(__stdcall *SetPortValType)(unsigned short PortAddr, unsigned long PortVal, unsigned short Size);
bool Apq_LoadDll::LoadDll()
{
if (!g_bIs_X64)
{
winio_lib.setFileName("WinIo32.dll");
}
else
{
winio_lib.setFileName("WinIo64.dll");
}
if (winio_lib.load())
return true;
else
return false;
}
bool Apq_LoadDll::InitializeWinIoType()
{
if (!winio_lib.isLoaded())
return false;
InitializeWinIoType pFunc = (InitializeWinIoType)winio_lib.resolve("InitializeWinIo");
if (pFunc != NULL)
{
bool Result = pFunc();
return Result;
}
return false;
}
//读取端口的数值
bool Apq_LoadDll::GetPortValType(unsigned short portAddr, unsigned long* portVal)
{
if (!winio_lib.isLoaded())
return false;
GetPortValType GetPortVal = (GetPortValType)winio_lib.resolve("GetPortVal");
if (GetPortVal != nullptr)
{
bool Result = GetPortVal(portAddr, portVal, 1);
return Result;
}
return false;
}
//写入端口的数值
bool Apq_LoadDll::SetPortValType(unsigned short portAddr, unsigned long portVal)
{
if (!winio_lib.isLoaded())
return false;
SetPortValType SetPortVal = (SetPortValType)winio_lib.resolve("SetPortVal");
if (SetPortVal != nullptr)
{
bool Result = SetPortVal(portAddr, portVal, 1);
return Result;
}
return false;
}
调用WinIO实现Speaker发声
void Widget::on_pushButton_clicked()
{
Apq_LoadDll winio_lib;
if (!winio_lib.LoadDll())
return;
if (!winio_lib.InitializeWinIoType())
return;
//开启蜂鸣器
DWORD data = 0;
winio_lib.GetPortValType(0x61, &data);
data |= 0x03;
winio_lib.SetPortValType(0x61, data);
Sleep(60);
//关闭蜂鸣器
winio_lib.GetPortValType(0x61, &data);
data &= 0xFC;
winio_lib.SetPortValType(0x61, data);
}
三、使用WinRing0控制主板Speaker发声
void Widget::on_pushButton_clicked()
{
if (!InitializeOls())
return;
//开启蜂鸣器
unsigned short data = 0;
ReadIoPortWordEx(0x61, &data);
data |= 0x03;
WriteIoPortWordEx(0x61, data);
Sleep(60);
//关闭蜂鸣器
ReadIoPortWordEx(0x61, &data);
data &= 0xFC;
WriteIoPortWordEx(0x61, data);
}
四、结语
亲测好用!!!WinIO和WinRing0是动态库,网上百度一下就出来了,这里因为我找的WinIO只有库没得头文件,所以用的动态调用。