第一次写东西,把前段时间在做的一个小项目整理一下吧。
做的是windows下实现IO口的操作,实现人体感应,让程序和系统能根据人体感应器来做一些动作。
首先要知道的是,主板上的gpio针脚的物理地址,这个可以看下主板说明书。
由于windows不能像linux一样直接操作底层,所以有位牛人写了一个winio库,winio库通过使用内核模式下设备驱动程序和其它一些底层编程技巧绕过windows安全保护机制,允许32位windows程序直接对I/O口进行操作。WinIo包含了3个文件:WinIo.dll、WinIo.sys、WinIo.lib和WINIO.VXD,其中WINIO.VXD驱动程序用在Win95/98系统上,WinIo.sys驱动程序用在WinNT/2000/XP系统上,WinIo.dll提供了功能函数的调用。在
WinIo.dll中有两个函数最重要:InitializeWinIo用来初始化WinIo的驱动程序,必须在调用所有其它功能函数之前调用该函数;ShutdownWinIo用来卸载WinIo的驱动程序,在中止应用函数之前或者不再需要使用WinIo时调用。在初始化完成之后就可以直接读写 I/O端口而不会出现非法操作,winio库现在更新到3.0了,去百度google一下就能找到了。
举个例子直接贴代码吧,例子是参考了他人的思路,如果侵权请联系。
比如这个例子程序实现的功能是,当有人过来的时候,系统就修改下分辨率,只是个例子啦,当然真正用的话没那么无聊。
#ifndef WINIOTEST_H
#define WINIOTEST_H
#pragma once
#include
#include
#include
#include
class CONTROL{
protected:
HWND hwndDialog;
int ReadByteFromEC(int offset, char *pdata);
int WriteByteToEC(int offset, char data);
public:
CONTROL(HINSTANCE );
~CONTROL();
};
#endif //WINIOTEST_H
#include
#include
#include "winio.h"
#include "winiotest.h"
#include
#include "stdafx.h"
using namespace std;
// Registers of the embedded controller
#define GPIO_BASE_ADDRESS 0x500
#define EC_DATAPORT 0x0e // EC data io-port
#define EC_CTRLPORT 0x0c // EC control io-port
// Embedded controller status register bits
#define EC_STAT_OBF 0x01 // Output buffer full
#define EC_STAT_IBF 0x02 // Input buffer full
#define EC_STAT_CMD 0x08 // Last write was a command write (0=data)
// Embedded controller commands
// (write to EC_CTRLPORT to initiate read/write operation)
#define EC_CTRLPORT_READ (char)0x80
#define EC_CTRLPORT_WRITE (char)0x81
#define EC_CTRLPORT_QUERY (char)0x84
int verbosity= 0; // verbosity for the logbuf (0= nothing)
char lasterrorstring[256]= "",
logbuf[8192]= "";
void GetScrnEERO(LONG i)
{
/*switch(i)
{
case 0:
cout << "**********"<0)
sprintf(logbuf+strlen(logbuf), "waitportstatus: tick port= %02x, status= %02x => data was %02x\n", port, bits, data);
if (!done) {
strcpy(lasterrorstring, "waitportstatus: GetPortValue failed");
break;
}
// check for desired result
int flagstate= (((char)data) & bits)!=0,
wantedstate= onoff!=0;
if (flagstate==wantedstate) {
ok= true;
break;
}
// try again after a moment
::Sleep(tick);
}
if (!ok && strlen(lasterrorstring)==0) {
sprintf(lasterrorstring, "waitportstatus: timeout waiting for port %02x to change to status %02x/%d", port, bits, onoff);
}
if (!ok) {
sprintf(logbuf+strlen(logbuf), "waitportstatus returns failed: ok= %d\n", ok);
}
return ok;
}
//-------------------------------------------------------------------------
// write a character to an io port through WinIO device
//-------------------------------------------------------------------------
int
writeport(int port, char data)
{
strcpy(lasterrorstring, "");
// write byte via WINIO.SYS
int done= SetPortVal(port, data, 1);
if (!done) {
sprintf(lasterrorstring, "writeport: port %02x, data %02x failed\n", port, data);
}
if (verbosity>1) {
sprintf(logbuf+strlen(logbuf), "writeport port= %02x, data= %02x, done= %d\n", port, data, done);
}
return done;
}
//-------------------------------------------------------------------------
// read a character from an io port through WinIO device
//-------------------------------------------------------------------------
int
readport(int port, char *pdata)
{
DWORD data= -1;
// read byte via WINIO.SYS
int done= GetPortVal(port, &data, 1);
if (done) {
*pdata= (char)data;
}
else {
sprintf(lasterrorstring, "readport: port %02x failed\n", port, data);
}
if (verbosity>1)
sprintf(logbuf+strlen(logbuf), "readport port= %02x, data= %02x, done= %d\n", port, (char)data, done);
return done;
}
void main(int offset, char *pdata)
{
DWORD dwPortVal;
DWORD rc = 0;
int port;
int ok;
// Call InitializeWinIo to initialize the WinIo library.
//声明一个结构
DEVMODE dmScreenSettings;
;
DWORD widthShao = 0,heightShao = 0;
memset(&dmScreenSettings,0,sizeof(dmScreenSettings));
dmScreenSettings.dmSize = sizeof(dmScreenSettings);
//显示图形设备
EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dmScreenSettings);
int i = 0;
BOOL bRetvol;
DEVMODE demove;
do
{
bRetvol = EnumDisplaySettings(NULL,i,&demove);
i++;
if(bRetvol)
{
if ((demove.dmPelsWidth != widthShao || demove.dmPelsHeight != heightShao) &&(demove.dmPelsWidth >= 800 &&demove.dmPelsHeight >= 600))
{
widthShao = demove.dmPelsWidth;
heightShao= demove.dmPelsHeight;
//cout<< endl<
在编译的时候记得把winio.lib加到项目中,不然会编译不过去。