GPIO驱动程序,主要是GIO_Control:
BOOL GIO_IOControl(DWORD hOpenContext,
DWORD dwCode,
PBYTE pBufIn,
DWORD dwLenIn,
PBYTE pBufOut,
DWORD dwLenOut,
PDWORD pdwActualOut)
{
switch(dwCode)
{
case IO_CTL_GPIO_A_CON:
v_pIOPregs->GPACON= *(DWORD*)pBufIn;//GPACON SET
break;
case IO_CTL_GPIO_A_DAT_OUTPUT:
v_pIOPregs->GPADAT= *(DWORD*)pBufIn; //GPADAT SET (OUTPUT) also for Functional Pin
break;
case IO_CTL_GPIO_B_CON:
v_pIOPregs->GPBCON= *(DWORD*)pBufIn;//GPBCON SET
break;
case IO_CTL_GPIO_B_DAT_INPUT:
*(DWORD*)pBufOut=v_pIOPregs->GPBDAT; //GPBDAT SET (INPUT) also for Functional Pin
break;
case IO_CTL_GPIO_B_DAT_OUTPUT:
v_pIOPregs->GPBDAT= *(DWORD*)pBufIn; //GPBDAT SET (OUTPUT) also for Functional Pin
break;
case IO_CTL_GPIO_B_UP:
v_pIOPregs->GPBUP= *(DWORD*)pBufIn;//GPBUP SET
break;
case IO_CTL_GPIO_C_CON:
v_pIOPregs->GPCCON= *(DWORD*)pBufIn;//GPCCON SET
break;
case IO_CTL_GPIO_C_DAT_INPUT:
*(DWORD*)pBufOut=v_pIOPregs->GPCDAT; //GPCDAT SET (INPUT) also for Functional Pin
break;
case IO_CTL_GPIO_C_DAT_OUTPUT:
v_pIOPregs->GPCDAT= *(DWORD*)pBufIn; //GPCDAT SET (OUTPUT) also for Functional Pin
break;
case IO_CTL_GPIO_C_UP:
v_pIOPregs->GPCUP= *(DWORD*)pBufIn;//GPCUP SET
break;
case IO_CTL_GPIO_D_CON:
v_pIOPregs->GPDCON= *(DWORD*)pBufIn;//GPDCON SET
break;
case IO_CTL_GPIO_D_DAT_INPUT:
*(DWORD*)pBufOut=v_pIOPregs->GPDDAT; //GPDDAT SET (INPUT) also for Functional Pin
break;
case IO_CTL_GPIO_D_DAT_OUTPUT:
v_pIOPregs->GPDDAT= *(DWORD*)pBufIn; //GPDDAT SET (OUTPUT) also for Functional Pin
break;
case IO_CTL_GPIO_D_UP:
v_pIOPregs->GPDUP= *(DWORD*)pBufIn;//GPDUP SET
break;
case IO_CTL_GPIO_E_CON:
v_pIOPregs->GPECON= *(DWORD*)pBufIn;//GPECON SET
break;
case IO_CTL_GPIO_E_DAT_INPUT:
*(DWORD*)pBufOut=v_pIOPregs->GPEDAT; //GPEDAT SET (INPUT) also for Functional Pin
break;
case IO_CTL_GPIO_E_DAT_OUTPUT:
v_pIOPregs->GPEDAT= *(DWORD*)pBufIn; //GPEDAT SET (OUTPUT) also for Functional Pin
break;
case IO_CTL_GPIO_E_UP:
v_pIOPregs->GPEUP= *(DWORD*)pBufIn;//GPEUP SET
break;
case IO_CTL_GPIO_F_CON:
v_pIOPregs->GPFCON= *(DWORD*)pBufIn;//GPFCON SET
break;
case IO_CTL_GPIO_F_DAT_INPUT:
*(DWORD*)pBufOut=v_pIOPregs->GPFDAT; //GPFDAT SET (INPUT) also for Functional Pin
break;
case IO_CTL_GPIO_F_DAT_OUTPUT:
v_pIOPregs->GPFDAT= *(DWORD*)pBufIn; //GPFDAT SET (OUTPUT) also for Functional Pin
break;
case IO_CTL_GPIO_F_UP:
v_pIOPregs->GPFUP= *(DWORD*)pBufIn;//GPFUP SET
break;
case IO_CTL_GPIO_G_CON:
v_pIOPregs->GPGCON= *(DWORD*)pBufIn;//GPGCON SET
break;
case IO_CTL_GPIO_G_DAT_INPUT:
*(DWORD*)pBufOut=v_pIOPregs->GPGDAT; //GPGDAT SET (INPUT) also for Functional Pin
break;
case IO_CTL_GPIO_G_DAT_OUTPUT:
v_pIOPregs->GPGDAT= *(DWORD*)pBufIn; //GPGDAT SET (OUTPUT) also for Functional Pin
break;
case IO_CTL_GPIO_G_UP:
v_pIOPregs->GPGUP= *(DWORD*)pBufIn;//GPGUP SET
break;
case IO_CTL_GPIO_H_CON:
v_pIOPregs->GPHCON= *(DWORD*)pBufIn;//GPHCON SET
break;
case IO_CTL_GPIO_H_DAT_INPUT:
*(DWORD*)pBufOut=v_pIOPregs->GPHDAT; //GPHDAT SET (INPUT) also for Functional Pin
break;
case IO_CTL_GPIO_H_DAT_OUTPUT:
v_pIOPregs->GPHDAT= *(DWORD*)pBufIn; //GPHDAT SET (OUTPUT) also for Functional Pin
break;
case IO_CTL_GPIO_H_UP:
v_pIOPregs->GPHUP= *(DWORD*)pBufIn;//GPHUP SET
break;
case IO_CTL_GPIO_J_CON:
v_pIOPregs->GPJCON= *(DWORD*)pBufIn;//GPJCON SET
break;
case IO_CTL_GPIO_J_DAT_INPUT:
*(DWORD*)pBufOut=v_pIOPregs->GPJDAT; //GPJDAT SET (INPUT) also for Functional Pin
break;
case IO_CTL_GPIO_J_DAT_OUTPUT:
v_pIOPregs->GPJDAT= *(DWORD*)pBufIn; //GPJDAT SET (OUTPUT) also for Functional Pin
break;
case IO_CTL_GPIO_J_UP:
v_pIOPregs->GPJUP= *(DWORD*)pBufIn;//GPJUP SET
break;
default:
break;
}
RETAILMSG(0,(TEXT("GPIO_Control:Ioctl code = 0x%x\r\n"), dwCode));
return TRUE;
}
测试程序,封装了2个输入输出GPIO函数,调用十分方便:
#include "stdafx.h"
#include "Relay2.h"
#include "Relay2Dlg.h"
#include "GPIO_Driver.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
DWORD RData,BUFCON,BUFOUT,BUFIN;
struct GPIO
{
DWORD GPIOCON;
DWORD GPIOIN;
DWORD GPIOOUT;
};
struct GPIO GPA={gpacon,NULL,gpaout },
GPB={gpbcon,gpbin,gpbout },
GPC={gpccon,gpcin,gpcout },
GPD={gpdcon,gpdin,gpdout },
GPE={gpecon,gpein,gpeout },
GPF={gpfcon,gpfin,gpfout },
GPG={gpgcon,gpgin,gpgout },
GPH={gphcon,gphin,gphout },
GPJ={gpjcon,gpjin,gpjout }; //define and choose GPIO
// CRelay2Dlg 对话框
CRelay2Dlg::CRelay2Dlg(CWnd* pParent /*=NULL*/)
: CDialog(CRelay2Dlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CRelay2Dlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CRelay2Dlg, CDialog)
#if defined(_DEVICE_RESOLUTION_AWARE) && !defined(WIN32_PLATFORM_WFSP)
ON_WM_SIZE()
#endif
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_BUTTON1, &CRelay2Dlg::OnBnClickedButton1)
ON_BN_CLICKED(IDC_BUTTON2, &CRelay2Dlg::OnBnClickedButton2)
END_MESSAGE_MAP()
// CRelay2Dlg 消息处理程序
BOOL CRelay2Dlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
gpiodriver=CreateFile(L"GIO1:",GENERIC_READ | GENERIC_WRITE, 0,NULL,OPEN_EXISTING,0,NULL );//gpiodriver init
if(!gpiodriver)
MessageBox(L"打开GPIO设备失败!");
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
#if defined(_DEVICE_RESOLUTION_AWARE) && !defined(WIN32_PLATFORM_WFSP)
void CRelay2Dlg::OnSize(UINT /*nType*/, int /*cx*/, int /*cy*/)
{
if (AfxIsDRAEnabled())
{
DRA::RelayoutDialog(
AfxGetResourceHandle(),
this->m_hWnd,
DRA::GetDisplayMode() != DRA::Portrait ?
MAKEINTRESOURCE(IDD_RELAY2_DIALOG_WIDE) :
MAKEINTRESOURCE(IDD_RELAY2_DIALOG));
}
}
#endif
DWORD CRelay2Dlg::GPIOINPUT(DWORD GPIOCON,DWORD GPIOIN,DWORD BUFCON,DWORD BUFOUT ) //the function is used for GPIO INPUT
{ DWORD RData;
DeviceIoControl(gpiodriver,GPIOCON,&BUFCON,4,NULL,0,NULL,NULL);
DeviceIoControl(gpiodriver,GPIOIN,NULL,0,&BUFOUT,4,NULL,NULL);
memcpy(&RData,&BUFOUT,4);
return RData;
}
DWORD CRelay2Dlg::GPIOINPUT1(struct GPIO GP,USHORT NUM ) //the function is used for GPIO INPUT BETTER
{
BUFCON &=~(3<<(2*NUM));
DeviceIoControl(gpiodriver,GP.GPIOCON,&BUFCON,4,NULL,0,NULL,NULL);
DeviceIoControl(gpiodriver,GP.GPIOIN,NULL,0,&BUFOUT,4,NULL,NULL);
memcpy(&RData,&BUFOUT,4);
return RData;
}
VOID CRelay2Dlg::GPIOOUTPUT(DWORD GPIOCON,DWORD GPIOOUT,DWORD BUFCON,DWORD BUFIN ) //the function is used for GPIO OUTPUT
{
DeviceIoControl(gpiodriver,GPIOCON,&BUFCON,4,NULL,0,NULL,NULL);
DeviceIoControl(gpiodriver,GPIOOUT,&BUFIN,4,NULL,0,NULL,0);
}
VOID CRelay2Dlg::GPIOOUTPUT1(struct GPIO GP,USHORT NUM,BYTE PINSTATE ) //the function is used for GPIO OUTPUT better
{
if(GP.GPIOIN!=NULL)
BUFCON=(BUFCON &~(3<<(2*NUM)))|(1<<(2*NUM));
else
BUFCON &=~(1<<NUM);
if(PINSTATE)
BUFIN |=(1<<NUM);
else
BUFIN &=~(1<<NUM);
DeviceIoControl(gpiodriver,GP.GPIOCON,&BUFCON,4,NULL,0,NULL,NULL);
DeviceIoControl(gpiodriver,GP.GPIOOUT,&BUFIN,4,NULL,0,NULL,0);
}
void CRelay2Dlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
GPIOOUTPUT1(GPB,8,1);
GPIOINPUT1(GPB,7);
GPIOOUTPUT1(GPB,6,0);
GPIOOUTPUT1(GPB,5,0);
// GPIOOUTPUT1(GPF,3,1); //GPF3 OUTPUT 1
GPIOOUTPUT1(GPF,2,0);
//GPIOOUTPUT1(GPG,5,0);
//GPIOOUTPUT1(GPG,7,1);
}
void CRelay2Dlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
DWORD GetData;
GetData =GPIOINPUT1(GPF,6); //GPF4 INPUT
if(GetData&=(1<<6))
MessageBox(_T("1"));
else
MessageBox(_T("0"));
}