Міністерство освіти і науки України
Національний університет “Львівська політехніка”
Кафедра ЕОМ
/
Лабораторна робота №1-4
з дисципліни «Переферійних пристроїв»
«Дослідження режимів функціонування інтерфейсу»
RS-232C
ТЕОРЕТИЧНІ ВІДОМОСТІ
Асинхронний послідовний інтерфейс – це основний тип інтерфейсу, за допомогою якого здійснюється передача даних між комп’ютерами. Термін асинхроний означає, що при передачі даних не використовуються ніякі синхронізуючі сигнали, і окремі символи можуть передаватись з випадковими інтервалами, як, наприклад при вводі даних з клавіатури.
Кожному символу, який передається через послідовне з’єднання, мусить передувати стандартний стартовий сигнал, а завершувати його передачу – стоповий сигнал. Стартовий сигнал – це нулевий біт, його ще називають стартовим бітом. Його призначення – повідомити пристою, який приймає дані про те, що наступні вісім бітів представляють собою байт даних. Після символа передаються один чи два стопових біта, які дають сигнал про закінчення передачі символа. В пристрої який приймає дані, символи розпізнаються по появі стартових і стопових сигналів, а не по моменту їх передачі. Асинхроний інтерфейс орієнтований на передачу символів (байтів), а при передачі використовується приблизно 20% інформації тільки для ідентифікації кожного символа.
Термін послідовний означає, що передача даних виконується по одиночному провіднику, а біти передаються послідовно один за другим. Такий тип зв’язку характерний для телефонної мережі, в якій кожний напрямок обслуговує один провідник. Багато компаній випускають доповняльні послідовні порти для комп’ютерів, звичайно ті порти встановлюються на багатофункціональних платах чи на платі з паралельним портом. На рисунку 1, показано стандартний 9-контактний роз’єм послідовного порта:
/
Рис.1 Роз’єм послідовного порту
До послідовного порта можна підключити самі різноманітні пристрої: модеми, плотери, принтери, інші комп’ютери, пристрої зчитування штрих-кодів, схему керування пристроями чи макетну плату. В основному у всіх пристроях, для яких потрібен двонапрямлений зв’язок з комп’ютером, використовується порт, який став стандартом – RS-232C (Reference Standard number 232 version C – стандарт обміну номер 232 версії С), який дозволяє передавати дані між несумісними пристроями.
Інтерфейс RS - 232С широко використовують у персональних
комп'ютерах для обміну інформацією з периферійними пристроями у послідовному дуплексному режимі обміну. Спрощений варіант інтерфейсу С2 є аналогом інтерфейсу RS - 232С для колишніх країн економічної співдружності. Швидкість передавання даних в асинхронному режимі може становити біт/с: 50, 75, 100, 150, 300, 600, 1200, 2400, 4800, 9600, 19200.
Інтерфейс RS-232C розроблено в 1969 році рядом корпорацій США для забезпечення з’єднання комп’ютерів та різноманітних периферійних пристроїв. Стандарт RS-232 в загальному випадку описує 4 інтерфейсні функції:
1. Визначення керувальних сигналів, що передаються через інтерфейс.
2. Визначення формату даних користувача, що передаються через інтерфейс.
3. Передачу тактових сигналів для синхронізації потоку даних.
4. Формування електричних характеристик інтерфейсу.
Інтерфейс RS-232 є послідовним асинхронним інтерфейсом, в якому перед бітами даних передається спеціальний стартовий біт, після бітів даних йде біт паритета та 1 чи 2 стопових біти. Така сукупність бітів носить назву старт-стопного символу. Кожний старт-стопний символ, як правило, у якості бітів даних містить один інформаційний символ, наприклад, символ стандартного коду для обміну інформацією, що задається таблицею ASCII. Символи ASCII відображаються семибітовими кодовими словами. Так, наприклад, латинська буква А має код 1000001. Її передача рівнями ТТЛ зображена на рис. 2.
Початок асинхронного символу завжди відмічається низьким рівнем стартового рівня (“0”). Після нього йдуть 8 біт даних, потім біт паритету, та 2 стопових біти. Біт паритету встановлюється в “1”, або “0”, наприклад, непарний паритет характеризується тим, що загальна кількість одиниць в групі з восьми біт повинно бути непарним числом. Стопові біти передаються високим рівнем (“1”).
/
Рис.2 Схема передачі даних через RS-232C.
Комп'ютер має 25-контактний (DB25P) або 9-контактний (DB9P) роз'єми для підключення RS-232C. Розташування контактів роз’ємів зображене на рисунку 3. Призначення контактів роз'ємів приведене в таблиці 1.
//
Рис. 3 Розташування контактів роз’ємів DB25P та DB9P
Таблиця 1. Призначення контактів роз’ємів DB25P та DB9P
Найменування
Напрям
Опис
Контакт(25-контактний роз'єм DB25P )
Контакт(9-контактний роз'єм DB9P)
DCD
IN
Carrie Detect (Визначення несучої)
8
1
- RXD
IN
Receive Data (Дані, що приймаються)
3
2
- TXD
OUT
Transmit Data (Дані, що передаються)
2
3
DTR
OUT
Data Terminal Ready (Готовність терміналу)
20
4
GND
-
System Ground (Корпус системи)
7
5
DSR
IN
Data Set Ready (Готовність даних)
6
6
RTS
OUT
Request to Send (Запит на відправку)
4
7
CTS
IN
Clear to Send (Готовність прийому)
5
8
RI
IN
Ring Indicator (Індикатор)
22
9
Найчастіше використовуються трьох- або чотирьохпровідний зв'язок (для двонаправленої передачі). Схема з'єднання для чотирьохпровідної лінії зв'язку показана на рисунку 4.
/
Рис.4 Схема 4-провідної лінії зв'язку для RS-232C
Для двопровідної лінії зв'язку у випадку передачі з комп'ютера на зовнішній пристрій використовуються сигнали SG і TхD. Всі 10 сигналів інтерфейсу задіюються лише при з'єднанні комп'ютера з модемом.
Формат даних, що передаються, показаний на рисунку 5. Власне дані (5, 6, 7 або 8 біт) супроводжуются стартовим бітом, бітом парності і одним або двома стоповими бітами. Отримавши стартовий біт, приймач вибирає з лінії біти даних через визначені інтервали часу. Дуже важливо, щоб тактові частоти приймача і передавача були однаковими, допустима розбіжність - не більше 10 %
/
Рис. 5 Формат даних RS-232C
Всі сигнали RS-232C передаються спеціально вибраними рівнями, що забезпечують високу завадостійкість зв'язку (рис.6). Відзначимо, що дані передаються в інверсному коді (логічній одиниці відповідає низький рівень, логічному нулю - високий рівень).
/
Рис. 6 Рівні сигналів RS-232C на передавальному і приймаючому кінцях лінії зв'язку.
Обмін по RS-232C здійснюється за допомогою звернень по спеціально виділених для цього портах COM1 (адреси 3F8h...3FFh, переривання IRQ4), COM2 (адреси 2F8h...2FFh, переривання IRQ3), COM3 (адреси 3F8h...3EFh, переривання IRQ10), COM4 (адреси 2E8h...2EFh, переривання IRQ11). Формати звернень по цих адресах можна знайти в численних описах мікросхем контроллерів послідовного обміну UART (Universal Asynchronous Receiver/Transmitter), наприклад, i8250, КР580ВВ51.
Алгоритм налаштування приймача перед початком роботи:
Алгоритм налаштування передавача перед початком роботи:
Алгоритм роботи приймача:
Алгоритм роботи передавача:
Оболонка програми/
Текст програми реалізованої в даній лабораторній роботі:
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Drawing;
namespace lab_1_signal
{
class grafik
{
private int x;
private int y;
private int signal;
private int signalold;
private int xg;
public grafik()
{
x = 20;
xg = 50;
y = 125;
signal = 0;
signalold = 0;
}
public void set(int x1, int x2, int so)
{
signalold = so;
signal = x1;
x = x2;
}
public void kv(object sander, PaintEventArgs e)
{
Graphics g = e.Graphics;
// g = Graphics.FromHwnd(this.Handle);
//18.674
Pen p = new Pen(Color.Black, 2);
//gr = Graphics.FromHwnd(label1.Handle);
Font f = new Font("Arial" , 12);
g.DrawLine(p, 18, 680, 18, 524);
g.DrawString("1",f,Brushes.Black,5,524);
g.DrawString("0",f,Brushes.Black,5,660);
g.DrawLine(p, 18, 680, 1041, 680);
while (xg < 1041)
{
g.DrawLine(p, xg, 674, xg , 684);
xg = xg + 20;
}
}
public void d(object sanger, PaintEventArgs e)
{
if (signal == 1 && signalold != 1)
{
Graphics g = e.Graphics;
Pen p = new Pen(Color.Lime,
g.DrawLine(p, x, y, x, y - 100);
g.DrawLine(p, x, y - 100, x + 20, y - 100);
Point po = new Point();
po.X = x+1;
po.Y = y - 20;
System.Drawing.Font font = new System.Drawing.Font("Arial", 14);
g.DrawString("1", font, Brushes.Lime, po);
}
if (signal == 0 && signalold == 1)
{
Graphics g = e.Graphics;
Pen pg = new Pen(Color.Lime, 3);
Pen pr = new Pen(Color.Red,3);
g.DrawLine(pg, x, y, x, y - 100);
g.DrawLine(pr, x, y , x + 20, y);
Point po = new Point();
po.X = x + 1;
po.Y = y - 20;
System.Drawing.Font font = new System.Drawing.Font("Arial", 14);
g.DrawString("0", font, Brushes.Red, po);
}
if (signal == 1 && signalold == 1)
{
Graphics g = e.Graphics;
Pen p = new Pen(Color.Lime, 3);
g.DrawLine(p, x, y - 100, x + 20, y - 100);
Point po = new Point();
po.X = x + 1;
po.Y = y - 20;
System.Drawing.Font font = new System.Drawing.Font("Arial", 14);
g.DrawString("1", font, Brushes.Lime, po);
}
if (signal == 0)
{
Graphics g = e.Graphics;
Pen p = new Pen(Color.Red, 3);
g.DrawLine(p, x, y, x + 20, y);
Point po = new Point();
po.X = x + 1;
po.Y = y - 20;
System.Drawing.Font font = new System.Drawing.Font("Arial", 14);
g.DrawString("0", font, Brushes.Red, po);
}
}
}
}
Клас , який реалізує анімацію передачі :
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace lab_1_signal
{
class Class1
{
protected int x1;
protected int y1;
protected int y;
public void set(int x, int c)
{
x1 = x;
y1 = c;
// MessageBox.Show(x.ToString() + "\n" + y.ToString());
}
public void pc(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
if (y1 == 49)
{
Pen p = new Pen(Color.Lime, 5);
y = 85;
g.DrawLine(p, x1, 75, x1 + 15, 75);
}
if (y1 == 48)
{
Pen p = new Pen(Color.Red, 5);
y = 105;
g.DrawLine(p, x1, 105, x1 + 15, 105);
}
}
}
}
Основний код програми , в якому реалізується моделі передавача , приймача , та їх взаємодія :
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using System.Runtime.InteropServices;
namespace lab_1_signal
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
int i=105;
int bitout = 8;
int bitin = 8;
int signal = 0;
int start = 0;
int[] mas = new int[70];
string s1;
int s = 1;
int j = 0;
int[] peredacha = new int[70];
int[] prujom = new int[70];
string sinput;
int cperedacha = 0; // лічильник бітів даних
int cprujom = 0;
int parity = 0; // перевірка на парність
int cparity = 0; // лічильник бітів на парність
int cperedachaz = 0; // zagalna peredacha
int takt=0;
int probil = 0;
int stop = 0;
int taktp = 0;
int parity_prujom = 0;
int dani = 0;
int x = 10;
int oldsignal = 0;
Class1 p = new Class1();
private void button1_Click(object sender, EventArgs e)
{
new Thread(go).Start();
// new Thread(go).Abort();
}
private void go()
{
int l = s1.Length;
int j = 0;
int x=0;
progressBar1.Maximum = l;
while (j < l)
{
x = Convert.ToInt32(s1[j]);
//MessageBox.Show(x.ToString());
if (x==49 || x==48 ) label4.Text = label4.Text + (x - 48).ToString();
pictureBox1.Paint += p.pc;
p.set(i, x);
while (i < 770)
{
p.set(i,x);
pictureBox1.Refresh();
i=i+s;
}
pictureBox1.Paint -= p.pc;
i = 0;
j++;
progressBar1.Value = j;
}
}
private void timer1_Tick(object sender, EventArgs e )
{
// pictureBox1.Refresh();
}
private void Form1_Load(object sender, EventArgs e)
{
s1 = label3.Text;
pictureBox1.Refresh();
// pictureBox1.Paint += p.pc;
this.Height = 563;
this.Width = 1069;
}
private void button6_Click(object sender, EventArgs e)
{
s1 = label3.Text;
int q = Convert.ToInt32(s1[0]);
int q1 = Convert.ToInt32(s1[1]);
int q2 = Convert.ToInt32(s1[2]);
int q3 = Convert.ToInt32(s1[3]);
MessageBox.Show(q.ToString() + q1.ToString() + q2.ToString() + q3.ToString());
//MessageBox.Show(s1[0].ToString() + s1[1].ToString() + s1[2].ToString() + s1[3].ToString());
//MessageBox.Show(s1[1].ToString());
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
s = trackBar1.Value;
}
private void trackBar2_Scroll(object sender, EventArgs e)
{
if (trackBar2.Value == 0) timer2.Interval = 300;
if (trackBar2.Value == 1) timer2.Interval = 200;
if (trackBar2.Value == 2) timer2.Interval = 100;
if (trackBar2.Value == 3) timer2.Interval = 50;
}
private void timer2_Tick(object sender, EventArgs e)
{
if (bitout==4)
{
if (cperedachaz == 0 + takt) // startovuj bit
{
signal = 1;
label6.Text = label6.Text + " ";
}
if (cperedachaz == 6 + takt) //stopovij bit
{
label6.Text = label6.Text + " ";
signal = 0;
takt = takt + 7;
if (stop == 1)
{
timer2.Enabled = false;
timer3.Enabled = false;
label7.Text = label7.Text + " 0";
richTextBox2.Text = richTextBox2.Text + "0" ;
}
}
if (cperedachaz == 5 + takt) //kontrolnij bit
{
label6.Text = label6.Text + " ";
signal = parity;
cparity = 0;
}
if (cperedachaz > 0 + takt && cperedachaz < 5 + takt) // informacijni bitu
{
if (probil == 0)
{
label6.Text = label6.Text + " ";
probil = 1;
}
//if (cperedacha == 0) label6.Text = label6.Text + " ";
//if ((cperedacha + 2) % 9 == 0 ) label6.Text = label6.Text + " ";
j = sinput[cperedacha];
if (j == 49) // робим перевірку на парність , збільшуєм лічильник парності
{
signal = 1;
cparity++;
}
if (j == 48) signal = 0;
if ((cperedacha + 1) % 4 == 0) // відправило 8 інфо біт передаєм біт парності
{
if (cparity % 2 == 0) parity = 0;
else parity = 1;
cparity = 0;
probil = 0;
}
cperedacha++;
if (cperedacha == sinput.Length)
{
stop = 1;
//timer2.Enabled = false;
//timer3.Enabled = false;
}
}
//малювалка
pictureBox1.Paint += p.pc;
grafik gr = new grafik();
gr.set(signal, x, oldsignal);
oldsignal = signal;
label14.Paint += gr.d;
x = x + 20;
label14.Width = label14.Width + 20;
p.set(i, j);
while (i < 770)
{
p.set(i, j);
pictureBox1.Refresh();
i = i + trackBar2.Value + 2;
}
pictureBox1.Paint -= p.pc;
i = 0;
//
label6.Text = label6.Text + signal.ToString();
cperedachaz++;
}
if (bitout == 8)
{
if (cperedachaz == 0 + takt) // startovuj bit
{
signal = 1;
label6.Text = label6.Text + " ";
}
if (cperedachaz == 10 + takt) //stopovij bit
{
label6.Text = label6.Text + " ";
signal = 0;
takt = takt + 11;
if (stop == 1)
{
timer2.Enabled = false;
timer3.Enabled = false;
label7.Text = label7.Text + " 0";
richTextBox2.Text = richTextBox2.Text + "0";
}
}
if (cperedachaz == 9 + takt) //kontrolnij bit
{
label6.Text = label6.Text + " ";
signal = parity;
cparity = 0;
}
if (cperedachaz > 0 + takt && cperedachaz < 9 + takt) // informacijni bitu
{
if (probil == 0)
{
label6.Text = label6.Text + " ";
probil = 1;
}
//if (cperedacha == 0) label6.Text = label6.Text + " ";
//if ((cperedacha + 2) % 9 == 0 ) label6.Text = label6.Text + " ";
j = sinput[cperedacha];
if (j == 49) // робим перевірку на парність , збільшуєм лічильник парності
{
signal = 1;
cparity++;
}
if (j == 48) signal = 0;
if ((cperedacha + 1) % 8 == 0) // відправило 8 інфо біт передаєм біт парності
{
if (cparity % 2 == 0) parity = 0;
else parity = 1;
cparity = 0;
probil = 0;
}
cperedacha++;
if (cperedacha == sinput.Length)
{
stop = 1;
//timer2.Enabled = false;
//timer3.Enabled = false;
}
}
//малювалка
pictureBox1.Paint += p.pc;
grafik gr = new grafik();
gr.set(signal, x, oldsignal);
oldsignal = signal;
label14.Paint += gr.d;
x = x + 20;
label14.Width = label14.Width + 20;
pictureBox1.Paint += p.pc;
p.set(i, j);
while (i < 770)
{
p.set(i, j);
pictureBox1.Refresh();
i = i + trackBar2.Value + 2;
}
pictureBox1.Paint -= p.pc;
i = 0;
//
label6.Text = label6.Text + signal.ToString();
cperedachaz++;
}
}
private void dekoder()
{
if (label13.Text == "10010111") richTextBox3.Text = richTextBox3.Text + "Ч" + "\n";
if (label13.Text == "10100101") richTextBox3.Text = richTextBox3.Text + "е" + "\n";
if (label13.Text == "11100000") richTextBox3.Text = richTextBox3.Text + "р" + "\n";
if (label13.Text == "10100010") richTextBox3.Text = richTextBox3.Text + "в" + "\n";
if (label13.Text == "10100000") richTextBox3.Text = richTextBox3.Text + "а" + "\n";
if (label13.Text == "10101010") richTextBox3.Text = richTextBox3.Text + "к" + "\n";
}
private void cleen()
{
cperedacha = 0;
//label14.BackColor = Color.Aqua;
label6.Text = "";
label7.Text = "";
richTextBox2.Text = "";
richTextBox3.Text = "";
i = 105;
signal = 0;
start = 0;
s = 1;
j = 0;
cperedacha = 0; // лічильник бітів даних
cprujom = 0;
parity = 0; // перевірка на парність
cparity = 0; // лічильник бітів на парність
cperedachaz = 0; // zagalna peredacha
takt = 0;
probil = 0;
stop = 0;
taktp = 0;
parity_prujom = 0;
dani = 0;
}
private void button7_Click(object sender, EventArgs e)
{
timer2.Enabled = true;
timer3.Enabled = true;
//signal = 1;
//label6.Text = label6.Text + " " + signal.ToString();
sinput = label10.Text;
}
private void timer3_Tick(object sender, EventArgs e)
{
if (bitin == 4)
{
if (start == 0 && signal == 1) start = 1;
if (start == 1)
{
if (cprujom == 0 + taktp) // startovuj
{
label7.Text = label7.Text + " ";
if (signal == 1)
{
label7.Text = label7.Text + signal.ToString();
richTextBox2.Text = richTextBox2.Text +"\n"+ signal.ToString()+"\t";
}
if (signal == 0)
{
label7.Text = label7.Text + signal.ToString() + " error";
richTextBox2.Text = richTextBox2.Text + "\n"+signal.ToString()+ "Error" + "\t";
}
}
if (cprujom > 0 + taktp && cprujom < 5 + taktp) // dani
{
if (dani == 0)
{
label7.Text = label7.Text + " ";
label13.Text = "";
}
if (signal == 1) parity_prujom++;
dani++;
label13.Text = label13.Text + signal.ToString();
label7.Text = label7.Text + signal.ToString();
richTextBox2.Text = richTextBox2.Text + signal.ToString();
if (dani == 4)
{
dani = 0;
richTextBox2.Text = richTextBox2.Text + "\t";
}
}
if (cprujom == 5 + taktp) // parnist
{
label7.Text = label7.Text + " ";
if (parity_prujom % 2 == 0 && signal == 0)
{
label7.Text = label7.Text + signal.ToString();
richTextBox2.Text = richTextBox2.Text + signal.ToString()+"\t";
}
if (parity_prujom % 2 == 0 && signal == 1)
{
label7.Text = label7.Text + signal.ToString() + "error";
richTextBox2.Text = richTextBox2.Text + signal.ToString() + "error" + "\t";
}
if (parity_prujom % 2 == 1 && signal == 0)
{
label7.Text = label7.Text + signal.ToString() + "error";
richTextBox2.Text = richTextBox2.Text + signal.ToString() + "error"+"\t";
}
if (parity_prujom % 2 == 1 && signal == 1)
{
label7.Text = label7.Text + signal.ToString();
richTextBox2.Text = richTextBox2.Text + signal.ToString()+"\t";
}
parity_prujom = 0;
}
if (cprujom == 6 + taktp) // stoop
{
label7.Text = label7.Text + " ";
if (signal != 0)
{
label7.Text = label7.Text + signal.ToString() + "error";
richTextBox2.Text = richTextBox2.Text + signal.ToString() + "error" + "\t";
}
label7.Text = label7.Text + signal.ToString();
richTextBox2.Text = richTextBox2.Text + signal.ToString() +"\t";
taktp = taktp + 7;
}
//label7.Text = label7.Text + " " + signal.ToString();
cprujom++;
}
}
if (bitin == 8)
{
if (start == 0 && signal == 1) start = 1;
if (start == 1)
{
if (cprujom == 0 + taktp) // startovuj
{
label7.Text = label7.Text + " ";
if (signal == 1)
{
label7.Text = label7.Text + signal.ToString();
richTextBox2.Text = richTextBox2.Text + "\n" + signal.ToString() + "\t";
}
if (signal == 0)
{
label7.Text = label7.Text + signal.ToString() + " error";
richTextBox2.Text = richTextBox2.Text + "\n" + signal.ToString() + "Error" + "\t";
}
}
if (cprujom > 0 + taktp && cprujom < 9 + taktp) // dani
{
if (dani == 0)
{
label7.Text = label7.Text + " ";
label13.Text = "";
}
if (signal == 1) parity_prujom++;
dani++;
label13.Text = label13.Text + signal.ToString();
label7.Text = label7.Text + signal.ToString();
richTextBox2.Text = richTextBox2.Text + signal.ToString();
if (dani == 8)
{
dekoder();
dani = 0;
richTextBox2