Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
КП МПС Варианты.doc
Скачиваний:
79
Добавлен:
12.04.2015
Размер:
1.44 Mб
Скачать
      1. Сопряжение с последовательным асинхронным интерфейсом

Схема организации интерфейса RS-232C приведена на рис.5.20.

Контроллер последовательного асинхронного обмена (UART) входит в состав микроконтроллераMCS-51. Он имеет два вывода для организации последовательного обмена –TxD(передаваемые данные) иRxD(принимаемые данные). Контроллер осуществляет преобразование поступающих данных в последовательном коде в параллельный код и обратное преобразование при передаче. Для обеспечения необходимых электрических уровней интерфейсаRS232 (-3В…-12В для логической единицы и +3В…+12В для логического нуля) необходим преобразователь уровня (микросхема ADM202), в состав которого входят умножитель напряжения (с использованием внешних конденсаторов) и инвертор напряжения, что позволяет получить необходимые уровни при питании только от +5В.

Рис.5.20. Организация интерфейса RS232C для MCS-51

Процессор обменивается информацией с UARTчерез регистры данных по приему и передаче, имеющих одно имя SBUF. Регистры управления режимом работы последовательного порта (SMOD, SCON,TMOD) задают скорость и формат обмена по порту.

Обмен по последовательному асинхронному каналу (UART) может быть осуществлен или опросом флагов прерывания с последующим переходом к процедуре обмена, или автоматическим переходом на подпрограмму обработки при возникновении прерывания. Используя систему прерываний, легко выделить процедуру приема передачи в отдельную задачу. Установив прерыванию последовательного порта определенный приоритет, можно осуществлять переключение задач в простых программах без использования операционной системы. На рис.5.21представлена диаграмма задач при обработке прерываний от встроенного контроллера последовательного обмена (UART) с передачей данных в пользовательский процесс. Обработчик прерываний от последовательного порта представляет собой отдельную задачу, запускаемую асинхронно (по приходу прерывания) от пользовательского процесса.

Рис.5.21. Часть диаграммы задач работы с последовательным портом

Взаимодействие между задачами должно осуществляться посредством вызова функции.

Часть диаграммы задач со схемой взаимодействия при обмене информацией через UART приведена на рис.5.22.

Программное обеспечение при работе с UARTсостоит из обработчика прерывания от последовательного канала, циклических буферов чтения и записи, функций чтения байта из последовательного канала и записи байта в последовательный канал.

Взаимодействие обработчика и функций чтения/записи осуществляется только через буфер. Обработчик взаимодействует с последовательным каналом напрямую. Если прерывание вызвано приходом байта по последовательному каналу, то обработчик записывает байт в буфер чтения RFIFO. Если прерывание вызвано окончанием передачи, то обработчик проверяет состояние буфера записи WFIFO, и, если он не пуст, считывает и пересылает следующий байт.

Рис.5.22. Диаграмма задач со схемой их взаимодействия

Функция чтения байта ReadUART() проверяет состояние буфера RFIFO, и если он не пуст, считывает из него байт. Функция WriteUART() записывает байт в буфер записи последовательного канала WFIFO. Если до записи буфер был пуст, необходимо аппаратно вызвать обработчик прерывания, чтобы инициировать передачу данных.

Граф состояний задачи обработчика прерываний отUARTпредставлен на рис.5.23.

На рисунке введены следующие обозначения:

Q1– состояние инициализации контроллераUART;

Q2– состояние ожидания прерывания по приему или передаче;

Q3– состояние приема байта отUARTи запись в приемный буфер;

Q4– состояние пересылки байта вUARTиз передающего буфера;

RI,TI– входные сигналы – флаги прерывания, соответственно приемника и передатчикаUART.

Описание графа состояний для задачи драйвера обмена по UART.

В состоянии Q2драйвер ожидает установление флага RI или TI. При установке флага RI осуществляется переход в состояниеQ3, а при установке флага TI – в состояниеQ4.

В состоянии Q3производится считывание принятого байта из приемного регистра SBUF и пересылка его в буфер, доступный по чтению для задачи обработки информации. После этого осуществляется возврат в состояниеQ2.

