; *****************
* ФУНКЦИЯ: Передает 8-битное значение по асинхронному каналу *
* РЕСУРСЫ: Модуль USART *
* ВХОД: 8-битное значение в DATA_OUT *
* ВЫХОД: Содержимое DATA_OUT не изменяется, байт передан *
; ******************
PUTCHAR btfss PIR1,TXIF;Проверим, полон ли буфер передатчика?
goto PUTCHAR;ЕСЛИ нет, ТО проверим снова
movf DATA_OUT,w;ИНАЧЕ считываем значение
movwf TXREG;и копируем его в регистр передатчика
return
; ******************
; * ФУНКЦИЯ: Принимает 8-битное значение по асинхронному каналу *
; * РЕСУРСЫ: Модуль USART *
; * ВХОД: Нет *
; * ВЫХОД: Принятый байт — в DATA_IN. *
; * ВЫХОД: ERR = 00, если не было ошибок. При ошибке *
; * кадрирования ERR = -1, при переполнении ERR = -2, *
; * при наличии обеих ошибок ERR = -3 *
; *******************
GETCHAR clrf ERR; Обнуляем признак ошибки
btfss PIR1,RCIF; Проверим, есть ли символ?
goto GETCHAR; ЕСЛИ нет, ТО проверим снова
; Обработка ошибок
btfss RCSTA,FERR; Была ошибка кадрирования?
goto CHECK_OERR; ЕСЛИ нет, ТО проверим на переполнение
movlw -1; ИНАЧЕ фиксируем ошибку
CHECK_OERR
btfss RCSTA,OERR; Было переполнение?
goco GET_EXIT; ЕСЛИ нет, TO завершаем обработку ошибок
decf ERR,f; Иначе фиксируем ошибку
decf ERR,f
bcf RCSTA,CREN; и сбрасываем логику приемника
bcf RCSTA,CREN
GET_EXIT
movf RCREG,w; Читаем байт данных
movwf DATA_IN; и помещаем во временный регистр
return
end
В некоторых системах нельзя позволить процессору тратить машинное время на ожидание символа, который придет неизвестно когда. Специально для таких случаев можно было бы написать альтернативную подпрограмму приема, назвав ее, скажем, getch. Эта подпрограмма будет возвращать ERR = +1 при отсутствии данных в буфере. И все же наилучшим выходом из ситуации будет генерация прерывания при обнаружении входящего символа, а не простой опрос флага этого прерывания.
В языке Си каналы асинхронного обмена могут использоваться в качестве стандартных потоков ввода/вывода. Что же касается конкретно компилятора CCS, то в нем имеется директива #use rs232 (), посредством которой можно сообщить компилятору, какие выводы будут использоваться для приема и передачи данных, а также какой должна быть скорость обмена. Стандартные Си-функции ввода/вывода, такие как printf (), используют эти выводы для связи со стандартным каналом. С помощью данного компилятора можно реализовать множество не связанных между собой асинхронных каналов.
В качестве примера, в Программе 12.16 приведена реализация на языке Си асинхронной дуплексной связи с терминалом (см. Рис. 12.25), работающим на скорости 9600 бод. К выводу RB0 подключена кнопка, и, когда оператор посылает микроконтроллеру символ ‘G’, тот начинает опрашивать состояние этой кнопки. При ее замыкании (появлении на выводе сигнала НИЗКОГО уровня) терминал извещает оператора строкой «Кнопка 1 замкнута». Для ввода и вывода данных воспользуемся стандартными функциями printf () >) и getch () >).