Міністерство освіти і науки України
Національний університет “Львівська політехніка”
Кафедра ЕОМ
Лабораторна робота №1-4
з Переферійних пристроїв
на тему: «Дослідження режимів функціонування інтерфейсу RS-232C»
МЕТА РОБОТИ: ознайомитися з процесом передачі даних через послідовний асинхронний інтерфейс RS-232C (COM-порт).
Короткі теоретичні відомості
Асинхронний послідовний інтерфейс – це основний тип інтерфейсу, за допомогою якого здійснюється передача даних між комп’ютерами. Термін асинхроний означає, що при передачі даних не використовуються ніякі синхронізуючі сигнали, і окремі символи можуть передаватись з випадковими інтервалами, як, наприклад при вводі даних з клавіатури.
Кожному символу, який передається через послідовне з’єднання, мусить передувати стандартний стартовий сигнал, а завершувати його передачу – стоповий сигнал. Стартовий сигнал – це нулевий біт, його ще називають стартовим бітом. Його призначення – повідомити пристою, який приймає дані про те, що наступні вісім бітів представляють собою байт даних. Після символа передаються один чи два стопових біта, які дають сигнал про закінчення передачі символа. В пристрої який приймає дані, символи розпізнаються по появі стартових і стопових сигналів, а не по моменту їх передачі. Асинхроний інтерфейс орієнтований на передачу символів (байтів), а при передачі використовується приблизно 20% інформації тільки для ідентифікації кожного символа.
Рис.1 Роз’єм послідовного порту
Інтерфейс 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”). Після нього йдуть 7 біт даних, потім біт паритету, та 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 на передавальному і приймаючому кінцях лінії зв'язку.
Хід роботи
Лабораторна робота № 1
Створення програми передавача пакетних даних
через COM порт .
МЕТА РОБОТИ: ознайомитися з процесом створення програми передавача пакетних даних через послідовний асинхронний інтерфейс RS-232C (COM-порт).
Хід роботи
Для створення моделі передавача даних через послідовний асинхронний інтерфейс RS-232C (COM-порт) використовую програми Емулятор і передавач.
Рис. 1. Емулятор інтерфейсу RS-232C
За допомогою симулятора можна запустити симуляцію двох.
Рис. 2. Передавач через інтерфейс RS-232C
За допомогою передавача можна підключитись до одного з двох портів які були створені емулятором, і передати повідомлення на приймач.
Лабораторна робота № 2
Створення програми приймача пакетних даних
через COM порт .
МЕТА РОБОТИ: ознайомитися з процесом створення програми приймача пакетних даних через послідовний асинхронний інтерфейс RS-232C (COM-порт).
Хід роботи
Для створення приймача потрібен емулятор, який емулює порти а також програма приймача, яка може приймати повідомлення передавача.
Рис. 3. Приймач через інтерфейс RS-232C
За допомогою передавача можна підключитись до одного з двох портів які були створені симулятором, і отримати повідомлення від передавача.
Лабораторна робота № 3
Відтворення передані та прийому інформації через COM порт у графічному вигляді.
МЕТА РОБОТИ: ознайомитися з процесом формування та передачі пакетних даних у графічному представленні через послідовний асинхронний інтерфейс RS-232C (COM-порт).
Хід роботи
Для того, щоб ознайомитись з передачею даних в графічному вигляді через інтерфейс RS-232C.
Рис. 4. Графік передачі символа ‘К’ через COM-port
На даному графіку поданий графік передачі даних, який включає стартовий біт, інформаційні біти, біт контролю, і 2 біти завершення.
Лабораторна робота № 4
Налаштування портів на передачу та прийом
інформації через COM порт.
МЕТА РОБОТИ: ознайомитися з процесом налаштування основних параметрів прийому – передачі пакетних даних через послідовний асинхронний інтерфейс RS-232C (COM-порт).
Хід роботи
Для того, щоб виконати передачу, потрібно виклнати запус емулятора, підключення Передавача і приймача і виконати передачу інформації.
Рис. 5. Емулятор інтерфейсу RS-232C
Рис. 6. Передавач через інтерфейс RS-232C
Рис. 7. Приймач через інтерфейс RS-232C
Висновок: я ознайомився з процесом передачі даних через послідовний асинхронний інтерфейс RS-232C (COM-порт).
Додаток:
Код програми:
// Sender_RS-232CDlg.h : header file
//
#pragma once
#include "SerialGate.h"
// CSender_RS232CDlg dialog
class CSender_RS232CDlg : public CDialog
{
// Construction
public:
CSender_RS232CDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
enum { IDD = IDD_SENDER_RS232C_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg void OnDraw(void);
inline void DrawLogicLevel_1(CDC *pDC, CPoint & Point, int nDX);
inline void DrawLogicLevel_0(CDC *pDC, CPoint & Point, int nDX);
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
CEdit m_Data;
CEdit m_ComId;
CEdit m_InfoField;
CEdit m_ByteToDrawNumb;
CEdit m_BoudRate;
SerialGate m_objPort;
bool m_bState;
public:
afx_msg void OnBnClickedSendData();
public:
afx_msg void OnBnClickedExit();
public:
afx_msg void OnBnClickedOpen();
public:
afx_msg void OnBnClickedClose();
public:
afx_msg void OnBnClickedDraw(void);
};
// Sender_RS-232CDlg.cpp : implementation file
//
#include "stdafx.h"
#include "Sender_RS-232C.h"
#include "Sender_RS-232CDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CSender_RS232CDlg dialog
CSender_RS232CDlg::CSender_RS232CDlg(CWnd* pParent /*=NULL*/)
: CDialog(CSender_RS232CDlg::IDD, pParent), m_bState(false)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CSender_RS232CDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_EDIT1, m_Data);
DDX_Control(pDX, IDC_EDIT2, m_ComId);
DDX_Control(pDX, IDC_EDIT3, m_InfoField);
DDX_Control(pDX, IDC_EDIT4, m_BoudRate);
DDX_Control(pDX, IDC_EDIT5, m_ByteToDrawNumb);
}
BEGIN_MESSAGE_MAP(CSender_RS232CDlg, CDialog)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDC_SEND_DATA, &CSender_RS232CDlg::OnBnClickedSendData)
ON_BN_CLICKED(IDC_EXIT, &CSender_RS232CDlg::OnBnClickedExit)
ON_BN_CLICKED(IDC_OPEN, &CSender_RS232CDlg::OnBnClickedOpen)
ON_BN_CLICKED(IDC_CLOSE, &CSender_RS232CDlg::OnBnClickedClose)
ON_BN_CLICKED(IDC_DRAW_BYTE, &CSender_RS232CDlg::OnBnClickedDraw)
END_MESSAGE_MAP()
// CSender_RS232CDlg message handlers
BOOL CSender_RS232CDlg::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
m_InfoField.SetWindowTextA("Sender_RS-232C: Data transfer through COM-Port");
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CSender_RS232CDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this function to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CSender_RS232CDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CSender_RS232CDlg::OnBnClickedSendData()
{
if (m_bState)
{
int nStrSize = m_Data.GetWindowTextLengthA()+1;
int nWrittenBytes = 0;
char* strSendFieldBuf =
new char[nStrSize];
m_Data.GetWindowTextA(strSendFieldBuf, nStrSize);
m_objPort.Send(strSendFieldBuf, nStrSize);
m_InfoField.SetWindowTextA("Data was sent!");
delete []strSendFieldBuf;
}
else
m_InfoField.SetWindowTextA("ERROR: COM-port isn't opened!");
}
void CSender_RS232CDlg::OnBnClickedExit()
{
OnOK();
}
void CSender_RS232CDlg::OnBnClickedOpen()
{
const int BOUD_BUF_SIZE = 6;
char ptrIdBuf[] = "1"; //com-port id buf
m_ComId.GetWindowTextA(ptrIdBuf, sizeof(ptrIdBuf)); //read id symbol
char ptrBoudBuf[BOUD_BUF_SIZE] = ""; //boud rate buffer size
m_BoudRate.GetWindowTextA(ptrBoudBuf, sizeof(ptrBoudBuf)); //read boud rate
//is everything all right at the time of COM-port opening ?
if (m_objPort.Open(atoi(ptrIdBuf), atoi(ptrBoudBuf)))
{
m_bState = true;
m_InfoField.SetWindowTextA("COM-port is opened!");
m_ByteToDrawNumb.SetWindowTextA("0");
}
else
{
m_bState = false;
m_InfoField.SetWindowTextA("ERROR: Cannot open a COM-port!");
}
}
void CSender_RS232CDlg::OnBnClickedClose()
{
if (m_bState)
{
m_objPort.Close();
m_InfoField.SetWindowTextA("COM-port is closed!");
m_bState = false;
RedrawWindow();
}
else
m_InfoField.SetWindowTextA("ERROR: COM-port isn't opened!");
}
inline void CSender_RS232CDlg::DrawLogicLevel_1(CDC *pDC, CPoint & Point, int nDX)
{
if (Point.y == 240)
{
pDC->MoveTo(Point);
Point.Offset(0, -100);
pDC->LineTo(Point);
}
pDC->MoveTo(Point);
Point.Offset(nDX, 0);
pDC->LineTo(Point);
}
inline void CSender_RS232CDlg::DrawLogicLevel_0(CDC *pDC, CPoint & Point, int nDX)
{
if (Point.y == 140)
{
pDC->MoveTo(Point);
Point.Offset(0, 100);
pDC->LineTo(Point);
}
pDC->MoveTo(Point);
Point.Offset(nDX, 0);
pDC->LineTo(Point);
}
void CSender_RS232CDlg::OnDraw(void)
{
int nX = 325, nY = 250; //coordinate grid center
int nDX = 23; //marks offset
char pByteToDrawInd[] = "0";
char chByteToDraw = '0';
if (m_bState)
{
//getting byte to draw
m_ByteToDrawNumb.GetWindowTextA(pByteToDrawInd, sizeof(pByteToDrawInd));
int nStrSize = m_Data.GetWindowTextLengthA()+1;
char* strSendFieldBuf =
new char[nStrSize];
m_Data.GetWindowTextA(strSendFieldBuf, nStrSize);
chByteToDraw = strSendFieldBuf[atoi(pByteToDrawInd)];
//settings
CDC *pDC = GetWindowDC();
pDC->SaveDC();
CPen p1(PS_SOLID, 2, RGB(0, 0, 0)),
p2(PS_SOLID, 2, RGB(0, 255, 0));
CBrush brush(RGB(0, 255, 0));
CRect rect;
pDC->SelectObject(p1);
pDC->SelectObject(brush);
pDC->SetTextColor(RGB(0, 0, 255));
pDC->SetBkColor(RGB(230, 230, 255));
//drawing coordinate axis
pDC->MoveTo(nX , nY);
pDC->LineTo(nX + 275, nY);
pDC->MoveTo(nX , nY);
pDC->LineTo(nX , nY - 125);
//drawing coordinate axis marks
pDC->MoveTo(nX - 3, nY - 10);
pDC->LineTo(nX + 3, nY - 10);
pDC->MoveTo(nX - 3, nY - 110);
pDC->LineTo(nX + 3, nY - 110);
//start-bit
pDC->TextOutA(nX, nY + 6, "start");
pDC->SelectObject(p2);
pDC->MoveTo(nX + 5, nY - 10);
pDC->LineTo(nX + 5, nY - 110);
pDC->MoveTo(nX + 5, nY - 10);
pDC->LineTo(nX + 5 + nDX, nY - 10);
//8-bit data
const int DATA_SIZE = 8;
CPoint CurrentPoint(nX + nDX + 5, nY - 10);
int nBitMask = 0x80;
int nBit = 1;
int nParBit = 0;
for (nBit; nBit<=DATA_SIZE; ++nBit)
{
pDC->SelectObject(p1);
pDC->MoveTo(nX + 5 + nDX * nBit, nY-3);
pDC->LineTo(nX + 5 + nDX * nBit, nY+3);
pDC->SelectObject(p2);
if (chByteToDraw & (nBitMask>>(nBit-1)))
{
DrawLogicLevel_1(pDC, CurrentPoint, nDX);
pDC->TextOutA(nX + 5 + nDX * nBit + nDX/2, nY + 6, "1");
}
else
{
DrawLogicLevel_0(pDC, CurrentPoint, nDX);
pDC->TextOutA(nX + 5 + nDX * nBit + nDX/2, nY + 6, "0");
}
nParBit ^= bool(chByteToDraw & (nBitMask>>(nBit-1)));
}
pDC->SelectObject(p1);
//parity bit
pDC->MoveTo(nX + 5 + nDX * nBit, nY-3);
pDC->LineTo(nX + 5 + nDX * nBit, nY+3);
pDC->TextOutA(nX + 5 + nDX * nBit, nY + 6, "par");
pDC->SelectObject(p2);
if (nParBit)
{
DrawLogicLevel_1(pDC, CurrentPoint, nDX);
}
else
{
DrawLogicLevel_0(pDC, CurrentPoint, nDX);
}
//stop-bit
pDC->SelectObject(p1);
pDC->MoveTo(nX + 5 + nDX * (++nBit), nY-3);
pDC->LineTo(nX + 5 + nDX * nBit, nY+3);
pDC->TextOutA(nX + 5 + nDX * nBit, nY + 6, "stop");
pDC->MoveTo(nX + 5 + nDX * (++nBit), nY-3);
pDC->LineTo(nX + 5 + nDX * nBit, nY+3);
pDC->SelectObject(p2);
DrawLogicLevel_1(pDC, CurrentPoint, nDX);
pDC->SelectObject(p1);
pDC->TextOutA(nX - 12, nY - 22, "0");
pDC->TextOutA(nX - 12, nY - 122, "1");
pDC->RestoreDC(-1);
}
else
m_InfoField.SetWindowTextA("ERROR: COM-port isn't opened!");
}
void CSender_RS232CDlg::OnBnClickedDraw(void)
{
RedrawWindow();
if (m_bState)
OnDraw();
}