МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ
НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ “ЛЬВІВСЬКА ПОЛІТЕХНІКА”
Кафедра ЕОМ
Звіт
до лабораторної роботи №1
з предмету: Периферійні пристрої
тема: Емулювання роботи RS-232.
Мета роботи: Створити программу, що емулює роботу RS-232.
Теоретичні відомості
В більшості схем, що містять інтерфейс RS-232С. дані перелаються асинхронно, тобто у вигляді послідовності пакету даних. Кожний пакет містить один символ коду АSСII, причому інформація в пакеті достатня для його декодування без окремого сигналу синхронізації.
Символи коду АSСII представляються сьома бітами, наприклад буква А має код 1000001. Щоб передати букву А по інтерфейсу RS-232С, необхідно ввести додаткові біти, що позначають початок і кінець пакету. Крім того, бажано добавити зайвий біт для простого контролю помилок по паритету (парності).
Найбільш широко поширений формат, що включає один стартовий біт. один біт паритет) і два степових біта. Початок пакету даних завжди відзначає низький рівень стартового біта. Після нього слідує 7 біт даних символа коду АSСII. Біт парності містить 1 або 0 так, щоб загальне число одиниць в 8-бітной групі було непарним. Останнім передаються два стопових біта, представлених високим рівнем напруги. Еквівалентний ТТЛ-сигнал при передачі букви А показаний на мал. 2.
Мал. 2. Представлення коду букви А сигнальними рівнями ТТЛ.
Таким чином, повне асихронно передаване слово складається з 11 біт (фактично дані містять тільки 7 біт) і записується у вигляді 01000001011.
Використовувані в інтерфейсі RS-232С рівні сигналів відрізняються від рівнів сигналів, діючих в комп'ютері. Логічний 0 (Space) представляється позитивною напругою в діапазоні від +3 до +25 В, логічна 1 (Mark) — негативною напругою в діапазоні від -3 до -25 В. На мал. З показаний сигнал в тому вигляді, в якому він існує на лініях TXD і RXD інтерфейсу RS-232С.
Мал. 3. Вид коду букви А на сигнальних лініях TXD і RXD
Зсув рівня, тобто перетворення ТТЛ-уровней в рівні інтерфейсу RS-232С і навпаки проводиться спеціальними мікросхемами драйвера лінії і приймача лінії.
Текст програми
//-------------- CGenerator ------------------
class CGenerator {
private:
int difer;
bool front; // current front value;
bool change; // 0 -> 1 && 1 -> 0
int count_limit; // limit value of signals before "1" standing
int count; // current value of signals before "1" standing
int i,j;
public:
CGenerator(int step_for_count) : count(0), front(true), difer(0) {
count_limit = step_for_count;
i=0; j=0;
}
void process(CPaintDC *, int);
int get_count() { return count; }
bool get_front() { return front; }
bool get_change() { return change; }
int get_difer() { return difer; }
};
inline void CGenerator::process(CPaintDC *dc, int xxx)
{
i++; j++;
change = false;
difer = 0;
if (i > count_limit) {
front = !front;
if (front) difer = 1;
i = 0;
if (front == true) count++;
change = true;
}
if (get_change() == true) {
if (get_front() == true) {
dc->MoveTo(10+j, xxx);
dc->LineTo(10+j, xxx+9);
}
else {
dc->MoveTo(10+j, xxx+8);
dc->LineTo(10+j, xxx-1);
}
}
if (get_front() == true) {
dc->SetPixel(10+j, xxx, 0x5555);
}
else dc->SetPixel(10+j, xxx+8, 0x5555);
}
// ------------------ CLine ---------------------
class CLine {
private:
CString value;
public:
CLine(CString sss) : value(sss) {}
CString get_value() { return value; }
};
// ---------------- CTransmiter -----------------
class CTransmitter {
private:
CString value;
bool bit;
bool value_bit;
int i, j, count, zatrumka, x, y, flag, k, size, current;
char symb;
int sqr(int f);
public:
CTransmitter(CLine *line) {
i = j = count = zatrumka = x = y = flag = k = current = 0;
y=8;
bit = false;
value_bit = false;
value = line->get_value();
size = value.GetLength();
}
bool stop_bit();
bool next_bit();
bool get_data() { return value_bit; }
bool get_count() { return count; }
void process(CPaintDC *, int, int, int, CGenerator);
};
inline bool CTransmitter::stop_bit()
{
if (current == (size*8)) return true;
else return false;
}
inline int CTransmitter::sqr(int f)
{
int s=1;
if (f==0) return s;
for(int i=0; i<f; i++)
s*=2;
return s;
}
inline bool CTransmitter::next_bit()
{
if (j==8) { i++; j=0; }
if ((i < value.GetLength()) && (j < 8)) {
symb = value[i];
j++;
current++;
return symb & sqr(8-j);
}
else return false;
}
inline void CTransmitter::process(CPaintDC *dc, int xxx, int cnt1, int cnt2, CGenerator gen)
{
dc->SetPixel(10+x++, xxx-y+8, 0x5555);
char s1[3];
if ((gen.get_front()) && (count == cnt1)) {
zatrumka++;
if (zatrumka >= (cnt2/3)) {
value_bit = next_bit();
wsprintf(s1,"%d",value_bit);
dc->TextOut(2+k, 180, s1);
k+=10;
count = 0;
if (value_bit) {
y=8;
if (!flag) {
dc->MoveTo(10+x, xxx-y+16);
dc->LineTo(10+x, xxx-y+8);
flag = 1;
}
}
else {
y=0;
if (flag) {
dc->MoveTo(10+x-1, xxx-y+8);
dc->LineTo(10+x-1, xxx-y);
flag = 0;
}
}
zatrumka = 0;
}
}
//fprintf(fp,"f = %d d = %d count = %d\n",gen.get_front(), gen.get_difer(),value_bit);
if (gen.get_difer() == 1) count++;
}
// ---------------- TReceiver -----------------
class CReceiver {
private:
char value[10];
bool bit;
int x, int y, count, i, j, k, zatrumka, flag;
int sqr(int f);
unsigned char symb;
FILE *fp;
public:
CReceiver() : x(0), y(8), count(0), i(0), j(7), k(0), zatrumka(0), flag(false) {
fp = fopen("1.txt","w");
}
~CReceiver() { fclose(fp); }
void set_bit(bool);
void precess(CPaintDC *, int, CTransmitter, CGenerator, CGenerator, int, int);
};
inline int CReceiver::sqr(int f)
{
int s=1;
if (f==0) return s;
for(int i=0; i<f; i++)
s*=2;
return s;
}
inline void CReceiver::set_bit(bool bit)
{
if (bit) symb &= sqr(j);
j--;
if (j==0) {
value[i++] = symb;
j=7;
}
}
inline void CReceiver::precess(CPaintDC *dc, int xxx, CTransmitter tx, CGenerator xx, CGenerator rx, int cnt1, int cnt2)
{
dc->SetPixel(10+x++, xxx-y+8, 0x5555);
char s1[3];
if (rx.get_difer()) {
if (tx.get_data()) y=8;
else y=0;
if (count >= cnt1) {
set_bit(tx.get_data());
fprintf(fp,"%d", tx.get_data());
count=0;
wsprintf(s1,"%d",tx.get_data());
dc->TextOut(2+k,200,s1);
k+=10;
}
if (tx.get_data()) {
y=8;
if (!flag) {
dc->MoveTo(10+x, xxx-y+16);
dc->LineTo(10+x, xxx-y+8);
flag = 1;
}
}
else {
y=0;
if (flag) {
dc->MoveTo(10+x-1, xxx-y+8);
dc->LineTo(10+x-1, xxx-y);
flag = 0;
}
}
}
if (xx.get_difer())
count++;
}
Результати виконання програми
Висновок: в даній лабораторній роботі я ознайомилася з роботою RS-232.