Прием и передача данных через UART
Перед работой с UART его следует установить в нужный режим, а также задать скорость обмена. Делается это, например, таким образом:
;для семейства Classic при частоте 4 МГц
ldi temp,25 ;скорость передачи 9600 при 4 МГц
out UBRR,temp ;устанавливаем
ldi temp, (1<<<<<���ТХВ8)
out UCR,temp ;разрешение приема/передачи 8 бит
Число BAUD для делителя частоты (в данном случае 25) можно определить из таблиц, которые имеются в каждом описании соответствующего контроллера (там же приводится и ошибка для выбранного значения частоты), или рассчитать по формуле: BAUD = f peз/16(UBRR+1). Для семейства Mega процедура несколько усложняется, потому что регистров в USART больше:
;для семейства Меда при частоте 16 МГц
ldi temp,103 ;9600 при 16 МГц
out UBRRL,temp
ldi temp,(1<< ;разрешение приема/передачи
out UCSRB,temp
ldi temp,(1<< ;формат 8n1
out UCSRC,temp
Чем выше тактовая частота МК /рез, тем точнее может быть установлена скорость. При частоте кварца 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 с ожиданием готовности
Читать дальше
Конец ознакомительного отрывка
Купить книгу