Интерфейс USB на примере HID джойстика Logitech Precision

Автор работы: Пользователь скрыл имя, 18 Марта 2013 в 21:01, курсовая работа

Краткое описание

Целью данной курсовой работы является освоение использования динамически подключаемых библиотек и их взаимодействие с устройствами, подключаемыми к персональному компьютеру через интерфейс USB, а также создание приложения типа “клиент-сервер” с помощью технологии Winsock.
Будем рассматривать работу с интерфейсом USB на примере HID джойстика Logitech Precision.

Содержание

Введение……………………………………………………….….…….....................3
1. Постановка задачи…………………………………………...…..….….….4
2. Описание HID устройств…………………………………………........….6
3. Описание DLL библиотек…………………………………..…………..…7
4. Динамическая библиотека HID_Lib_Plus.dll………..…………..…....….8
5. Программирование с использованием сокетов……..……………....….11
6. Результат работы программ……………………….……….…………..…14
Заключение………………………….……………………….……………….....…..16
Список литературы………………………………………………….…….………..18
Приложение А………………………………………………………….…….....….19

Вложенные файлы: 1 файл

Содержание.docx

— 198.13 Кб (Скачать файл)

#define Button_7 0x0400

#define Button_8 0x0800

#define Button_9 0x1000

#define Button_10 0x2000

 

TForm1 *Form1;

 

typedef int (WINAPI *MyType) (int, int, short, short);

typedef int (WINAPI *MyType1) (int, char*, int);

//статус подключения

HANDLE tHandle;

TCP* tcp;

int Vid = 0x046D, Pid = 0xC21A, Rev = 4;

int flag=1;

DWORD WINAPI ThreadFunction();

unsigned short CreateState(char buffer[5]);

int OneHex2Deg(char hex);

int StrHex2Deg(char *hex, int n);

void InitFunctions();

 

MyType HID_DeviceTest;

MyType HID_OpenDevice;

MyType1 HID_ReadDevice;

 

//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)

        : TForm(Owner)

{

 

}

//---------------------------------------------------------------------------

 

void __fastcall TForm1::FormCreate(TObject *Sender)

{

        InitFunctions();

        tcp = new TCP();

        DWORD thID;

        tHandle = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)ThreadFunction, NULL, NULL, &thID);

}

//Функция потока для джойстика

DWORD WINAPI ThreadFunction()

{

int test=0, old_test=0;

        int handle; //хэндл для джойстика

        char buffer[5];

        int bufferLenght = sizeof(buffer);

        int nBytes, i;

 

        while(1)

        {

 

        if(flag)

        {

                //Проверяем, подключен ли джойстик

                test = HID_DeviceTest(Pid, Vid, Rev, 0);

                if(test)

                {

                        if(test!=old_test)

                        {

                                //открываем устройство

                                handle = HID_OpenDevice(Pid, Vid, Rev, 0);

                        }

                        old_test = test;

 

                        Form1->GroupBox1->Caption = "Device IDs [CONNECTED]";

 

                        //читаем данные

                        nBytes = HID_ReadDevice(handle, &buffer[0], bufferLenght);

                        if(nBytes == bufferLenght)

                        {

                                Form1->RefreshButton(CreateState(buffer));

                                tcp->Send(buffer);

                        }

                }//if(test)

                else

                {

                        //джойстик не подключен

                        old_test = test;

                        Form1->GroupBox1->Caption = "Device IDs [DISCONNECTED]";

                }

        }//if(flag)

        }//while

        return 0;

}

 

 

//---------------------------------------------------------------------------

void InitFunctions()

{

        //подключаем нашу dll

HINSTANCE hLib = LoadLibrary("HID_Lib_Plus.dll");

//Выставляем указатели на функции dll

  (FARPROC &)HID_DeviceTest = GetProcAddress(hLib, "HID_DeviceTest");

(FARPROC &)HID_OpenDevice = GetProcAddress(hLib, "HID_OpenDevice");

(FARPROC &)HID_ReadDevice = GetProcAddress(hLib, "HID_ReadDevice");

}

 

 

unsigned short CreateState(char b[5])

