Чем выше тактовая частота МК /рез, тем точнее может быть установлена скорость. При частоте кварца 4 МГц мы с приемлемой точностью можем получить скорости обмена не более 28 800 бод. Правда, при выборе специального кварца (например, 3,6864 МГц) можно получить с нулевой ошибкой весь набор скоростей вплоть до 115 200, но зато для других целей такие частоты неудобны. Для получения скоростей передачи выше указанных (стандартно COM-порт позволяет установить скорости, как указано ранее до 256 кбод) придется увеличивать частоту. Так, при кварце 8 МГц и общем коэффициенте деления, равном единице, мы получим скорость 250 000, что отличается от стандартных 256 000 на приемлемые 2,4 %.

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

С UART связаны прерывания, причем в силу важности предмета тут их аж целых три: «передача завершена» (ТХ Complete), «регистр передатчика пуст» (ТХ UDR Empty) и «прием завершен» (RX Complete). Для их использования можно поступить следующим образом (примеры приведены для семейства Classic). Сначала вы инициализируете прерывание «прием закончен» (для чего надо установить бит RXCIE в регистре UCR). Возникновение этого прерывания означает, что в регистре данных udr имеется принятый байт. Процедуру обработки этого прерывания иллюстрирует листинг 16.1.

Листинг 16.1

UART_RXC:

    in temp,UDR  ;принятый байт — в переменной temp

     cbi UCR,RXCIE  ;запрещаем прерывание «прием закончен»

             <анализируем команду, если это не та команда — опять разрешаем прерывание «прием закончен» и выходим из процедуры

      sbi UCR,RXCIE

      reti

             В противном случае готовим данные, самый первый посылаемый байт должен быть в переменной temp>

      sbi UCR,UDRIE  ;разрешение прерывания «регистр данных пуст»

reti

Далее у нас почти немедленно возникает прерывание «регистр данных пуст». Обработчик этого прерывания состоит в том, что мы посылаем байт, содержащийся в переменной temp, и готовим данные для следующей посылки (листинг 16.2).

Листинг 16.2

UART_DRE:

    out UDR,temp  ;посылаем байт

    cbi UCR,UDRIE  ;запрещаем прерывание «регистр данных пуст»

          <готовим данные, следующий байт — в temp. Если же был отправлен последний нужный байт, то опять разрешаем прерывание «прием закончен» и далее выходим из процедуры, иначе выполняем следующий оператор:>

    sbi UCR,UDRIE  ;разрешаем прерывание «регистр данных пуст»

reti

Для семейства Mega (USART) вместо UCR в текст примеров надо подставить UCSRB. Обратим внимание на то, что после обработки первого прерывания переменная temp здесь может содержать подготовленный для отправки байт, и не должна в промежутках между прерываниями использоваться еще где-то. В противном случае ее надо сохранять, например, в стеке, или все же отвести для этого дела специальный регистр. Как видите, все довольно сложно.

Однако, как и в случае записи в EEPROM (см. главу 15), поскольку эти события (прием и передача) происходят относительно редко, на практике мы не будем использовать прерывания, и процедуры резко упростятся (на примере USART — листинг 16.3).

Листинг 16.3

Out_com:  ;посылка байта из temp с ожиданием готовности

           sbis UCSRA,UDRE  ;ждем готовности буфера передатчика

           rjmp out_com

           out UDR,temp  ;собственно посылка байта

ret  ;возврат из процедуры Out_com

In_com:  ;прием байта в temp с ожиданием готовности

           sbis UCSRA,RXC  ;ждем готовности буфера приемника

           rjmp in_com

           in temp,UDR  ;собственно прием байта

ret  ;возврат из процедуры In_com

Для семейства Classic надо заменить все UCSRA на USR. Для сформулированной ранее задачи непрерывного ожидания внешних команд обращение к процедуре In_com при этом вставляется в пустой цикл в конце программы:

Перейти на страницу:

Поиск

Похожие книги