Рис.5.23. Граф состояний для задачи обработчика прерываний от UART

В состоянии Q4производится пересылка байта в передающий регистр SBUF из буфера, доступного по записи для задачи обработки информации. После этого осуществляется возврат в состояниеQ2.

При использовании прерывания состояние Q2будет представлять собой лишь проверку причины прерывания для осуществления перехода к следующему состоянию. Переход из состоянийQ3иQ4будет представлять собой выход из прерывания.

Ниже приведена программа драйвера обмена по последовательному порту. В подпрограмме прерывания вызываются функции обработки принятого байта или передачи байта в приемопередатчик. Для независимого написания этих функций в подпрограмму прерывания передаются указатели на функции, которые не имеют параметров и возвращают тип void. Данные функции описываются в другом модуле.

/* модуль приема/передачи байт по последовательному порту*/

#include <io51.h>

#define SysFreq 11059200 /* частота генератора контроллера*/

#define F9600bod 256-SysFreq/12/16/2/9600 /* константа, загружаемая в таймер и

определяющая скорость передачи

по последовательному порту - 9600 бит/с */

extern char Rx232Flag; /* признак наличия данных в приемном буфере*/

void (*Tx232Func)(void), (*Rx232Func)(void); /* описание указателей на функции */

char Rx232Byte; /* приемный канал: байт данных */

char Tx232Byte, RS232TxFlag; /* передающий канал: байт данных и признак*/

/* состояние Q1 процедура инициализации */

void RS232Init(void (*Rx)(void), void (*Tx)(void)) )) /* в функцию, в качестве

параметров, передаются указатели на функции Rx и Tx */

{

Tx232Func = Tx; Rx232Func = Rx; /* привязка указателей к функциям пользователя*/

Rx232Flag = Tx232Flag = 0; /*обнуление признаков*/

TMOD = 0x20; /* Timer 1 – режим mode 2 */

TR1 = 1; /* Разрешение работы таймера 1 */

SCON = 0x60; /* формат посылки UART – 8-bit */

TH1 = TL1 = F9600bod; /* 9600 бит/с на частоте 11.059 MHz */

REN = 1; /* Разрешение приема по UART */

ES = 1; /* Разрешение прерывания от UART */

}

/* Процедура приема/передачи байта – вектор прерывания UART */

interrupt [0x23] void SCON_int(void)

{

/* состояние Q2 */

if (RI) /* если установлен флаг прерывания по приему байта, */

{

/* состояние Q3 */

Rx232Byte = SBUF; /*то прочитать принятый байт */

(*Rx232Func)(); /* вызов функции обработки принятого байта */

RI=0; /* Сбросить флаг прерывания приемника */

}

if (TI) /* если установлен флаг прерывания по передаче байта, то передать байт */

{

/* состояние Q4 */

TI=0; /* Сбросить флаг прерывания передатчика*/

(*Tx232Func)(); /* вызов функции передачи байта */

}

}

/* процедура чтения принятого байта */

void RS232Read(char *c) /* Чтение принятого байта RS232 */

{

c = Rx232Byte; /* запись принятого байта в *c */

}

/* процедура записи байта в передающий регистр UART */

void RS232Write(char c) /* выдача байта в передатчик*/

{

while (!TI); /* Ожидание конца передачи */

SBUF = c; /* выдача байта на передачу*/

}

Флаги RI и TI могут быть сброшены только программным путем, обычно в пределах подпрограммы прерывания, где необходимо также определить, какому из флагов - RI или TI - соответствует прерывание. Для управления работой системы прерывания микроконтроллер имеет биты разрешения индивидуального прерывания (для UART это бит ES) и бит ЕА – общего разрешения прерывания. Вектор прерывания (адрес подпрограммы) последовательного порта равен 0023h.

Процедура инициализации

void RS232Init(void (*Rx)(void), void (*Tx)(void)) ))

задает скорость обмена по последовательному порту и устанавливает соответствие между указателями и конкретными функциями пользователя - *Rx,*Tx.

