Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
686.docx
Скачиваний:
85
Добавлен:
24.04.2019
Размер:
6.68 Mб
Скачать

6.3 Программирование последовательного канала

Простейшим из способов организации последовательного обмена является

асинхронный обмен с программной проверкой готовности. Примером такого

обмена может служить работа с контроллером последовательного канала

(UART) МК ADuC812 в стенде SDK-1.1 «по опросу» (см. раздел 2.2.9.1). Если

требуется переслать байт, то: 1) сбрасывается TI; 2) в SBUF записывается

нужный байт данных; и 3) ожидается, пока TI не будет установлен

контроллером. С приемом здесь сложнее: нужно постоянно проверять флаг RI

и, если он установлен, то читать принятый байт из SBUF и сбрасывать RI.

Такой способ удобен, когда разработчику четко известно, когда произойдет

прием данных и когда его завершать. Неудобен он тем, что время выполнения

самой программы напрямую зависит от скорости обмена. В самом деле, чем

медленнее скорость, тем дольше по времени цикл ожидания готовности к

приему/посылке следующего байта.

Пример программы:

/*--------------------------------------------------------------------

init_sio

----------------------------------------------------------------------

Инициализирует последовательный канал на заданной скорости.

Вход: char speed - скорость. Задается константами, описанными в

заголовочном файле sio.h

bit sdouble - дублирование скорости: 0 - не дублировать скорость,

заданную аргументом speed; 1 - дублировать.

Выход: нет

Результат: нет

------------------------------------------------------------------- */

void init_sio( unsigned char speed )

{

TH1 = speed;

TMOD |= 0x20; //Таймер 1 будет работать в режиме autoreload

TCON |= 0x40; //Запуск таймера 1

SCON = 0x50; //Настройки последовательного канала

ES = 0; //Запрещение прерываний от приемопередатчика

}

/*--------------------------------------------------------------------

RSioStat

----------------------------------------------------------------------

Возвращает ненулевое значение, если буфер приема не пуст

Вход: нет

Выход: нет

Результат: 0 - буфер приема пуст,

1 - был принят символ

------------------------------------------------------------------- */

unsigned char rsiostat(void)

249

{

}

return RI;

/*--------------------------------------------------------------------

wsio

----------------------------------------------------------------------

Отправляет символ по последовательному каналу

Вход: unsigned char c - символ, который нужно отправить

Выход: нет

Результат: нет

------------------------------------------------------------------- */

void wsio( unsigned char c )

{

SBUF = c;

TI = 0;

while( !TI );

}

/*--------------------------------------------------------------------

rsio

----------------------------------------------------------------------

Дожидается приема символа из последовательного канала и возвращает его.

Вход: нет

Выход: нет

Результат: принятый символ

------------------------------------------------------------------- */

unsigned char rsio(void)

{

while( !RI );

RI = 0;

return SBUF;

}

/*--------------------------------------------------------------------

type

----------------------------------------------------------------------

Выводит ASCIIZ-строку в последовательный канал

Вход: char *str - указатель на строку

Выход: нет

Результат: нет

------------------------------------------------------------------- */

void type(char * str)

{

while( *str ) wsio( *str++ );

}

/*--------------------------------------------------------------------

main

--------------------------------------------------------------------*/

void main( void )

{

unsigned char c;

init_sio( S9600 );

type("Тест драйвера SIO для стенда SDK-1.1\r\n");

type("Нажимайте кноки для тестирования... \r\n");

while( 1 )

250

{

if( rsiostat() )

{

c = rsio();

switch( c

{

case '1':

case '2':

case '3':

)

type("\r\ntest 1\r\n"); break;

type("\r\ntest 2\r\n"); break;

type("\r\ntest 3\r\n"); break;

}

}

}

default: wsio( c );

}

break;

При организации асинхронного обмена по прерыванию при приеме байта с

линии происходит прерывание и передача управления соответствующей

программе-обработчику, который читает принятый байт из порта данных

контроллера UART и, к примеру, помещает его в специальный буфер-очередь

принятых байт, доступный прерванной программе (см. раздел А.2.4). По

завершении процедуры обработки прерывания управление передается в

прерванную программу, которая при желании (в любом удобном месте

алгоритма) может забрать принятый байт. С другой стороны, при завершении

отправки контроллером очередного байта также происходит прерывание,

сигнализирующее о том, что байт послан и в буфер UART можно поместить

новые данные. Обработчик прерывания, при наличии данных в исходящей

очереди, записывает очередной байт в порт данных контроллера и запускает

посылку. Основная же программа может, не заботясь о готовности или

неготовности контроллера принять очередной байт, может спокойно помещать

данные в исходящий буфер, а всю работу с устройством выполнит обработчик

прерываний, когда оно (устройство) будет готово.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]