最新WinIO驱动测试GPIO口

it2024-01-06  68

目录

前言实验环境第一步:准备实验环境第二步:代码实现初始化写值到具体的地址中从具体的地址中读值 第三步:程序的打包总结

前言

首先,对于WinIo这个驱动的介绍你可以参考这个博客利用winIO3.0进行windows10 64bit端口读取,我的测试能够成功,很大部分也是参考了这个。所谓WinIo驱动程序呢,就是通过使用一种内核模式的设备驱动器和其它几种底层编程技巧,绕过了Windows系统的保护机制,允许在32位的Windows应用程序中直接对I/O端口和物理内存进行存取操作,而在64位Windows程序中有诸多前提条件的驱动程序。而大家其实现在在用的很大一部分都是Window10,64位的,也很少见到32位了。所以,这篇博客的意义就显而易见了,我会尽自己所能,将整个需要讲解的东西全都详细的讲明白,所有过程都是我自己亲自试验成功的,你可以跟着一步一步来。

实验环境

首先,我使用的编译环境是Win10 64位 +VS2015 +QT5.12,使用的语言是QT。我的试验成功也打破了网上某些人对于编译环境说要求在VS2013及以下的一种错误想法,不过,也有可能是环境不一样。程序的试验环境是Win10 64位的工控机。所以,后面我的程序还会涉及到应用程序的打包。

第一步:准备实验环境

第一步首先准备好你要实验的工控机的环境吧。我就直接摘抄上面那个博客了。

首先,先下载WinIo驱动程序,现在网上已经很多都已经不具有什么参考价值了,我就自己在网上下载了一个:WinIO驱动程序。我如果后面有讲到什么需要的文件的话,我都放在那里了。去下载就可以了,如果失效请留言。接下来,就是在你要测试的机器上开启测试模式了。你可以参考这个利用winIO3.0进行windows10 64bit端口读取进行测试模式的开启。还有就是安装WinIo64.sys的测试签名。这些你参考一下这个博客应该都可以解决。我主要讲需要注意的点:首先就是你要把WinIo64放在你运行程序的目录之前下,然后进行安装。然后把WinIo.h,WinIo64.lib,WinIo64.sys,WinIo64.dll,WINIO.VXD这些文件都放在程序的当前目录之下,这些在我给的链接里面都有的。反正可以参考下面这个图片: 经过上面的步骤,基本可以说关于WinIo这部分的环境就已经配置完毕了。下面讲一下代码,然后再讲一下打包方面的事情。

第二步:代码实现

就我自己的代码来说,我使用的是以插件的形式来实现我的测试程序。

初始化

这个测试程序的初始化很简单,你只需要调用InitializeWinIo()这个函数就可以了,然后看一下返回值。可以在插件中弄一个QMessageBox去弹出是否初始化成功。

int HTKIOTest::openDevice() { int retValue = 0;//非0代表的是失败,所以先暂时赋值为0 retValue = InitializeWinIo(); if (!retValue) { qDebug()<<"Error In InitializeWinIo!\n"; } return retValue; }

写值到具体的地址中

首先,这里的第一个形参是一个具体的端口,你应该会拿到你要测试GPIO的一个文档,不然,你是搞不了的。上面有这些端口的具体地址。 第一个形参是具体的端口地址,我会在外面传入,第二个是在这个地址上的第几位。代码如下:

//1 param: 写入的IO内存地址 ;2 param: 写入的值,单位为字;3 param:1 byte 2 WORD 3 DWORD int HTKIOTest::HTKWriteDo(WORD pbPhysAddr ,int bitIndex) { //若写入成功,则返回0 int flag = 0; WORD Data; DWORD dwPortVal2 = 0x0; DWORD temp = 1; temp = temp<<bitIndex;//将1左移bitIndex位,从而得到要与的值 GetPortVal((WORD)pbPhysAddr,&dwPortVal2,1); QString str2 = "Previous write data:"+QString::number(dwPortVal2, 10); QMessageBox::information(NULL, "dwPortVal2", str2); DWORD flag2 = dwPortVal2&temp; if(flag2)//若为真,则第bitIndex位为1,灯是灭的,那么就要将其点亮 { dwPortVal2 = ~dwPortVal2; Data = dwPortVal2 | temp;//取反->与->取反 Data = ~Data; } else { Data = dwPortVal2 | temp; } QString str3 = "Write data:"+QString::number(Data, 10); QMessageBox::information(NULL, "Data", str3); SetPortVal((WORD)pbPhysAddr,(DWORD)Data,1);//进行设置 dwPortVal2 = 0x0;//再初始化一次然后再获取 GetPortVal((WORD)pbPhysAddr,&dwPortVal2,1); return dwPortVal2;//把那个地址获得的数据往上传 }

上面我还做了几个弹窗操作,来弹出几个较为重要的值,不然,在工控机上你是很难判断你是否有写入值以及写入是否成功的。关于GPIO的输出,我是用外接信号灯来实现是否有输出信号。输入的测试的话,我是用外接的四个按钮对应这个输入的四个针脚,从而判断是否输入成功。

从具体的地址中读值

这个读值就简单的读了。直接GetPortVal就可以了。下面给代码:

//1 param: 要读出的IO内存地址 ;2 param: 读出的值,单位为字;3 param:1 byte 2 WORD 3 DWORD //dwPortVal指向双字变量的指针,接收从端口得到的数据。 int HTKIOTest::HTKReadDI(WORD pbPhysAddr ,int index) { int flag = 0; DWORD val = 0x0 ; GetPortVal((WORD)pbPhysAddr,&val,1); return val; }

第三步:程序的打包

首先,你先把你的主程序放在一个文件夹中,然后按照这个博客进行打包。关于Qt打包exe文件到其他电脑运行,欠什么文件的话,你就直接在电脑上搜索就好了,你可以使用Listray进行搜索,很好用的一个软件,我已经给出地址了,直接进行全局搜索就可以了。然后,你就把这个主程序依赖的插件还有其他的一些dll文件都要放进去。到这,可以运行看看,有没有达到你的预期了,如果达到了,当然是最好的,如果没达到的话,你继续走第三步。要用管理员模式运行主程序。如果还是不行的话,走第四步。找不到一些插件依赖的库文件时 ,可以使用depends去找到底缺少什么文件。参考这个博客:dll依赖查看工具-depends。还是不行,走第五步。把这些硬件支持dll文件放进去。硬件支持dll文件这已经是我遇到我的所有问题了,如果还是不行的话,可以私聊或是自己再找下有没有其他答案。祝你一切顺利,别走到这一步。

总结

其实代码部分都不难,难得是整个环境的配置,确实需要挺多步 的,希望你能耐心的一步一步走下来,加油~所做的一切都是为了更好的自己!!

最新回复(0)