TcTimer Sample für VisualStudio 2005
TwinCAT I/O - TcTimer Sample Project for VisualStudio 2005
- Erzeugen Sie eine neue Konsolen Applikation im Visual Studio 2005.
- Linken Sie Ihr projekt mit TcTimerWrap.lib und TCatIoDrvW32.lib
- Fügen Sie folgenden Quellcode zu Ihrem Programm hinzu:
///////////////////////////////////////////////////////////////////////////////
//
// Beckhoff Automation
//
// TwinCAT CE ® I/O sample program using TwinCAT Timer.
//
///////////////////////////////////////////////////////////////////////////////
// TcTimerWrap.lib and TCatIoDrvW32.lib must be linked for this project
//
#include "stdafx.h"
#include "stdio.h"
#include "windows.h"
#include "TCatIoW32Api.h" // header file shipped with TwinCAT® I/O
#include "TcTimerApi.h" // header file shipped with TwinCAT® I/O
#include "Task1ms.h" // TwinCAT® System Manager generated
#include "Task10ms.h" // TwinCAT® System Manager generated
#define IOERR_IOSTATEBUSY 0x2075
#define TASK1MS_DELAY 1 // Ticks
#define TASK10MS_DELAY 10 // Ticks
#define DELAY_IN_100NS(x) (x*10000)
PTask1ms_Outputs pT1msOut;
PTask1ms_Inputs pT1msIn;
PTask10ms_Outputs pT10msOut;
PTask10ms_Inputs pT10msIn;
HANDLE g_hEvent1, g_hEvent2;
BOOL g_bExit;
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
static DWORD WINAPI TimerProc1( LPVOID lpParam)
{
static int i=0;
long nError;
while(!g_bExit)
{
WaitForSingleObject(g_hEvent1,INFINITE);
// first try to get the inputs and test if input update succeeded
if ( (nError = TCatIoInputUpdate( TASK1MS_PORTNUMBER )) == 0 )
{
// do your calculation and logic
pT1msOut->AnalogOut = pT1msIn->AnalogIn;
// start the I/O update and field bus cycle
TCatIoOutputUpdate( TASK1MS_PORTNUMBER );
}
else
printf( "TCatInputUpdate(%d) %d failed with 0x%x !\n",
TASK1MS_PORTNUMBER, i++, nError );
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////
static DWORD WINAPI TimerProc2( LPVOID lpParam)
{
static int i=0;
long nError;
while(!g_bExit)
{
WaitForSingleObject(g_hEvent2,INFINITE);
if ( (nError = TCatIoInputUpdate( TASK10MS_PORTNUMBER )) == 0 )
{
// optionally test the device state, zero is ok.
if ( pT10msIn->IoDeviceState != 0 )
printf( "I Device Error !\n" );
else
{
// do your calculation and logic
pT10msOut->DigitalOut[0] = pT10msIn->DigitalIn[0];
pT10msOut->DigitalOut[1] = pT10msIn->DigitalIn[1];
// start the I/O update and field bus cycle
TCatIoOutputUpdate( TASK10MS_PORTNUMBER );
}
}
else
printf("TCatInputUpdate(%d) %d failed with 0x%x !\n",
TASK10MS_PORTNUMBER, i++, nError );
}
return 0;
}
int _tmain(int argc, TCHAR* argv[])
{
INT idTimer1, idTimer2;
TCHAR pszTask1Name[MAX_PATH] = TEXT("evt_TASK_1_TICK");
TCHAR pszTask2Name[MAX_PATH] = TEXT("evt_TASK_10_TICK");
HANDLE hThreadTask1, hThreadTask2;
long m_nAdsState;
DWORD m_dwBaseTime;
// always call TCatIoOpen first.
if ( TCatIoOpen() == 0 )
{
m_nAdsState = TCatGetState();
if( (TcTimerInitialize() != STATUS_SUCCESS) && (m_nAdsState != ADSSTATE_RUN) )
{
TCatIoClose();
printf("Failed to Initialize TcTimer or TwinCAT not in RUN mode\n");
getchar();
return FALSE;
}
m_dwBaseTime = TcTimerGetTickTime()/10;
printf("Base Time = %d microseconds\n", m_dwBaseTime);
// get the process image pointer
if ( TCatIoGetOutputPtr(TASK1MS_PORTNUMBER, (void**)&pT1msOut,sizeof(Task1ms_Outputs) ) == 0 &&
TCatIoGetInputPtr( TASK1MS_PORTNUMBER,(void**)&pT1msIn, sizeof(Task1ms_Inputs) ) == 0 &&
TCatIoGetOutputPtr(TASK10MS_PORTNUMBER,(void**)&pT10msOut, sizeof(Task10ms_Outputs) )== 0 &&
TCatIoGetInputPtr(TASK10MS_PORTNUMBER,(void**)&pT10msIn, sizeof(Task10ms_Inputs) )== 0 )
{
// Create Events for the Tasks
g_hEvent1 = CreateEvent(NULL,FALSE,FALSE,pszTask1Name);
g_hEvent2 = CreateEvent(NULL,FALSE,FALSE,pszTask2Name);
// Set Events in TcTimer
idTimer1 = TcTimerSetEvent( TASK1MS_DELAY, pszTask1Name, TIME_CALLBACK_EVENT_SET|TIME_PERIODIC );
idTimer2 = TcTimerSetEvent( TASK10MS_DELAY, pszTask2Name, TIME_CALLBACK_EVENT_SET|TIME_PERIODIC );
g_bExit = FALSE;
// Create thread
hThreadTask1 = CreateThread( NULL, 0, TimerProc1, NULL, CREATE_SUSPENDED, NULL);
hThreadTask2 = CreateThread( NULL, 0, TimerProc2, NULL, CREATE_SUSPENDED, NULL);
// Set the Priorities of the Thread
if (CeSetThreadPriority(hThreadTask1, 26) && CeSetThreadPriority(hThreadTask2, 27))
{
ResumeThread(hThreadTask1);
ResumeThread(hThreadTask2);
}
// Wait for the end
printf("Press any key to End !!\n");
getchar();
g_bExit = TRUE;
SetEvent(g_hEvent1);
SetEvent(g_hEvent2);
// events are no longer needed
TcTimerKillEvent( idTimer1 );
TcTimerKillEvent( idTimer2 );
CloseHandle( g_hEvent1 );
CloseHandle( g_hEvent2 );
}
// free resources
TCatIoClose();
TcTimerDeinitialize();
}
return 0;
}
- Sollten Sie beim Kompilieren einen Linker Fehler bekommen, stellen Sie sicher dass die Compiler Option "/Zc:wchar_t-" eingeschaltet ist. (Offnen Sie die Projekt Eigenschaften -> Configuration Properties->C++->Language->Treat wchar_t as Built-in Type)
Debuggen der BeispielApplikation
Um das Programm zu debuggen führen sie die folgenden Schritte durch:
- In der Vs2005 IDE wählen Tools -> Options -> Device Tools -> Devices.
- Wählen Sie Ihr Gerät aus und öffnen der Properties Dialog.
- Wählen Sie "TCP Connect Transport" aus und geben Sie die IP Adresse Ihres Gerätes ein
- Auf Ihrem Cx Gertät navigieren sie zu \Hard Disk\System
- Starten Sie die Tools "conmanclient2" und "cmaccept"
- In der IDE wählen Sie Tools -> Connect to Device.
- Starten Sie das Programm.