{

        unsigned short state=0;

        if(b[3]&1) state = state|Button_1;

        if(b[3]&2) state = state|Button_2;

        if(b[3]&4) state = state|Button_3;

        if(b[3]&8) state = state|Button_4;

        if(b[3]&16) state = state|Button_5;

        if(b[3]&32) state = state|Button_6;

        if(b[3]&64) state = state|Button_7;

        if(b[3]&128) state = state|Button_8;

        if(b[4]&1) state = state|Button_9;

        if(b[4]&2) state = state|Button_10;

        if(b[4]&16) state = state|Button_Up;

        if(b[4]&32) state = state|Button_Down;

        if(b[4]&4) state = state|Button_Left;

        if(b[4]&8) state = state|Button_Right;

        return state;

}

 

void TForm1::RefreshButton(unsigned short state)

{

      CheckBox1->Checked = state&Button_1;

      CheckBox2->Checked = state&Button_2;

      CheckBox3->Checked = state&Button_3;

      CheckBox4->Checked = state&Button_4;

      CheckBox5->Checked = state&Button_5;

      CheckBox6->Checked = state&Button_6;

      CheckBox7->Checked = state&Button_7;

      CheckBox8->Checked = state&Button_8;

      CheckBox9->Checked = state&Button_9;

      CheckBox10->Checked = state&Button_10;

 

      CheckBox11->Checked = state&Button_Left;

      CheckBox12->Checked = state&Button_Down;

      CheckBox13->Checked = state&Button_Right;

      CheckBox14->Checked = state&Button_Up;

}

 

int OneHex2Deg(char hex)

{

        if((hex == '0')||(hex == '0')) return 0;

        if((hex == '1')||(hex == '1')) return 1;

        if((hex == '2')||(hex == '2')) return 2;

        if((hex == '3')||(hex == '3')) return 3;

        if((hex == '4')||(hex == '4')) return 4;

        if((hex == '5')||(hex == '5')) return 5;

        if((hex == '6')||(hex == '6')) return 6;

        if((hex == '7')||(hex == '7')) return 7;

        if((hex == '8')||(hex == '8')) return 8;

        if((hex == '9')||(hex == '9')) return 9;

        if((hex == 'A')||(hex == 'a')) return 10;

        if((hex == 'B')||(hex == 'b')) return 11;

        if((hex == 'C')||(hex == 'c')) return 12;

        if((hex == 'D')||(hex == 'd')) return 13;

        if((hex == 'E')||(hex == 'e')) return 14;

        if((hex == 'F')||(hex == 'f')) return 15;

        return 0;

}

 

int StrHex2Deg(char *hex, int n)

{

    int i, deg =0;

    for(i=0; i<n;i++)

        deg+=OneHex2Deg(hex[i])*pow(16,n-i-1);

    return deg;

}

void __fastcall TForm1::Button2Click(TObject *Sender)

{

        flag = 0;

        char *buf = new char[6];

 

        strcpy(buf, EditVid->Text.c_str());

        Vid = StrHex2Deg(&buf[0], EditVid->Text.Length());

 

        strcpy(buf, EditPid->Text.c_str());

        Pid = StrHex2Deg(&buf[0], EditPid->Text.Length()) ;

 

        strcpy(buf, EditRev->Text.c_str());

        Rev = StrHex2Deg(&buf[0], EditRev->Text.Length()) ;

        flag = 1;

}

//---------------------------------------------------------------------------

 

 

 

 

void __fastcall TForm1::Button4Click(TObject *Sender)

{

        char * temp  = new char[20];

 

        strcpy(temp, EditIp->Text.c_str());

 

        if(tcp->Init(temp, EditPort->Text.ToInt()))

                GroupBox2->Caption = "Network IDs [CONNECTED]";

        else

                GroupBox2->Caption = "Network IDs [DISCONNECTED]";

 

        //tcp->Send("awd");

        temp=NULL;

}

//---------------------------------------------------------------------------

 

void __fastcall TForm1::GroupBox3Click(TObject *Sender)

{

        if(GroupBox3->Height == 161)

                GroupBox3->Height = 15;

        else

                GroupBox3->Height = 161;

}

//---------------------------------------------------------------------------

Листинг TCP.cpp – реализует класс для создания и использования tcp/ip сокетов

//---------------------------------------------------------------------------

#pragma hdrstop

#include "TCP.h"

 

