WINCE下实现流水灯的应用程序---线程的创建与使用
上次通过应用程序在WINCE操作系统下实现了LED灯的点亮与熄灭的控制,这里只是对寄存器进行一次性操作,如果需要寄存器时刻的变化,那需要怎么做呢?这里不同于简单的单片机,做个死循环,让寄存器不断的变化就行了,因为在WINCE底下是多任务系统。这样就涉及到了线程问题。
具体的方法是建立一个线程,让应用程序去调用这个线程。当应用程序关闭的时候,线程也随着该进程的关闭而终止。仍然采用上文给出的流水灯的底层驱动实现流水灯和花样灯的控制。详细应用程序代码如下:
#include "stdafx.h"
#include "GPIOControl.h"
#include
"GPIOControlDlg.h"
#include "GPIO.h"
HANDLE hFile=INVALID_HANDLE_VALUE;
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char
THIS_FILE[] = __FILE__;
#endif
DWORD g_dwThreadId = 0;
BOOL g_bOpen = TRUE;
/////////////////////////////////////////////////////////////////////////////
//
CGPIOControlDlg dialog
CGPIOControlDlg::CGPIOControlDlg(CWnd* pParent )
:
CDialog(CGPIOControlDlg::IDD,
pParent)
{
//{{AFX_DATA_INIT(CGPIOControlDlg)
//
NOTE: the ClassWizard will add member initialization
here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require
a subsequent DestroyIcon in Win32
m_hIcon =
AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CGPIOControlDlg::DoDataExchange(CDataExchange*
pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CGPIOControlDlg)
//
NOTE: the ClassWizard will add DDX and DDV calls
here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CGPIOControlDlg,
CDialog)
//{{AFX_MSG_MAP(CGPIOControlDlg)
ON_BN_CLICKED(IDC_OPEN_GPIO,
OnOpenGpio)
ON_BN_CLICKED(IDC_LED_OFF,
OnLedOff)
ON_BN_CLICKED(IDC_CLOSE_GPIO,
OnCloseGpio)
ON_BN_CLICKED(IDC_LED_ON,
OnLedOn)
ON_BN_CLICKED(IDC_FLOWLED,
OnFlowled)
ON_BN_CLICKED(IDC_SPECLED,
OnSpecled)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
//
CGPIOControlDlg message handlers
BOOL
CGPIOControlDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this
automatically
// when the application's main window is not a
dialog
SetIcon(m_hIcon, TRUE); // Set big
icon
SetIcon(m_hIcon, FALSE); // Set small
icon
CenterWindow(GetDesktopWindow()); // center to the
hpc screen
// TODO: Add extra initialization here
return
TRUE; // return TRUE unless you set the focus to a control
}
//打开GPIO驱动,这里LED0表示需要调用的驱动的名字。如果出错则无法打开驱动!
void
CGPIOControlDlg::OnOpenGpio()
{
hFile=CreateFile(TEXT("LED0:"),GENERIC_READ
|
GENERIC_WRITE,0,
NULL,OPEN_EXISTING,0,0);
if(hFile==INVALID_HANDLE_VALUE)
{
MessageBox(_T("打开GPIO驱动失败!"));
}
else
{
MessageBox(_T("打开GPIO驱动成功!"));
}
}
//关闭GPIO驱动
void
CGPIOControlDlg::OnCloseGpio()
{
if(hFile!=INVALID_HANDLE_VALUE)
{
CloseHandle(hFile);
MessageBox(_T("关闭GPIO驱动成功!"));
}
else
{
MessageBox(_T("关闭GPIO驱动失败!"));
}
}
//
void CGPIOControlDlg::OnLedOff()
{
BOOL
ret;
ret=::DeviceIoControl(hFile,IO_CTL_LED_ALL_OFF,NULL,
1,NULL,0,NULL,NULL);
if(ret!=TRUE)
{
MessageBox(_T("关闭LED失败!"));
MessageBox(_T("请打开GPIO驱动!"));
}
g_bOpen
= FALSE;
}
void CGPIOControlDlg::OnLedOn()
{
BOOL
ret;
ret=::DeviceIoControl(hFile,IO_CTL_LED_ALL_ON,NULL,
1,NULL,0,NULL,NULL);
if(ret!=TRUE)
{
MessageBox(_T("点亮LED失败!"));
MessageBox(_T("请打开GPIO驱动!"));
}
}
//流水灯线程函数
DWORD WINAPI FlowThreadFunc(HANDLE Thread)
{
static
BOOL bCount =
0;
while(g_bOpen)
{
if(hFile==INVALID_HANDLE_VALUE)
{
return
0;
}
switch(bCount)
{
case
0:
DeviceIoControl(hFile,IO_CTL_LED_1_ON,NULL,
1,NULL,0,NULL,NULL);
break;
case
1:
DeviceIoControl(hFile,IO_CTL_LED_2_ON,NULL,
1,NULL,0,NULL,NULL);
break;
case
2:
DeviceIoControl(hFile,IO_CTL_LED_3_ON,NULL,
1,NULL,0,NULL,NULL);
break;
case
3:
DeviceIoControl(hFile,IO_CTL_LED_4_ON,NULL,
1,NULL,0,NULL,NULL);
break;
case
4:
DeviceIoControl(hFile,IO_CTL_LED_4_OFF,NULL,
1,NULL,0,NULL,NULL);
break;
case
5:
DeviceIoControl(hFile,IO_CTL_LED_3_OFF,NULL,
1,NULL,0,NULL,NULL);
break;
case
6:
DeviceIoControl(hFile,IO_CTL_LED_2_OFF,NULL,
1,NULL,0,NULL,NULL);
break;
case
7:
DeviceIoControl(hFile,IO_CTL_LED_1_OFF,NULL,
1,NULL,0,NULL,NULL);
break;
default:
break;
}
bCount
++;
if(bCount>7)
{
bCount
=
0;
}
Sleep(500);
}
return
0;
}
//花样灯线程函数
DWORD WINAPI SpecThreadFunc(HANDLE Thread)
{
static
BOOL bCount =
0;
while(g_bOpen)
{
if(hFile==INVALID_HANDLE_VALUE)
{
return
0;
}
DeviceIoControl(hFile,IO_CTL_LED_ALL_OFF,NULL,
1,NULL,0,NULL,NULL);//熄灭所有灯
switch(bCount)
{
case
0: //点亮LED1,4
DeviceIoControl(hFile,IO_CTL_LED_1_ON,NULL,
1,NULL,0,NULL,NULL);
DeviceIoControl(hFile,IO_CTL_LED_4_ON,NULL,
1,NULL,0,NULL,NULL);
break;
case
1://点亮LED2,3
DeviceIoControl(hFile,IO_CTL_LED_2_ON,NULL,
1,NULL,0,NULL,NULL);
DeviceIoControl(hFile,IO_CTL_LED_3_ON,NULL,
1,NULL,0,NULL,NULL);
break;
case
2://点亮LED1,4
DeviceIoControl(hFile,IO_CTL_LED_1_ON,NULL,
1,NULL,0,NULL,NULL);
DeviceIoControl(hFile,IO_CTL_LED_4_ON,NULL,
1,NULL,0,NULL,NULL);
break;
case
3://全灭
DeviceIoControl(hFile,IO_CTL_LED_ALL_OFF,NULL,
1,NULL,0,NULL,NULL);
break;
case
4://全亮
DeviceIoControl(hFile,IO_CTL_LED_ALL_ON,NULL,
1,NULL,0,NULL,NULL);
break;
case
5://全灭...
DeviceIoControl(hFile,IO_CTL_LED_ALL_OFF,NULL,
1,NULL,0,NULL,NULL);
break;
case
6://全亮...
DeviceIoControl(hFile,IO_CTL_LED_ALL_ON,NULL,
1,NULL,0,NULL,NULL);
break;
case
7://全灭
DeviceIoControl(hFile,IO_CTL_LED_ALL_OFF,NULL,
1,NULL,0,NULL,NULL);
break;
case
8://全亮
DeviceIoControl(hFile,IO_CTL_LED_ALL_ON,NULL,
1,NULL,0,NULL,NULL);
break;
case
9://LED1,3亮
DeviceIoControl(hFile,IO_CTL_LED_1_ON,NULL,
1,NULL,0,NULL,NULL);
DeviceIoControl(hFile,IO_CTL_LED_3_ON,NULL,
1,NULL,0,NULL,NULL);
break;
case
10://LED2,4亮
DeviceIoControl(hFile,IO_CTL_LED_2_ON,NULL,
1,NULL,0,NULL,NULL);
DeviceIoControl(hFile,IO_CTL_LED_4_ON,NULL,
1,NULL,0,NULL,NULL);
break;
default:
break;
}
bCount
++;
if(bCount>11)
{
bCount
=
0;
}
Sleep(500);
}
return
0;
}
void CGPIOControlDlg::OnFlowled()
{
g_bOpen =
FALSE;
Sleep(700);
g_bOpen =
TRUE;
CreateThread(NULL,0,FlowThreadFunc,NULL,0,&g_dwThreadId);//调用一个线程
}
void CGPIOControlDlg::OnSpecled()
{
g_bOpen =
FALSE;
Sleep(700);
g_bOpen =
TRUE;
CreateThread(NULL,0,SpecThreadFunc,NULL,0,&g_dwThreadId);//调用一个线程
}
这是一个对话框的代码,通过上面的按钮实现多种操作。