Міністерство освіти і науки України
Національний університет „ Львівська політехніка”
Кафедра EOM
Звіт
з предмету: “Периферійні пристрої”
по лабораторних роботах №1 - №4
«Дослідження режимів функціонування інтерфейсу RS-232C»
МЕТА РОБОТИ: ознайомитися з процесом передачі даних через послідовний асинхронний інтерфейс RS-232C (COM-порт).
Короткі теоретичні відомості
Асинхронний послідовний інтерфейс – це основний тип інтерфейсу, за допомогою якого здійснюється передача даних між комп’ютерами. Термін асинхроний означає, що при передачі даних не використовуються ніякі синхронізуючі сигнали, і окремі символи можуть передаватись з випадковими інтервалами, як, наприклад при вводі даних з клавіатури.
Кожному символу, який передається через послідовне з’єднання, мусить передувати стандартний стартовий сигнал, а завершувати його передачу – стоповий сигнал. Стартовий сигнал – це нулевий біт, його ще називають стартовим бітом. Його призначення – повідомити пристою, який приймає дані про те, що наступні вісім бітів представляють собою байт даних. Після символа передаються один чи два стопових біта, які дають сигнал про закінчення передачі символа. В пристрої який приймає дані, символи розпізнаються по появі стартових і стопових сигналів, а не по моменту їх передачі. Асинхроний інтерфейс орієнтований на передачу символів (байтів), а при передачі використовується приблизно 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 відображаються семибітовими кодовими словами.
Хід роботи
Перед виконанням роботи я детально вивчив поставлене мені завдання: промоделювати передачу даних між двома COM – портами. Поставлену мені роботу я виконував у програмному середовищі Visual Studio 2011 за допомогою MFC application. Також я врахував, що по закінченню роботи я повинен представити викладачеві графік, який демонструє правильність передачі та отримання даних. Я працював із компортами на швидкості 9600 біт/с, як і при передаванні, так і при прийманні.
Перш за все, потрібно увімкнути модуляцію COM-портів у режимі «пара», це продемонстровано на рис.1 та рис.2:
/
Рис.1 Задання типу зв’язку – «пара»
/
Рис.2 Додавання у «пару» COM-портів
По натисканні клавіші «Готово» ми отримаємо створену «пару», що складається з таких пристроїв: COM1 та COM2.
Після створення «пари», перейдемо безпосередньо до передачі даних між COM-портами, для цього налаштуємо підключення COM-портів одне до одного, а також установимо швидкість передачі даних у режимі 9600 біт/с, продемонструємо це на рис.3 та рис.4:
/
Рис.3 Підключення до першого COM-порта
/
Рис.4 Підключення до другого COM-порта
Після успішного створення підключення між COM-портами, перейдемо до пересилання даних. На рис.5 та рис.6 наводиться результати пересилання даних(слово – «Kutaev») від першого COM-порта до другого COM-порта у вигляді часової діаграми, яка представлена в інверсному вигляді:
/
Рис.5 Представлення результату пересилання перших 3-ох літер слова «Kutaev» у вигляді часової діаграми, яка представлена в інверсному вигляді
/
Рис.6 Представлення результату пересилання останніх 3-ох літер слова «Kutaev» у вигляді часової діаграми, яка представлена в інверсному вигляді
Після успішного пересилання даних від першого COM-порта до другого COM-порта, перейдемо до пересилання даних від другого COM-порта до першого COM-порта. На рис.7 та рис.8 наводиться результати пересилання даних(слово – «Kutaev») від другого COM-порта до першого COM-порта у вигляді часової діаграми, яка представлена в інверсному вигляді:
/
Рис.7 Представлення результату пересилання перших 3-ох літер слова «Kutaev» у вигляді часової діаграми, яка представлена в інверсному вигляді
/
Рис.8 Представлення результату пересилання останніх 3-ох літер слова «Kutaev» у вигляді часової діаграми, яка представлена в інверсному вигляді
Висновки
Я ознайомився з процесом передачі даних через послідовний асинхронний інтерфейс RS-232C (COM-порт). Навчився проводити модуляцію COM-портів у режимі «пара», пересилати та приймати дані між COM-портами.
Додатки
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections;
using System.Globalization;
using System.IO.Ports;
using System.Threading;
using System.Windows.Threading;
namespace Port_No_Stupid
{
/// <summary>
/// Interaction logic for MainWindow.xaml
///
/// </summary>
public partial class MainWindow : Window
{
#region змінні
//Richtextbox
FlowDocument mcFlowDoc = new FlowDocument();
Paragraph para = new Paragraph();
//Serial
SerialPort serial = new SerialPort();
string recieved_data;
double Jump = 0.2;
int Lenth=220;
bool [] data=new bool [220];
const int countDot = 30;
List<double[]> dataList = new List<double[]>();
DrawingGroup drawingGroup = new DrawingGroup();
#endregion
public MainWindow()
{
InitializeComponent(); Connect_btn.Content = "Підключитись";
NullData();
Execute();
image1.Source = new DrawingImage(drawingGroup);
}
void Drawing()
{
Execute();
image1.Source = new DrawingImage(drawingGroup);
}
#region створення графіки
void Execute()
{
MaketFun();
GrafFun();
MarkerFun();
}
private void MaketFun()
{
GeometryGroup geometryGroup = new GeometryGroup();
LineGeometry lineV = new LineGeometry(new Point(0.1,0),new Point (0.1,1));
geometryGroup.Children.Add(lineV);
LineGeometry lineH = new LineGeometry(new Point(0, 0.8), new Point(Lenth/3, 0.8));
geometryGroup.Children.Add(lineH);
GeometryDrawing gd = new GeometryDrawing();
gd.Geometry = geometryGroup;
gd.Pen = new Pen(Brushes.Green, 0.02);
drawingGroup.Children.Add(gd);
}
private void AditionMarkerFun( )
{
GeometryGroup geometryGroup = new GeometryGroup();
string str = new TextRange(Commdata.Document.ContentStart, Commdata.Document.ContentEnd).Text;
for (int i = 0; i < str.Length; i++)
{
FormattedText formattedText = new FormattedText(str[i].ToString(),
CultureInfo.CurrentCulture,
FlowDirection.LeftToRight,
new Typeface("Verdana"),
0.1,
Brushes.Black);
Geometry geometry = formattedText.BuildGeometry(new Point(i*2.2+1, 0.95));
geometryGroup.Children.Add(geometry);
}
GeometryDrawing geometryDrawing = new GeometryDrawing();
geometryDrawing.Geometry = geometryGroup;
geometryDrawing.Brush = Brushes.DarkGreen;
geometryDrawing.Pen = new Pen(Brushes.Black, 0.005);
drawingGroup.Children.Add(geometryDrawing);
}
private void MarkerFun()
{
double x=0.1;
GeometryGroup geometryGroup = new GeometryGroup();
for (int i = 0; i < 2; i++)
{
FormattedText formattedText = new FormattedText(
( 1 - i ).ToString(),
CultureInfo.CurrentCulture ,
FlowDirection.LeftToRight,
new Typeface("Verdana"),
0.1,
Brushes.Black);
Geometry geometry = formattedText.BuildGeometry(new Point(0, i * 0.65));
geometryGroup.Children.Add(geometry);
}
int iter = 1;
for (int i = 0; i < Lenth; i++)
{
int temp = Convert.ToInt32(data[i]);
FormattedText formattedText = new FormattedText(
temp.ToString(),
CultureInfo.InvariantCulture,
FlowDirection.LeftToRight,
new Typeface("Verdana"),
0.1,
Brushes.Black);
formattedText.SetFontWeight(FontWeights.Bold);
Geometry geometry = formattedText.BuildGeometry(new Point(i*Jump+Jump, 0.80));
//geometryGroup.Children.Add(geometry);
iter++;
if (iter == 12)
{
iter = 1;
LineGeometry line = new LineGeometry(new Point(i * Jump + 0.3, 0), new Point(i * Jump + 0.3, 1));
geometryGroup.Children.Add(line);
}
LineGeometry lineS = new LineGeometry(new Point(x, 0.75), new Point(x, 0.85));
geometryGroup.Children.Add(lineS);
x+=Jump;
}
GeometryDrawing geometryDrawing = new GeometryDrawing();
geometryDrawing.Geometry = geometryGroup;
geometryDrawing.Brush = Brushes.DarkGreen;
geometryDrawing.Pen = new Pen(Brushes.DarkGreen, 0.005);
drawingGroup.Children.Add(geometryDrawing);
}
private void GrafFun()
{
double x = 0.1; double y = 0; double yy=0 ;
GeometryGroup gg = new GeometryGroup();
for(int i=0;i<Lenth;i++)
{
yy = y;
if (data[i] == true)
{ y=0.7;}
else
{y=0;}
if (yy != y)
{
LineGeometry lineV = new LineGeometry(new Point(x, yy), new Point(x, y));
gg.Children.Add(lineV);
}
LineGeometry lineH=new LineGeometry(new Point (x,y),new Point (x+Jump,y));
gg.Children.Add(lineH);
x += Jump;
}
GeometryDrawing gd=new GeometryDrawing();
gd.Geometry=gg;
gd.Pen = new Pen(Brushes.Red, 0.03);
drawingGroup.Children.Add(gd);
}
#endregion
private void scrollBar1_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
scrollBar1.Maximum = Lenth * 100 ;
scrollBar1.Minimum = 0;
image1.Margin = new Thickness(scrollBar1.Value*-1, 0, 0, 0);
}
private void Connect_Comms(object sender, RoutedEventArgs e)
{
try
{
if (Connect_btn.Content == "Підключитись")
{
//Sets up serial port
serial.PortName = Comm_Port_Names.Text;
serial.BaudRate = Convert.ToInt32(Baud_Rates.Text);
serial.Handshake = System.IO.Ports.Handshake.None;
serial.Parity = Parity.None;
serial.DataBits = 7;
serial.StopBits = StopBits.Two;
serial.ReadTimeout = 2000;
serial.WriteTimeout = 50;
serial.Open();
//Sets button State and Creates function call on data recieved
Connect_btn.Content = "Відключитись";
serial.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(Recieve);
}
else
{
try // just in case serial port is not open could also be acheved using if(serial.IsOpen)
{
serial.Close();
Connect_btn.Content = "Підключитись";
}
catch
{
}
}
}
catch
{
MessageBox.Show("Невдається підключитись до порта"+" "+Comm_Port_Names.Text);
}
}
#region приймання
private delegate void UpdateUiTextDelegate(string text);
private void Recieve(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
recieved_data = serial.ReadExisting();
Dispatcher.Invoke(DispatcherPriority.Send,
new UpdateUiTextDelegate(WriteData), recieved_data);
}
private void WriteData(string text)
{
para.Inlines.Add(text);
mcFlowDoc.Blocks.Add(para);
Commdata.Document = mcFlowDoc;
}
#endregion
#region передавання
private void Send_Data(object sender, RoutedEventArgs e)
{
SerialCmdSend(SerialData.Text);
SerialData.Text = "";
}
public void SerialCmdSend(string data)
{
if (serial.IsOpen)
{
try
{
// Send the binary data out the port
byte[] hexstring = Encoding.ASCII.GetBytes(data);
//There is a intermitant problem that I came across
//If I write more than one byte in succesion without a
//delay the PIC i'm communicating with will Crash
//I expect this id due to PC timing issues ad they are
//not directley connected to the COM port the solution
//Is a ver small 1 millisecound delay between chracters
foreach (byte hexval in hexstring)
{
byte[] _hexval = new byte[] { hexval }; // need to convert byte to byte[] to write
serial.Write(_hexval, 0, 1);
Thread.Sleep(1);
}
}
catch (Exception ex)
{
para.Inlines.Add("Failed to SEND" + data + "\n" + ex + "\n");
mcFlowDoc.Blocks.Add(para);
Commdata.Document = mcFlowDoc;
}
}
else
{
}
}
#endregion
private void button1_Click(object sender, RoutedEventArgs e)
{
drawingGroup = new DrawingGroup();
Execute();
image1.Source = new DrawingImage(drawingGroup);
}
void Word_To_Byte(string text)
{
int size = 0;
Byte[] hexstring = Encoding.ASCII.GetBytes(text);
foreach (Byte buff in hexstring)
{
size++;
}
size -= 2;
if(size>20)
{
data = new bool[size * 11];
Lenth=size*11;
}
for (int i = 0; i < size; i++)
{
BitArray bitArray = new BitArray(new byte[] { hexstring[i] });
data[i*11] = false;
int par = 0;
for (int j=0; j <8; j++)
{
if (bitArray[j] == true)
{
data[i * 11 + (7 - j)] = true;
par++;
}
else
data[i * 11 + (7 - j)] = false;
}
if(par%2!=0)
data[i*11+8]=true;
data[i*11+9]=false;
data[i * 11 + 10] = false;
}
}
private void Commdata_TextChanged(object sender, TextChangedEventArgs e)
{
int i = 0;
NullData();
Word_To_Byte(new TextRange(Commdata.Document.ContentStart, Commdata.Document.ContentEnd).Text);
drawingGroup = new DrawingGroup();
Execute();
AditionMarkerFun();
image1.Source = new DrawingImage(drawingGroup);
}
private void VolumeSlider_ValueChanged(object sender, System.Windows.RoutedPropertyChangedEventArgs<double> e)
{
VolumeSlider.Maximum = Lenth * 25 ;
VolumeSlider.Minimum = 0;
image1.Margin = new Thickness(VolumeSlider.Value*-1, 0, 0, 0);
}
private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
{
Commdata.Document=new FlowDocument();
drawingGroup = new DrawingGroup();
int i=0;
NullData();
Execute(); // Заполнение слоев
image1.Source = new DrawingImage(drawingGroup);
}
private void NullData()
{
for (int i = 0; i < data.Length; i++)
data[i] = true;
}
private void Comm_Port_Names_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
}
private void image1_ImageFailed(object sender, ExceptionRoutedEventArgs e)
{
}
private void Baud_Rates_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
}
}
}