МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ
НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ “ЛЬВІВСЬКА ПОЛІТЕХНІКА”
Лабораторна робота
з дисципліни
" Периферійні пристрої "
На тему: «Дослідження режимів функціонування інтефейсу USB»
МЕТА РОБОТИ: ознайомитися з процесом передачі даних через послідовний інтерфейс USB; ознайомитися з процесом створення елементів програми для сканування USB-портів на наявність підключених пристроїв до послідовного USB інтерфейсу; ознайомитися з процесом створення та налаштування основних параметрів програми передачі даних через послідовний USB інтерфейс; ознайомитися з процесом формування та передачі постмвольних даних у графічному представленні в схемі кодування NRZI через послідовний USB інтерфейс.
ТЕОРЕТИЧНІ ВІДОМОСТІ
USB (англ. Universal Serial Bus, абревіатура читається ю-ес-бі) — укр. універсальна послідовна шина, призначена для з'єднання периферійних пристроїв. Шина USB представляє собою послідовний інтерфейс передачі даних для середньошвидкісних та низькошвидкісних периферійних пристроїв. Для високошвидкісних пристроїв на сьогодні кращим вважається FireWire. USB-кабель представляє собою дві виті пари: по одній парі відбувається передача даних в кожному напрямку (диференціальне включення), а інша пара використовується для живлення периферійного пристрою (+5 В). Завдяки вбудованим лініям живлення, що запезпечують струм до 500 мА, USB часто дозволяє використовувати пристрої без власного блоку живлення (якщо ці пристрої споживають струм потужністю не більше 500 мА). До одного контролера шини USB можно під'єднати до 127 пристроїв через ланцюжок концентраторів (вони використовують топологію «зірка»). На відміну від багатьох інших стандартних роз’ємів, для USB характерні довговічність та механічна міцність. Інтерфейс USB є послідовною, напівдуплексною, двонаправленою шиною.| Шина дозволяє підключити до ПК до 127 фізичних пристроїв. Кожен фізичний пристрій може, у свою чергу, складатися з декількох логічних (наприклад, клавіатура з вбудованим манипулятором-трекболом). Кабельна розводка USB починається з вузла (host). Хост володіє інтегрованим кореневим концентратором (root hub), який надає декілька роз'ємів USB для підключення зовнішніх пристроїв. Потім кабелі йдуть до інших пристроїв USB, які також можуть бути концентраторами, і функціональних компонентів (наприклад, модем або акустична система). Концентратори часто вбудовуються в монітори і клавіатури (які є типовими складеними пристроями). Концентратори можуть містити до семи "витікаючих" портів. Для передачі сигналів шина USB використовує чотирипровідною інтерфейс. Одна пара провідників ("+5В" і "загальний") призначена для живлення периферійних пристроїв з навантаженням до 500 мА. Дані передаються по іншій парі ("D+" "D-"). Для передачі даних використовується диференціальна напруга до 3 В (з метою зниження впливу шуму) і схема кодування NRZI (що позбавляє від необхідності виділяти додаткову пару провідників під тактовий сигнал). Всі концентратори повинні підтримувати на своїх витікаючих портах пристрої обох типів, не дозволяючи високошвидкісному трафіку досягати низькошвидкісних пристроїв. Високопродуктивні пристрої підключаються за допомогою екранованого кабелю, довжина якого не повинна перевищувати 3 м. Якщо ж пристрій не формулює особливих вимог до смуги пропускання, його можна підключити і неекранованим кабелем (який може бути тоншим і гнучкішим). Максимальна довжина кабелю для низькошвидкісних пристроїв - 5 м. Вимоги пристрою до живлення (діаметр провідників, споживана потужність) можуть зумовити необхідність використання кабелю меншої довжини. Із-за особливостей розповсюдження сигналу по кабелю число послідовно сполучених концентраторів обмежене шістьма (і сім'ю п'ятиметровими відрізками кабелю). Хост дізнається про підключення або відключення пристрою з повідомлення від концентратора (ця процедура називається опитом шини - bus enumeration). Потім хост привласнює пристрою унікальну адресу USB (1:127). Після відключення пристрою від шини USB його адреса стає доступною для інших пристроїв. Для індивідуального звернення до конкретних функціональних можливостей складеного пристрою застосовується 4-бітове поле кінцевої крапки. У низькошвидкісних пристроях за кожною функцією закріплюється не більше двох адрес кінцевих крапок: нульова кінцева крапка використовується для конфігурації і визначення стану USB, а також управління функціональним компонентом; а інша крапка - відповідно до функціональних можливостей компоненту. Пристрої з максимальною продуктивністю можуть підтримувати до 16 кінцевих крапок, резервуючи нульову крапку для завдань конфігурації і управління USB.Хост опитує всі пристрої і видає їм дозволу на передачу даних (розсилаючи для цього пакет-маркер - Token Packet). Таким чином, пристрої позбавлені можливості безпосереднього обміну даними - всі дані проходять через хост. Ця умова сильно заважала впровадженню інтерфейсу USB на ринок портативних пристроїв. В результаті в кінці 2001 року було прийнято доповнення до стандарту USB 2.0 - специфікація USB OTG (On-The-Go), призначена для з'єднання периферійних USB-устройств один з одним без необхідності підключення до хосту (наприклад, цифрова камера і фотопринтер). Пристрій, підтримуюче USB OTG, здатний частково виконувати функції хоста і розпізнавати, коли воно підключене до повноцінного хосту (на основі ПК), а коли - до іншого периферійного пристрою. Специфікація описує також протокол узгодження вибору ролі хоста при з'єднанні два USB. OTG-пристроїв. Дані на шині передаються транзакціями, інтервал між якими складає 1 мс. Передбачено чотири типи транзакцій. Передачі, що управляють, використовуються для конфігурації знов підключених пристроїв (наприклад, привласнення ним адреси USB) і їх компонентів. Пристрої з максимальною продуктивністю можуть бути налаштовані на роботу з конфігураційними повідомленнями завдовжки 8, 16, 32 або 64 байти (за умовчанням - 8 байт). Пристрої з низькою продуктивністю в змозі розпізнавати повідомлення, що управляють, завдовжки не більше 8 байт. Групова передача (bulk) використовується для адресної пересилки даних великого об'єму (до 1023 байт). Як приклад можна привести передачу даних на принтер або від сканера. Пристрої з низькою продуктивністю не підтримують цей режим. Передача даних переривання, наприклад, введених з клавіатури даних або відомостей про переміщення миші. Ці дані мають бути передані достатньо швидко для того, щоб користувач не відмітив ніякої затримки. Відповідно до специфікацій час затримки USB складає декілька мілісекунд. Ізохронні передачі (передачі в реальному масштабі часу). Пропускна спроможність і затримка доставки обмовляються до початку передачі даних. До ізохронних даних алгоритми корекції помилок непридатні (оскільки час на повторну їх ретрансляцію перевищує допустимий інтервал затримки). За один сеанс в такому режимі може бути передано до 1023 байт. Пристрої з низькою продуктивністю не підтримують цей режим. Слід також відзначити, що різними виробниками пропонувалися специфікації, що описують інтерфейс різних апаратних реалізацій контроллера USB. Фірмою Intel була запропонована специфікація UHCI (Universal Host Controller Interface), яка передбачає надзвичайно просту апаратну реалізацію контроллера USB. В рамках даної специфікації основні функції контролю і арбітражу шини покладаються на програмний драйвер. Альтернативна специфікація була запропонована компаніями Compaq, Microsoft і National Semiconductor - OHCI (Open Host Interface). Контроллери по специфікації OHCI володіють уніфікованим абстрактним інтерфейсом, що передбачає апаратну реалізацію більшості функцій, що управляють, що полегшує їх програмування.
Схема USB:
Розміщення провідників в USB
Номер контакту
Позначення
Колір провідника
1
V BUS
червоний
2
D-
білий
3
D+
зелений
4
GND
чорний
Хід роботи:
Дана програма написана на базі .NET, з використанням мови С++. Для створення проекту використовується Visual Studio 2010. Для створення форми були виконані наступні дії.
1.File -> New -> Project
2. Так як вибрана мова С++ використовуємо компілятор CLR, та шаблон Windows Forms Application, вказується назва проекту та місце його зберігання.
3.Далі використовуємо стандартні налаштування.
4.Потім додаємо на форму потрібні об’єкти. І створюємо подібне вікно
5. Далі пишемо програму для передачі даних. Текст програми міститься у Додатку.
РЕЗУЛЬТАТИ РОБОТИ
Рис. 1. Загальний вигляд вікна програми
Рис. 2. Записуємо інформацію в створений текстовий документ
Рис. 3. При натисканні кнопки READ, нам вибиває повідомлення з інформацією, яка записана в нашому раніше створеному текстовому документі
Рис. 4. Текстовий документ з записаною в ньому інформацією
ГРАФІКИ
1 1 1 1
0 1
0
0
Т – 24410 = 1111 01112
Р – 14410 = 1001 00002
1
0
0 1
0
0
0
0
О – 14210 = 1000 11102
1
0
0
0 1 1 1
0
М – 14010 = 1000 11002
1
0
0
0 1 1
0
0
А – 12810 = 1000 00002
1
0
0
0
0
0
0
0
Н – 14110 = 1000 11012
1
0
0
0 1 1
0 1
О – 14210 = 1000 11102
1
0
0
0 1 1 1
0
В – 13010 = 1000 00102
1
0
0
0
0
0 1
0
С – 14510 = 1001 00012
1
0
0 1
0
0
0 1
Ь – 15610 = 1001 11002
1
0
0 1 1 1
0
0
К – 13810 = 1000 10102
1
0
0
0 1
0 1
0
И – 13610 = 1000 10002
1
0
0
0 1
0
0
0
Й – 13710 = 1000 10012
1
0
0
0 1
0
0 1
Додаток:
Form.h
#pragma once
#include"windows.h"
namespace USBport {
using namespace System;
using namespace System::IO;
using namespace System::Text;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
/// <summary>
/// Summary for Form1
///
/// WARNING: If you change the name of this class, you will need to change the
/// 'Resource File Name' property for the managed resource compiler tool
/// associated with all .resx files this class depends on. Otherwise,
/// the designers will not be able to interact properly with localized
/// resources associated with this form.
/// </summary>
public ref class Form1 : public System::Windows::Forms::Form
{
public:
Form1(void)
{
InitializeComponent();
//
//TODO: Add the constructor code here
//
}
private: System::Windows::Forms::TextBox^ textBox1;
private: System::Windows::Forms::RichTextBox^ richTextBox1;
private: System::Windows::Forms::Button^ button3;
public:
private: System::Windows::Forms::Timer^ timer1;
private: System::Windows::Forms::Button^ button2;
public:
static char* DT=new char[250];
protected:
/// <summary>
/// Clean up any resources being used.
/// </summary>
~Form1()
{
if (components)
{
delete components;
}
}
private: System::Windows::Forms::ComboBox^ comboBox1;
private: System::Windows::Forms::Button^ button1;
private: System::ComponentModel::IContainer^ components;
protected:
private:
/// <summary>
/// Required designer variable.
/// </summary>
#pragma region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
void InitializeComponent(void)
{
this->components = (gcnew System::ComponentModel::Container());
this->comboBox1 = (gcnew System::Windows::Forms::ComboBox());
this->button1 = (gcnew System::Windows::Forms::Button());
this->textBox1 = (gcnew System::Windows::Forms::TextBox());
this->richTextBox1 = (gcnew System::Windows::Forms::RichTextBox());
this->button3 = (gcnew System::Windows::Forms::Button());
this->timer1 = (gcnew System::Windows::Forms::Timer(this->components));
this->button2 = (gcnew System::Windows::Forms::Button());
this->SuspendLayout();
//
// comboBox1
//
this->comboBox1->FormattingEnabled = true;
this->comboBox1->Location = System::Drawing::Point(12, 12);
this->comboBox1->Name = L"comboBox1";
this->comboBox1->Size = System::Drawing::Size(41, 21);
this->comboBox1->TabIndex = 0;
//
// button1
//
this->button1->Enabled = false;
this->button1->Location = System::Drawing::Point(229, 12);
this->button1->Name = L"button1";
this->button1->Size = System::Drawing::Size(115, 23);
this->button1->TabIndex = 1;
this->button1->Text = L"write";
this->button1->UseVisualStyleBackColor = true;
this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click);
//
// textBox1
//
this->textBox1->Location = System::Drawing::Point(59, 13);
this->textBox1->Name = L"textBox1";
this->textBox1->Size = System::Drawing::Size(164, 20);
this->textBox1->TabIndex = 2;
this->textBox1->TextChanged += gcnew System::EventHandler(this, &Form1::textBox1_TextChanged);
//
// richTextBox1
//
this->richTextBox1->Location = System::Drawing::Point(12, 39);
this->richTextBox1->Name = L"richTextBox1";
this->richTextBox1->Size = System::Drawing::Size(458, 57);
this->richTextBox1->TabIndex = 4;
this->richTextBox1->Text = L"";
this->richTextBox1->KeyPress += gcnew System::Windows::Forms::KeyPressEventHandler(this, &Form1::richTextBox1_KeyPress);
//
// button3
//
this->button3->Enabled = false;
this->button3->Location = System::Drawing::Point(360, 11);
this->button3->Name = L"button3";
this->button3->Size = System::Drawing::Size(106, 23);
this->button3->TabIndex = 5;
this->button3->Text = L"read";
this->button3->UseVisualStyleBackColor = true;
this->button3->Click += gcnew System::EventHandler(this, &Form1::button3_Click);
//
// timer1
//
this->timer1->Enabled = true;
this->timer1->Interval = 2000;
this->timer1->Tick += gcnew System::EventHandler(this, &Form1::timer1_Tick);
//
// button2
//
this->button2->Enabled = false;
this->button2->Location = System::Drawing::Point(101, 145);
this->button2->Name = L"button2";
this->button2->Size = System::Drawing::Size(10, 23);
this->button2->TabIndex = 3;
this->button2->Text = L"rewrite";
this->button2->UseVisualStyleBackColor = true;
this->button2->Click += gcnew System::EventHandler(this, &Form1::button2_Click);
//
// Form1
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->BackColor = System::Drawing::SystemColors::ActiveCaption;
this->ClientSize = System::Drawing::Size(482, 109);
this->Controls->Add(this->button3);
this->Controls->Add(this->richTextBox1);
this->Controls->Add(this->button2);
this->Controls->Add(this->textBox1);
this->Controls->Add(this->button1);
this->Controls->Add(this->comboBox1);
this->Name = L"Form1";
this->Text = L"USB";
this->Load += gcnew System::EventHandler(this, &Form1::Form1_Load);
this->ResumeLayout(false);
this->PerformLayout();
}
#pragma endregion
String^ CharToSysString(char* ch)
{
String^ str;
str = gcnew String(ch);
return str;
}
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
if (File::Exists(comboBox1->Text+"\\"+textBox1->Text+".txt")!=true)
{
FileStream^ fs=File::Create(comboBox1->Text+"\\"+textBox1->Text+".txt");
fs->Close();
};
StreamWriter^ sw = File::AppendText(comboBox1->Text+"\\"+textBox1->Text+".txt");
for(int nI=0; nI<richTextBox1->Lines->Length; nI++)
sw->Write(richTextBox1->Lines[nI]+"\r\n");
sw->Close();
}
private: System::Void button3_Click(System::Object^ sender, System::EventArgs^ e)
{
richTextBox1->Clear();
String^ STR="Start";
if(File::Exists(comboBox1->Text+"\\"+textBox1->Text)==true)
{
FileStream^ sw = File::OpenRead(comboBox1->Text+"\\"+textBox1->Text);
array<Byte>^b = gcnew array<Byte>(1024);
UTF8Encoding^ temp = gcnew UTF8Encoding( true );
while ( sw->Read( b, 0, b->Length ) > 0 )
richTextBox1->AppendText( temp->GetString( b ) );
sw->Close();
}else
MessageBox::Show("->in.file.read", ->name.txt, MessageBoxButtons::OK, MessageBoxIcon::Exclamation);
}
private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e)
{
FileStream^ fs=File::Create(comboBox1->Text+"\\"+textBox1->Text+".txt");
fs->Close();
StreamWriter^ sw = gcnew StreamWriter(comboBox1->Text+"\\"+textBox1->Text+".txt");
for(int nI=0; nI<richTextBox1->Lines->Length; nI++)
sw->Write(richTextBox1->Lines[nI]+"\r\n");
sw->Close();
}
private: System::Void timer1_Tick(System::Object^ sender, System::EventArgs^ e)
{
DT[1]=':';
DT[2]='\0';
String^ str;
str = comboBox1->Text;
comboBox1->Text="";
comboBox1->Items->Clear();
for (int nI=0; nI<25; nI++)
{
DT[0] = char(65+nI);
if (GetDriveTypeA(DT)==2)
{
comboBox1->Items->Add(CharToSysString(DT));
if(str==CharToSysString(DT)) comboBox1->Text=str;
}
}
if((comboBox1->Text=="")&&(comboBox1->Items->Count!=0))
comboBox1->Text = comboBox1->Items[0]->ToString();
if(comboBox1->Text=="")
{
button1->Enabled=false;
button2->Enabled=false;
button3->Enabled=false;
}else if((textBox1->Text=="")||(comboBox1->Text==""))
{
button1->Enabled=false;
button2->Enabled=false;
button3->Enabled=false;
}
else
{
button3->Enabled=true;
if(richTextBox1->Lines->Length!=0)
{
button1->Enabled=true;
button2->Enabled=true;
}
}
}
private: System::Void richTextBox1_KeyPress(System::Object^ sender, System::Windows::Forms::KeyPressEventArgs^ e)
{
if((richTextBox1->Lines->Length==0)||(textBox1->Text=="")||(comboBox1->Text==""))
{
button1->Enabled=false;
button2->Enabled=false;
}
else
{
button1->Enabled=true;
button2->Enabled=true;
}
}
private: System::Void textBox1_TextChanged(System::Object^ sender, System::EventArgs^ e)
{
if((textBox1->Text=="")||(comboBox1->Text==""))
{
button1->Enabled=false;
button2->Enabled=false;
button3->Enabled=false;
}
else
{
button3->Enabled=true;
if(richTextBox1->Lines->Length!=0)
{
button1->Enabled=true;
button2->Enabled=true;
}
}
}
private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) {
}
};
}
usb.cpp
// USB port.cpp : main project file.
#include "stdafx.h"
#include "Form1.h"
using namespace USBport;
[STAThreadAttribute]
int main(array<System::String ^> ^args)
{
// Enabling Windows XP visual effects before any controls are created
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
// Create the main window and run it
Application::Run(gcnew Form1());
return 0;
}
Висновок: я ознайомився з процесом передачі даних через послідовний інтерфейс USB; ознайомився з процесом створення елементів програми для сканування USB-портів на наявність підключених пристроїв до послідовного USB інтерфейсу; ознайомився з процесом створення та налаштування основних параметрів програми передачі даних через послідовний USB інтерфейс; ознайомився з процесом формування та передачі посимвольних даних у графічному представленні в схемі кодування NRZI через послідовний USB інтерфейс.