//---------------------------------------------------------------------------

 

#pragma package(smart_init)

 

 

TCP::TCP()

{

        SERVERADDR = new char[20];

}

 

int TCP::Init(char * serveraddr, int port)

{

        //TODO: Add your source code here

 

        closesocket(my_sock);

        WSACleanup();

 

        char buff[1024];

        strcpy(SERVERADDR,serveraddr);

        PORT = port;

 

        //Инициализация библиотеки Winsock

        if (WSAStartup(0x202, (WSADATA *)&buff[0]))

        {

                //Ошибка

        return 0;

        }

                //Создание сокета

        my_sock = socket(AF_INET, SOCK_STREAM, 0);

        if (my_sock < 0)

        {

                //Ошибка

        return 0;

        }

 

        //Заполнение структуры sockaddr_in –  указание адреса и порта сервера

        dest_addr.sin_family = AF_INET;

        dest_addr.sin_port = htons(PORT);

dest_addr.sin_addr.s_addr = inet_addr(SERVERADDR);

 

        //Устанавливаем соеденение

        if (connect(my_sock, (sockaddr *)&dest_addr, sizeof(dest_addr)))

        {

                //Ошибка

                return 0;

        }

        //ALL GOOD!!!

        return 1;

}

 

void TCP::Send(char * buffer)

{

        //TODO: Add your source code here

        send(my_sock, buffer, 5, 0);

}

 

TCP::~TCP()

{

        //TODO: Add your source code here

        closesocket(my_sock);

        WSACleanup();

}

Листинг сервера

Unit1.cpp – реализация основного алгоритма сервера

#pragma comment(lib,"wsock32.lib")

#include <winsock2.h>

#include <vcl.h>

#pragma hdrstop

#include <stdio.h>

#include "Unit1.h"

#include "math.h"

//#include "dButtons.h"

 

#include <windows.h>

#include "Unit2.cpp"

#define PI 3.141592653589

 

#pragma package(smart_init)

#pragma resource "*.dfm"

/*

#define Button_Down 0x0001

#define Button_Up 0x0002

#define Button_Left 0x0004

#define Button_Right 0x0008

#define Button_1 0x0010

#define Button_2 0x0020

#define Button_3 0x0040

#define Button_4 0x0080

#define Button_5 0x0100

#define Button_6 0x0200

#define Button_7 0x0400

#define Button_8 0x0800

#define Button_9 0x1000

#define Button_10 0x2000    */

 

TForm1 *Form1;

static int fig=1;

StateTel* statetel;

int nclients = 0;

//прототип функции  для слежения за подключениями

DWORD WINAPI ThreadFunction();

//протототип функции  для работы с клиентами

DWORD WINAPI ToClient(LPVOID client_socket);

//Порт для входящих  подключений

int MY_PORT=666;

int flag = 1;

SOCKET sock2,sock1;

 

unsigned short CreateState(char b[5]);

 

static unsigned int left=0, right=0, down=0, up = 0, kyrsL=0, kyrsR = 0, gazUp =0, gazDown = 0;

 

__fastcall TForm1::TForm1(TComponent* Owner)

        : TForm(Owner)

{

Form1->Memo2->Clear();

obj=new OGL(Panel1->Handle,Panel1->Width,Panel1->Height);

}

 

unsigned short state = 0;

 

void __fastcall TForm1::Timer1Timer(TObject *Sender)

{

UpdateBtnMap();

statetel->UpdateTel(state, ButtonMap);

obj->DrawQe(statetel);

}

 

void __fastcall TForm1::FormCreate(TObject *Sender)

{

        statetel = new StateTel();

}

//---------------------------------------------------------------------------

 

 

double TForm1::deg2rad(double deg)

{

return deg*PI/180.;

}

void __fastcall TForm1::Button2Click(TObject *Sender)

{

    statetel->Clear();

 

}

//---------------------------------------------------------------------------

DWORD WINAPI ThreadFunction()

