; **************
; * ФУНКЦИЯ: Передает 8-битное значение в асинхронном режиме *
; * ФУНКЦИЯ: Скорость передачи: 1200…9600 для XTAL 1…20 МГц *
; * РЕСУРСЫ: Макрокоманда BAUD_DELAY, формирующая задержку 0.5 битового интервала; COUNT *
; * ВХОД: 8-битное слово данных в DATA_OUT, предопределенные константы XTAL и BAUD *
; * ВЫХОД: Содержимое DATA_OUT обнуляется, байт передан *
; **************
PUTCHAR movlw 8; Восемь битов данных
movwf COUNT
bcf PORTA,ТХ; Старт-бит
Baud_delay; Задержка 2x0.5 бита
Baud_delay
; Теперь выдвигаем байт данных, начиная с младшего бита
PUTCHAR_LOOP rrf DATA_OUT,f; Сдвигаем вправо через перенос
btfss STATUS,С; Проверяем флаг переноса
goto ITS_A_0; ЕСЛИ 0, ТО передаем 0
bsf PORTA,TX; ИНАЧЕ передаем 1
goto PUTCHAR_NEXT; и продолжаем
ITS_A_0 bcf PORTA,TX; Выдаем 0
PUTCHAR_NEXT
Baud_delay; Задержка на 1 бит
Baud_delay
decfsz COUNT,f; Повторяем восемь раз
goto PUTCHAR_LOOP
bsf PORTA,ТХ; Стоп-бит
Baud_delay
Baud_delay
return
; **************
; * ФУНКЦИЯ: Принимает 8-битное значение в асинхронном режиме *
; * : Скорость передачи: 1200…9600 для XTAL 1…20 МГц *
; * РЕСУРСЫ: Макрокоманда BAUD_DELAY, формирующая задержку 0.5 битового интервала; COUNT *
; * ВЫХОД: Принят байт в DATA_IN *
; * ВЫХОД: Если нет ошибки кадрирования, ERR = 0, ИНАЧЕ ERR = -1*
; **************
GETCHAR movlw 8; Восемь битов данных
movwf COUNT
clrf ERR; Обнуляем байт признака ошибки
GETC HAR_START
btfsc PORTA,RX; Ожидаем появления 0
goto GETCHAR_START
Baud_delay; Ждем в течение 0.5 бита
btfsc PORTA,RX; Все еще 0?
goto GETCHAR_START
Baud_delay; ЕСЛИ да, TO ждем в течение 1 бита
Baud_delay
GETCHAR_LOOP bcf STATUS,С;Сбрасываем флаг переноса
rrf DATA_IN,f; Вдвиг аем 0 в байт данных
btfsc PORTA,RX; На входе ВЫСОКИЙ уровень?
bsf DATA_IN,7; ЕСЛИ да, ТО устанавливаем бит
Baud_delay
Baud_delay
decfsz COUNT,f; Повторяем восемь раз
goto GETCHAR_LOOP
btfss PORTA,RX; Проверяем приход стоп-бита (1)
decf ERR,f; ЕСЛИ 0, ТО сообщаем об ошибке
return
Подпрограмма приема GETCHAR более сложна. Появление на выводе RX НИЗКОГО уровня расценивается как приход старт-бита. Однако если осуществлять выборку значений последующего потока данных с периодичностью, равной длительности битового интервала (два включения макроса Baud_delay), то, поскольку этот момент может соответствовать моменту окончания битового интервала, уход любой из двух частот может привести к появлению ошибок. Чтобы избежать этого, состояние вывода RX считывается повторно после задержки, равной половине битового интервала, чтобы еще раз убедиться в наличии старт-бита. Если это окажется так, то последующие выборки осуществляются с периодом, равным двум битовым интервалам. При этом моменты выборок будут приходиться примерно на середину интервала. Лучших результатов можно достичь, считывая состояние вывода с большей частотой (передискретизация) и принимая мажоритарное решение на основании считанных значений.