Процедура приема/передачи байта организованна в виде функции обработки прерывания. При приеме байта вызывается функция пользователя через указатель на нее (*Rx232Func)().При передаче байта вызывается функция пользователя через указатель на нее(*Тx232Func)().

Процедура чтения байта

RS232Read(char *c),

возвращает его через указатель *с.

Процедура выдачи байта

RS232Write (char c),

принимает его через параметр с.

Задача обмена информацией по последовательному порту (путем вызова функции *KEYFunc)() ) должна содержать следующие процедуры:

  • вызов процедуры инициализации с указателем на функции записи в приемный буфер и чтения из передающего буфера –

RS232Init(RS232Receiver, RS232Transmitter);

  • записи байта в приемный буфер

void RS232Receiver(void);

  • чтения байта из передающего буфера

void RS232Transmitter(void);

  • процедуру обработки принимаемых/передаваемых данных;

  • анализ признаков наличия данных в буферах.

Процедура записи байта в приемный буфер вызывается из подпрограммы прерывания через указатель на функцию. Она осуществляет вызов функции чтения байта RS232Read (&BufR[bHPtr]), запись его в приемный буфер и устанавливает признак наличия данных в буфере.

Процедура чтения из передающего буфера вызывается из подпрограммы прерывания через указатель на функцию. Она осуществляет чтение очередного байта из передающего буфера и вызов функции выдачи байта на передачу RS232Write(Buffer[Namb++]), если буфер не пуст.

Процедура обработки принимаемых/передаваемых данных должна включать:

- процедуру чтения байт из приемного буфера, аналогичную процедуре чтения кодов нажатых клавиш из буфера;

- процедуру обработки полученных данных в соответствии с требуемым алгоритмом;

- процедуру записи данных в передающий буфер, которая анализирует текущий адрес в буфере пересылаемых байт с целью ожидания окончании пересылки, затем устанавливает начальный адрес в 0, записывает новые данные в буфер, с указанием их максимального числа.

/* процедуры записи данных в приемный буфер и выборки из передающего буфера*/

extern void RS232Read (char *Val);

extern void RS232 Write (charVal);

extern char Tx232Flag; /* признак наличия данных в передающем буфере*/

extern char MAX, Namb, Buffer[MAX]; /*передающий буфер – макс. размер и

текущий номер байта*/

char bHPtr, bTPtr, BUFSize = 20; /* bTPtr - текущий адрес хвоста (адрес самого старого

невыбранного байта из буфера);

bHPtr - текущий адрес головы (адрес

последнего записанного байта в буфер);

BUFSize - размер буфера*/

char Ptr, BufR [BUFSize]; /*адрес элемента передающего буфера, приемный буфер*/

char Rx232Flag, ; /* признак наличия данных в приемном буфере*/

RS232Init(RS232Receiver, RS232Transmitter); /* инициализация UART с указанием

функций чтения и записи данных

в приемный и передающий буферы*/

/* Функция записи кода в приемный буфер и установка признака приема*/

void RS232Receiver(void)

{ char i;

if (bHPtr = =BUFSize-1) i =0; /*Дошли до конца буфера?*/

/* Да, установить адрес на начало буфера */

else i =bHPtr+1; /*Нет, увеличить адрес в буфере*/

if (i != bTPtr) /* Нет переполнения буфера?

(адрес для записи не равен адресу по чтению из буфера?) */

{

RS232Read (&BufR[bHPtr]); /* Запишем в буфер байт по адресу записи */

bHPtr = i; /* Установим новый адрес для записи следующего байта */

Rx232Flag =1; /* Установим признак наличия данных в буфере */

}

}

/*Функция выборки байта из выходного буфера и передача */

void RS232Transmitter(void)

{

if (MAX-Namb) RS232Write(Buffer[Namb++]); /* выдача байта в передатчик*/

}

В [70] приведены программа для микроконтроллера AVR и разработка программы для компьютера, связь между которыми выполнена по каналу RS-232. Программное обеспечение для компьютера выполнено в среде разработки Borland Delphi.