{

char buff[1024];

char str[200];

printf("TCP SERVER DEMO\n");

if (WSAStartup(0x0202, (WSADATA *)&buff[0]))

{

// Ошибка

        Form1->Memo2->Lines->Add("Error WSAStartup");

return 0;

}

 

SOCKET mysocket;

if ((mysocket = socket(AF_INET, SOCK_STREAM, 0)) < 0)

{

// Ошибка

        Form1->Memo2->Lines->Add("Error socket");

WSACleanup();

return 0;

}

 

sockaddr_in local_addr;

local_addr.sin_family = AF_INET;

local_addr.sin_port = htons(MY_PORT);

local_addr.sin_addr.s_addr = 0;

 

if (bind(mysocket, (sockaddr *)&local_addr, sizeof(local_addr)))

{

//Ошибка

        Form1->Memo2->Lines->Add("Error bind");

closesocket(mysocket);

WSACleanup();

return 0;

}

 

if (listen(mysocket, 0x100))

{

//Ошибка

        Form1->Memo2->Lines->Add("Error listen");

        closesocket(mysocket);

WSACleanup();

return -1;

}

sock1 = mysocket;

SOCKET client_socket;

sockaddr_in client_addr;

 

int client_addr_size = sizeof(client_addr);

 

while(flag)

{

if(nclients==0)

        {

        Form1->GroupBox2->Caption = "Network IDs [Expectation of connections]";

if ((client_socket = accept(mysocket, (sockaddr *)&client_addr, &client_addr_size)))

{

nclients++;

                HOSTENT *hst;

hst = gethostbyaddr((char *)&client_addr. sin_addr.s_addr, 4, AF_INET);

 

// вывод  сведений о клиенте

                sprintf(str,"+%s [%s] new connect!",

(hst) ? hst->h_name : "", inet_ntoa(client_addr.sin_addr));

                Form1->Memo2->Lines->Add(AnsiString(str));

 

                Form1->GroupBox2->Caption = "Network IDs [CONNECTED]";

   DWORD thID;

CreateThread(NULL, NULL, ToClient, &client_socket, NULL, &thID);

}

        }

}

Form1->GroupBox2->Caption = "Network IDs [DISCONNECTED]";

return 1;

 

}

 

DWORD WINAPI ToClient(LPVOID client_socket)

{

SOCKET my_sock;

my_sock = ((SOCKET *)client_socket)[0];

        sock2 = my_sock;

char buff[5];

        char str[100];

int bytes_recv;

while ((bytes_recv = recv(my_sock, &buff[0], sizeof(buff), 0)) &&

bytes_recv != SOCKET_ERROR)

{

        state =  CreateState(buff);

        sprintf(str, "%d",state);

        Form1->Memo2->Lines->Add(AnsiString(str));

}

nclients--;

        Form1->GroupBox2->Caption = "Network IDs [Expectation of connections]";

        Form1->Memo2->Lines->Add("User disconnected...");

closesocket(my_sock);

return 0;

}

 

unsigned short CreateState(char b[5])

{

        unsigned short state=0;

        if(b[3]&1) state = state|Button_1;

        if(b[3]&2) state = state|Button_2;

        if(b[3]&4) state = state|Button_3;

        if(b[3]&8) state = state|Button_4;

        if(b[3]&16) state = state|Button_5;

        if(b[3]&32) state = state|Button_6;

        if(b[3]&64) state = state|Button_7;

        if(b[3]&128) state = state|Button_8;

        if(b[4]&1) state = state|Button_9;

        if(b[4]&2) state = state|Button_10;

        if(b[4]&16) state = state|Button_Up;

        if(b[4]&32) state = state|Button_Down;

        if(b[4]&4) state = state|Button_Left;

        if(b[4]&8) state = state|Button_Right;

        return state;

}

void __fastcall TForm1::GroupBox1Click(TObject *Sender)

{

        if(Form1->GroupBox1->Height == 15)

                Form1->GroupBox1->Height = 113;

        else Form1->GroupBox1->Height = 15;

 

}

//---------------------------------------------------------------------------

 

void __fastcall TForm1::Button4Click(TObject *Sender)

{

     MY_PORT = EditPort->Text.ToInt();

 

     DWORD thID;

     CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)ThreadFunction, NULL, NULL, &thID);

 

     Form1->Button4->Enabled= false;

 

}

//---------------------------------------------------------------------------

 

void __fastcall TForm1::Button1Click(TObject *Sender)

{

     Form2->Visible = true;

 


Информация о работе Интерфейс USB на примере HID джойстика Logitech Precision