Вы находитесь на странице: 1из 12

6/2/4. Работа приемника USART.

“Въезд” в процедуру бмена данными между


ПИКом и компьютером (двунаправленная работа) с помощью учебного
устройства (“made in СССР”).

Работа приемника USART в асинхронном режиме (8-битный прием).

Основа приемника USART - тот же, что и в передатчике USART, сдвиговый регистр,
но работающий, как бы, наоборот (см. рис. 12-7 на странице 76 даташита PIC16F628A).
В передатчике USART, данные в сдвиговый регистр (TSR) вводятся в параллельной
форме, а выводятся в последовательной форме, а в приемнике USART все наоборот:
данные в сдвиговый регистр (RSR) вводятся в последовательной форме (побитно), а
выводятся в параллельной форме (побайтно).
Картинками, поясняющими принцип последовательного считывания уровней битов
принятого байта данных, могут служить картинки рисунков 2 и 3 подраздела 6/2/1,
плюс, сопровождающая их информация.
Байт данных вводится в сдвиговый регистр, начиная с бита №0 и заканчивая битом
№7.
Такт для сдвигового регистра приемника USART вырабатывается генератором скорости
обмена.
Генератор скорости обмена работает всегда (за исключением SLEEP), поэтому, если не
предпринять “шлагбаумных” мер, то регистр RSR будет непрерывно “выдавать на гора”
“кучу” байтов, которые не будут являться принятыми байтами данных.
Роль этого “шлагбаума” выполняет устройство поиска стартового бита, работающего по
принципу поиска нулевого уровня.
Пока на приемной (относительно ПИКа) линии будет выставлен уровень единицы
(уровень стопа), устройство поиска стартового бита блокирует как такт сдвигового
регистра, так и выборки.
По этой причине, “жизнь” в сдвиговом регистре, а значит и в приемнике USART,
“замирает” (сдвигов и выборок не присходит).
Это состояние приемника USART соответствует режиму ожидания поступления, на его
вход, байта данных.
При обнаружении устройством поиска стартового бита, на приемной линии, уровня
нуля, сдвиги и выборки разрешаются.
Начинается последовательное, побитное заполнение ячеек сдвигового регистра RSR
битами принимаемого байта данных.
“Механизм” этой “свистопляски” такой:
1. Cначала производится выборка.
2. Результат выборки записывается в ячейку самого старшего разряда сдвигового
регистра.
3. Далее, производится сдвиг содержимого сдвигового регистра на одну позицию
вправо.
Далее, производится следующая выборка и т.д., до тех пор, пока не произойдет
последняя выборка (в пределах одного принимаемого байта данных).
После ее осуществления, принимаемый байт данных полностью (побитно) перепишется
в сдвиговый регистр RSR.
Это и есть преобразование принятого байта данных из последовательной в
параллельную форму.
После этого, весь байт можно одномоментно считать с выходов 8-ми ячеек сдвигового
регистра, что, после осуществления последней выборки, и имеет место быть.
Кроме того, после осуществления последней выборки, начинает работать устройство
поиска стопового бита, то есть, уровня 1.
Если уровень 1, на приемной линии, обнаруживается, то устройство поиска стопового
бита “сообщает” об этом устройству поиска стартового бита и “вырубается”.
Устройство поиска стартового бита закрывает “шлагбаум” до появления, на приемной
линии, нулевого уровня следующего стартового бита.
Далее - “на колу мочало, начинаем все сначала”.
Итак, принятый байт данных одномоментно считался.
Куда?
В регистр RCREG.
1
Это тот регистр, из которого программа ПИКа “черпает” принятые байты данных
(“закрома” приемника USART).
Таким образом, регистр RCREG является буфером приемника USART, причем,
буфером двухуровневым.
Это означает то, что RCREG является названием сдвоенного регистра, состоящего из
двух регистров - RCREG1 и RCREG2.
Получается что-то типа “накопителя” данных.
“Механизм” его работы такой:
Изначально (до приема 1-го байта массива байтов), регистры RCREG1 и RCREG2
пусты.
После осуществления выборки последнего бита 1-го байта данных, он (байт)
одномоментно переписывается (аппаратно), из регистра RSR, в регистр RCREG1.
А так как регистр RCREG2 пуст, то происходит примерно то же, что и при передаче:
байт данных, как бы, “проскакивает транзитом” регистр RCREG1 и “оседает” в регистре
RCREG2, из которого и производится его считывание программой ПИКа.
Таким образом, считывание программой ПИКа принятого приемником USART байта
данных, происходит строго из регистра RCREG2, а не из регистра RCREG1.
Регистр RCREG1 является “накопителем” данных.
После осуществления выборки последнего бита 2-го байта данных, он аппаратно
переписывается в регистр RCREG1.
Далее, его (байта) “судьбинушка” зависит от того, пуст регистр RCREG2 или полон.
Регистр RCREG2 “опустошается” сразу же после считывания из него, программой
ПИКа, байта данных.
Так вот, если это считывание произошло (регистр RCREG2 пуст), то 2-й байт данных
“проскакивает транзитом” регистр RCREG1 (по образу и подобию сказанного выше) и
“оседает” в регистре RCREG2.
Если этого считывания не произошло, то 2-й байт данных “ставится в очередь”, то
есть, “закладывается на хранение” в регистр RCREG1, и будет находиться там до
“опустошения” регистра RCREG2 (считывания программой ПИКа, из буфера приемника
USART, принятого байта данных).
И так далее, для любого количества принятых байтов данных.
После такого объяснения, возникает законный вопрос: “Для чего нужен такой
относительно сложный способ буферизации”?
Ответ: если есть “жу-жу”, то оно неспроста (Винни-Пух совсем не глуп).
Значит, речь идет о каком-то “ефрейторском зазоре”, предохраняющем от какой-то
“бяки”.
Какой “бяки”?
А той, которая может иметь место быть в ПП прерывания.
Стоп. Теперь, для понимания происходящего, нужно разобраться с прерываниями.
В этой связи, возникает вопрос: “Если программа ПИКа исполняется последовательно,
а значит и исключается случай одновременной реализации двух программных
процедур, то каким образом ПИК “поймет”, что компьютер “заслал” в линию байт
данных и его нужно принять”?
А если, на “приемной проволочине”, байт данных появился во время исполнения
программной процедуры передачи?
В этом случае, о проверках “линейных” уровней и речи идти не может
(“обпроверяешься”).
Остаются только прерывания.
Таким образом, в “основном теле” программы, должна исполняться процедура передачи
байтов данных, а в ПП прерывания должна исполняться процедура приема байтов
данных.
В этом случае, “все шито – крыто”.
Значит нужно устроить “разборки” с прерываниями от приемника USART.
Есть такие?
Есть.
Прерывание от приемника USART происходит после записи принятого байта
данных из сдвигового регистра (RSR) в буфер приемника USART (в регистр
RCREG1).

2
При этом, поднимается флаг прерывания от приемника USART (бит №5 регистра PIR1
с названием RCIF).
Таким образом, на момент возникновения прерывания от приемника USART, в его
буфере “лежит” принятый, “тепленький” байт данных, который остается только считать
и использовать в дальнейшей работе программы ПИКа.
Именно это и делается в ПП прерывания.
Но как принятый байт данных “пролез” в сдвиговый регистр RSR (а затем и в буфер
приемника USART) во время работы программы в “основном теле” программы, ведь
заполнение сдвигового регистра RSR происходит до ухода в прерывание от приемника
USART?
А вот так и “пролез” - “молча”, как “шпион”, так как работу генератора скорости
обмена никто не отменял, и этому “шпиону” абсолютно “наплевать” на то, что там
“вытворяет” программа в своем “основном теле”, так как для обеспечения его
“пролезания”, необходимо и достаточно только наличие такта, формируемого
генератором скорости обмена.
Не дать, не взять - “выпускник шпионской школы”.
А мы тебя, родимого, поджидаем у “дырки”, из которой ты вылезешь (знание - сила) и
цап за ухо…
Вот ты, пацан, и попался. Колись.
Видишь бормашину? То-то и оно … Влип ты серьезно.
И так будет с каждым, так как особой изворотливости вообще не прослеживается.
Клоны есть клоны. С такими творчески работать - со скуки помрешь.
Проще “сваять” такую же “тупую”, как эти “шпионы”, подпрограмму прерываний, и пусть
она, по мере “вылезания”, извлекает их из “дырки”, “дает подзатыльник” (чтобы
сговорчивее были), ставит на их оловянных лбах “штемпели” и “по почте отправляет в
район трудотерапии”. Будут там “целину пахать” и приносить пользу обществу.
Сопротивление бесполезно.
После исполнения такой “почтовой” ПП прерываний, рабочая точка программы
возвращается в то “место” (в надежде на Вашу информированность, “расшифровывать”
не буду) “основного тела” программы, из которого она ушла в прерывание и программа
начинает исполняться далее.
Естественно, что для ухода в прерывания от приемника USART, эти прерывания
должны быть разрешены (более подробно - ниже).
Теперь вернусь к ранее прерванным рассуждениям.
Так вот, в ПП прерывания, перед считыванием, из регистра RCREG2, принятого байта
данных, могут “делаться еще какие-то дела той или иной массивности”.
В этом случае, считывание, программой ПИКа, принятого байта данных, будет
произведено не сразу же после его “загрузки” в регистр RCREG2, а с некоторой
“ёклмн-задержкой” (я ее так “обозвал” для функционального выделения).
А если предположить, что регистра RCREG1 нет (работает только RCREG2), и “ёклмн-
задержка” больше интервала времени приема одного кадра?
В этом случае, произойдет “наезд” одного байта на другой и будет “Гитлер капут”.
В большинстве случаев, “ёклмн-задержка” меньше интервала времени приема одного
кадра, так как он (интервал) довольно-таки внушителен.
В этом случае, “накопитель” (регистр RCREG1) не работает, и имеет место быть
“транзитное проскакивание” принятого байта данных, через регистр RCREG1, в регистр
RCREG2.
Если величина “ёклмн-задержки” будет больше времени приема одного кадра, то
ничего страшного также не произойдет, так как в работу включится “накопитель”.
А вот если величина “ёклмн-задержки” будет больше времени приема 2-х кадров, то
наступит “Гитлер капут”.
Вывод: величина интервала времени между моментом входа в ПП прерывания и
моментом считывания байта из буфера приемника USART, не должна превышать
величину интервала времени приема 2-х кадров.
Выполнить это условие легко, так как интервал времени приема 2-х кадров достаточно
внушителен (а ради этого и затеян весь “сыр-бор” с буферизацией), и в ПП
прерывания, нужно очень “постараться” (причем, специально или с дуру, “влепив”, до
считывания принятого байта, массивную задержку), чтобы его превысить.
Разработчики они на то и разработчики, чтобы перестраховываться.
3
А раз это так, то такого рода перестраховка требует “развития темы”, ведь мало
“проколоться”, нужно еще и сделать так, чтобы этот “прокол” был сразу же обнаружен.
Вот Вам и смысл существования бита №1 регистра RCSTA, с названием OERR.
Это флаг переполнения буфера приемника USART, который устанавливается аппаратно
(можно только прочитать).
Если переполнение буфера приемника USART произошло (величина интервала времени
между моментом входа в ПП прерывания и моментом считывания байта из буфера
приемника USART, превышает величину интервала времени приема 2-х кадров), то
флаг OERR поднимается (OERR=1). Это считается ошибкой приема.
После поднятия флага OERR, работа приемника USART “парализуется” (он
блокируется), и ничего не остается делать, как запретить прием, то есть, установить в
0 бит CREN регистра RCSTA (при этом, флаг OERR сбрасывается), а затем его
разрешить (для осуществления новой попытки чтения).
Реально, на практике, вероятность переполнения буфера приемника есть, но она очень
мала (для этого нужно очень сильно “постараться”).
В связи с этим, а также с учетом знания изложенной выше информации (всегда
“извернуться” можно), необходимость в проверках состояний флага OERR просто
отпадает, и на него можно “закрыть глаза” (но иногда “подглядывать”, так как
осторожность и бдительность должны присутствовать всегда).
Имеется еще один флаг - флаг ошибки кадра: бит №2 регистра RCSTA с названием
FERR.
Флаг FERR поднимается (FERR=1) тогда, когда не обнаруживается стопового бита и
остается опущеным (FERR=0) в том случае, если стоповый бит обнаруживается.
Такую проверку вполне можно включить в цикл считывания байта данных, в случаях
работы по длинной линии с помехами, с целью либо блокировки “кривого” кадра, либо
организации повторного его приема (“до победного конца”).
В большинстве случаев, применяются короткие соединительные линии, и поэтому на
флаг FERR также можно “закрыть глаза” (с поправкой - см. выше).
Итак, “основные контуры обрисованы” и теперь нужно “все собрать до кучи”, а заодно
и выяснить кое-какие детали.
В этом деле мне помог Высочанский Петр.
Петр, по собственной инициативе (а это дорогого стоит), “сваял” простое, учебное
устройство, которое позволяет визуально отследить процесс двунаправленного обмена
информацией между ПИКом (PIC16F628A) и компьютером.
Принципиальная схема устройства:

Сразу нужно прояснить один момент.


Почему катод светодиода HL6 подключен не к выводу RA5, а к выводу RB0?

4
Потому, что вывод RA5 “славен” тем, что, при его настройке на работу “на выход”,
выход соответствующей защелки к этому выводу либо не подключается, либо этой
защелки вообще нет (подключаться не к чему).
Из даташита PIC16F628A не вполне ясно, какой именно из этих вариантов имеет
место быть, но от этого смысл не меняется.
А смысл такой: вывод RA5 не может ничем управлять. Он работает только на ввод (с
него можно только считать уровни).
Обычно, вывод RA5 используется как вывод MCLR, но в данном случае, это не так: в
битах конфигурации, он настроен как порт ввода (бит №5 в слове конфигурации).
Примечание: информация по выводу RA5 имеется на стр. 2 и 3 подраздела 1/4
“Самоучителя по программно – аппаратному анализу”.
По поводу резистора R5.
Технически корректнее было бы, вместо одного токоограничительного резистора R5,
подключить 8 токоограничительных резисторов (по одному на каждый светодиод).
В последнем случае, яркость свечения светодиодов не зависела бы от количества
активных светодиодов.
В данном случае, яркость свечения светодиодов зависит от количества активных
светодиодов, но это беда небольшая - устройство-то учебное и “лишние” резисторы
ему совсем не нужны.
Ну и пусть яркость свечения светодиодов будет уменьшаться по мере увеличения
количества активных светодиодов.
В данном случае, важны сами факты их “загорания”, а не его интенсивность.
В этом, с Петром я согласен.
В качестве преобразователя уровней, использован простой преобразователь уровней,
не содержащий дорогих радиодеталей.
А это программа Петра:

;********************************************************************************
; USART.asm РАБОТА "СВЯЗКИ" ПИК-КОМПЬЮТЕР ПРИ ДВУНАПРАВЛЕННОМ ОБМЕНЕ ДАННЫМИ.
; Учебная программа.
;********************************************************************************
; Автор: Высочанский Пётр, Приднестровье.
; "Практикум по конструированию устройств на PIC контроллерах".
; http://ikarab.narod.ru karabea@lipetsk.ru
; Эта программа входит в состав 6-го раздела.
;-----------------------------
; Объем программы: 58 команд.
;********************************************************************************
LIST p=16F628A ; Определение типа микроконтроллера.
__CONFIG 03F10H ; Внутренний RC генератор, PWRTE включен,
; WDT отключен.
;================================================================================
; Определение положений регистров специального назначения.
;================================================================================
OptionR equ 01h ; Option - банк1.
Status equ 03h ; Status
PortA equ 05h ; Порт A.
TrisA equ 05h ; Tris A - банк1.
PortB equ 06h ; Порт B.
TrisB equ 06h ; Tris B - банк1.
IntCon equ 0Bh ; IntCon.
PIR1 equ 0Ch ; Регистр флагов прерываний от периферии.
PIE1 equ 0CH ; Регистр содержит биты разрешения прерываний
; от периферии.
PCON equ 0EH ; Регистр выбора частоты в режиме
; RC генератора.
RCSTA equ 18h ; Регистр управления и статуса
; приёмника USART.
TXSTA equ 18H ; Регистр управления и статуса
; передатчика USART.
SPBRG equ 19H ; Регистр скорости обмена USART.
TXREG equ 19H ; Регистр данных передатчика USART.

5
RCREG equ 1AH ; Регистр данных приёмника USART.
CMCON equ 1Fh ; Регистр управления модулем компараторов.
;================================================================================
; Определение названий и положений регистров общего назначения.
;================================================================================
pr_w equ 70h ; Регистр хранения содержимого W.
pr_stat equ 71h ; Регистр хранения содержимого Status.
knopka equ 72h ; Регистр хранения кода клавиатуры.
p_temp equ 73h ; Регистр временного хранения.
;================================================================================
; Определение места размещения результатов операций.
;================================================================================
W equ 0 ; Результат направить в аккумулятор.
F equ 1 ; Результат направить в регистр.
;================================================================================
; Присваивание битам названий.
;================================================================================
RP0 equ 5 ; Биты
RP1 equ 6 ; банков.
Z equ 2 ; Флаг нулевого результата.
TXIF equ 4 ; Флаг прерывания от передатчика USART.
;================================================================================
org 0 ; Начать выполнение программы
goto START ; с подпрограммы START.
;********************************************************************************

;********************************************************************************
; Подпрограмма прерываний от приёмника USART.
;================================================================================
org 4 ; Точка входа в прерывание.
movwf pr_w ; Сохранение содержимого
swapf Status,W ; регистров W и Status на
movwf pr_stat ; момент ухода в прерывание.

bcf Status,RP0 ; Переход в 0-й банк.


movf RCREG,W ; Копирование байта из регистра данных
movwf p_temp ; приемника USART (через W) в регистр
; временного хранения.
btfsc p_temp,5 ; Анализ состояния пятого принятого бита.
goto RB_0 ; Если он =1, то переход на метку RB_0.
bsf PortB,0 ; Если он =0, то установка на выводе RB0
; уровня лог.1.
DALEE comf p_temp,W ; Инверсия содержимого регистра p_temp (в нем
movwf PortA ; хранится принятый байт) и запись результата
; в защелки порта А.
swapf pr_stat,W ; Восстанавление
movwf Status ; содержимого
swapf pr_w,F ; регистров
swapf pr_w,W ; W и Status.

retfie ; Выход из ПП прерывания.

RB_0 bcf PortB,0 ; Установка на выводе RB0 уровня лог.0.


goto DALEE ; Переход на метку DALEE.

;********************************************************************************
; "Основное тело" программы. Начало программы.
;********************************************************************************
; Подготовительные операции.
;================================================================================
START bsf Status,RP0 ; "Двойная, штатная" команда
bcf Status,RP1 ; перехода в 1-й банк.

clrf OptionR ; Включение подтягивающих резисторов (для

6
; кнопок).
clrf TrisA ; Все выводы порта А работают на выход.
movlw b'11111110' ; Выводы порта В работают на вход (в том числе
movwf TrisB ; и RB1,RB2), кроме RB0 (работает на выход).

bsf PCON,3 ; Частота внутреннего RC генератора


; равна 4 МГц.
movlw b'00100110' ; Настройка USART: высокоская скорость,
movwf TXSTA ; асинхронный режим, передача разрешена,
; 8-битная передача.
movlw d'25' ; Установка скорости
movwf SPBRG ; приема/передачи 9600 бит/с.
movlw b'00100000' ; Разрешение прерываний от приемника USART
movwf PIE1 ; и запрет остальных периферийных прерываний.
bcf Status,RP0 ; Переход в 0-й банк.

movlw .07 ; Отключение модуля


movwf CMCON ; компараторов.

movlw b'10010000' ; Разрешение работы приемника USART


movwf RCSTA ; и разрешение работы модуля USART.

movlw 0FFh ; Гашение


movwf PortA ; всех
bsf PortB,0 ; светодиодов.

movlw b'11000000' ; Разрешение всех немаскированных


movwf IntCon ; прерываний от периферийных модулей.
;================================================================================
; Основная часть программы.
;================================================================================
; Опрос клавиатуры.
;----------------------------------------------
SNOVA movf PortB,W ; Считывание байта из порта В в W.
iorlw b'00001111' ; Установка единиц в младшем полубайте W.
movwf knopka ; Запись полученного результата
; в регистр knopka.
comf knopka,F ; А затем инверсия его содержимого.
;#############################################
; ПОЯСНЕНИЕ.
;#############################################
; При нажатии одной из кнопок, в регистр
; knopka будет записано одно из чисел:
; SB1: 10H 0001 0000
; SB2: 20H 0010 0000
; SB3: 40H 0100 0000
; SB4: 80H 1000 0000
; Если нажата одна из кнопок, флаг Z
; регистра Status будет сброшен.
;---------------------------------------------
; Анализ содержимого регистра knopka.
;---------------------------------------------
btfsc Status,Z ; Все кнопки отжаты или одна из кнопок нажата?
goto $+3 ; Если отжаты, то переход на запись
; в TXREG нуля.
movf knopka,W ; Если одна из кнопок нажата, то код кнопки
; записывается в W,
goto $+2 ; а затем - переход на его запись в TXREG.
movlw 0 ; Запись в W нуля.
;---------------------------------------------
; Передача байта регистра knopka.
;---------------------------------------------
movwf TXREG ; Загрузка байта в буфер передатчика.
btfss PIR1,TXIF ; Байт данных передан или нет?
goto $-1 ; Если байт еще не передан, то ожидаем.

7
goto SNOVA ; Если байт передан, то переход на
; следующий цикл опроса клавиатуры.
;********************************************************************************
end ; Конец программы.

Объяснение работы программы USART.asm.

Начну с битов конфигурации.

Можете свериться даташитом PIC16F628A (стр. 89).


С учетом этого, к рисунку 2 и добавить нечего.
Программа начинает исполняться с “двойной, штатной” команды перехода в 1-й банк.
По умолчанию, выставлен 0-й банк, и поэтому команда bcf Status,RP1 не обязательна,
но, для порядка и привыкания к относительно сложной “банковской конструкции”
PIC16F628A, пусть “глаза помозолит”.
Далее, операций с битом RP1 не производится.
Содержимое регистра OptionR сбрасывается в ноль (в данном случае, самый простой
вариант) только потому, что, для обеспечения нормального функционирования кнопок,
нужно включить подтягивающие резисторы порта В.
Примечание: вариант настройки регистра OptionR “по умолчанию” не пройдет, так как,
по умолчанию, во все его биты записываются единицы.
Так как к выводам порта А подключены светодиоды, эти выводы настраиваются на
работу “на выход”.
Вывод RB0 также настраивается на работу “на выход”, так как к нему тоже подключен
светодиод.
Остальные выводы порта В настраиваются на работу “на вход”: RB4 … RB7 потому,
что к ним подключены кнопки, а RB1 и RB2 потому, что задействуется модуль USART,
и такая настройка является необходимиым условием его функционирования.
Вывод RB3 настраивается на работу “на вход” “за компанию” (не задействован).
Далее устанавливается значение частоты внутреннего RC генератора равное 4 Мгц.
Этот выбор происходит в бите №3 (OSCF) регистра PCON установкой его в 1 (см.
стр. 24 даташита PIC16F628A).
Далее происходит та настройка модуля USART, которая была описана ранее.
Повторяться не буду.
А вот далее производится нечто новенькое - разрешение прерываний от приемника
USART и запрет прерываний от остальных периферийных модулей.
Что такое периферийные модули?
Проще всего представить себе, что существует некая “мать” в виде PIC16F84A,
которая содержит в своем составе базовый “набор” модулей, а все что дополняет этот
“набор”, и называется периферийными модулями.
Операции в 1-м банке закончились, и далее следует переход в 0-й банк, после чего
подготовительные операции продолжаются.
Так как модуль компараторов не задействуется, то его обязательно нужно отключить
(почему? См. подраздел 6/1 “Практикума…”).
Далее, разрешается работа приемника USART и вцелом модуля USART.
Далее, гасятся все светодиоды.

8
При этом, все выходы защелок порта А переводятся в единичное состояние потому,
что имеет место быть линейка светодиодов с общим анодом (если бы линейка была с
общим катодом, то выходы защелок нужно было бы переводить в нулевое состояние).
То же самое проделывается и с “портящим строй” выводом RB0.
Далее происходит еще одна “манипуляция” с настройкой прерываний.
На этот раз то, что было предварительно разрешено ранее, глобально разрешается.
Почему в регистре IntCon выставляется две разрешающих единицы, а не одна?
Потому, что есть разделение на два вида модулей - основные модули и
периферийные модули (см. то, о чем говорилось выше), причем, необходимым
условием глобального разрешения работы любого модуля (не зависимо от того,
основной он или периферийный), является установка бита GIE регистра IntCon в 1.
Для того чтобы разрешить прерывания от ранее выбранного периферийного модуля
(модулей), нужно еще, в добавок, выставить 1 и в бите PEIE регистра IntCon (см. стр.
21 даташита PIC16F628A).
Таким образом, бит PEIE, фактически, является битом некоего “окологлобального”
разрешения прерываний от периферийных модулей, и его “статус” ниже, чем у бита
GIE.
По этой причине, бит GIE, как бы, является “начальником”, а бит PEIE “находится у
него в подчинении”.
Следовательно, 1 нужно установить и в бите GIE, и в бите PEIE.
Это Вы и видите в самом конце ПП START.
В конечном итоге, запрещаются все виды прерываний, кроме прерываний от приемника
USART.
“Ковыляю” далее.
Предположим, что байты данных не принимаются приемником USART, а значит и
прерываний, от приемника USART, нет, то есть, речь идет о “чистой передаче”.
Что, в данном случае, подлежит передаче?
Код клавиатуры из 4-х кнопок, подключенных к выводам RB4 … RB7 (в составе байта!).
Поэтому, сразу же после завершения подготовительных операций ПП START, рабочая
точка программы “перескакивает” (на “линейном” участке) в процедуру опроса
клавиатуры.
Так как кнопки подключены к выводам RB4 … RB7 (а это соответствует старшему
полубайту), то младший полубайт, во избежание возможных “недоразумений”,
“нейтрализуется” (iorlw b’00001111’), после чего, результат этой “нейтрализации”
(хххх 1111) переписывается в регистр knopka.
Так как далее будет произведена проверка на нулевой результат, то содержимое
регистра knopka необходимо инвертировать, иначе нулевого результата не будет
никогда.
Таким образом, результатом “манипуляций” с клавиатурой будет либо нулевой
результат (если ни одна из кнопок не нажата), либо, в зависимости от того, какая
именно кнопка нажата, то, что Вы видите, в тексте программы, под словом
“ПОЯСНЕНИЕ”.
При этом следует отметить то, что при “одновременном” (я надеюсь, что смысл
кавычек понятен), долговременном нажати 2-х и более кнопок, будут последовательно
формироваться дополнительные коды, но в программе Петра (в той, которая в
Виндах), на индикацию выведется название только той кнопки, которая была нажата
первой, то есть, идентификация нажатой кнопки производится по первому кадру.
Теперь можно производит проверку на нулевой (или нет) результат.
Если результат нулевой (все кнопки отжаты), то в буфер передатчика записывается 0.
Если результат не нулевой, то в буфер передатчика записывается код кнопки.
Напоминаю, что передача, передатчиком USART, байта данных начинается сразу же
после записи этого байта данных в буфер передатчика USART (movwf TXREG).
Во время передачи байта, работает “плавающая” задержка, “механизм” работы которой
был описан ранее.
После выхода рабочей точки программы из “плавающей” задержки, “миссия закончена”
и можно переходить на следующий цикл опроса клавиатуры (goto SNOVA).
Таким образом, по ходу работы программы USART.asm, в зависимости от текущего
состояния клавиатуры, возможна передача всех ее кодов, включая и код 0000 0000,
соответствующий отжатию всех кнопок.
9
В этом случае, программа Петра (та, которая в Виндах) “уничтожает” название ранее
нажатой кнопки (ни одно название кнопки на индикацию не выводится).
Итак, компьютерная программа Петра “проглотила”, переданный ПИКом, байт кода
клавиатуры и вывела на индикацию (в своем окне) название той кнопки, которой этот
код соответствует.
Пол-задачи решено.
Теперь нужно продемонстрировать работу приемника USART.
В данном случае, речь не идет об “отклике” компьютера на нажатие той или иной
кнопки, но это можно сделать, в простейшем случае, “ретранслировав” (через
компьютер) байт данных с одной “проволочины” на другую.
В этом случае, потребуется линейка только из 4-х светодиодов.
Петр усложнил задачу.
Его программа (та, которая в Виндах), хотя и не “откликается” на принятый байт, но
позволяет, на приемной стороне, в линейке из 8-ми светодиодов, визуально
сформировать любое двоичное число в диапазоне байта, а это, с точки зрения
обучения, на мой взгляд, более наглядно.
“Набор” этого числа происходит при помощи “кнопок”, расположенных в окне
программы Петра (что-то типа 8-кнопочной клавиатуры).
Каждой кнопке соответствует один из номеров битов байта и соответственно, один из
светодиодов линейки, который “привязан” к этому биту.
Например, щелкаете по кнопке бита №2, и “на периферии” (в устройстве на ПИКе), в
линейке светодиодов, “загорается” 2-й светодиод.
Если щелкнуть по этой же кнопке еще раз, то 2-й светодиод “погаснет”.
То же самое можно проделать и с другими кнопками, причем, они работают
независимо друг от друга, то есть, речь идет об аналоге 8-кнопочного переключателя с
независимой фиксацией.
В соответствии с этой логикой, формируется однобайтный код (коды), который
передается компьютером и соответственно, принимается приемником модуля USART.
Итак, компьютерная программа сформировала байт данных и передала его в линию.
К другому концу этой линии подключен вход приемника USART, который “денно и
ночно сторожит” состояние своей приемной “проволочины” на предмет наличия
стартового бита.
С момента обнаружения приемником USART нулевого уровня стартового бита,
запускается “механизм” приема байта данных, который я описал выше.
Повторяться не буду.
Сразу же после того, как принятый байт данных будет загружен из сдвигового регистра
в буфер приемника USART, произойдет прерывание от приемника USART (оно
разрешено в ПП START).
Начиная со 2-го “витка” полного цикла программы, “зона” разрешения прерываний от
приемника USART включает в себя весь полный цикл программы, что есть “зер гут” по
той простой причине, что момент возникновения прерывания есть случайное событие.
Таким образом, прерывание от приемника USART может возникнуть в интервале
времени исполнения любой команды “основного тела” программы, начиная от команды
movf PortB,W и до директивы end.
При наступлении такого события, адрес возврата закладывается в вершину стека,
работа программы, в ее “основном теле”, приостанавливается, и рабочая точка
программы “улетает” в подпрограмму прерываний.
Сначала, в ПП прерываний, исполняются “формальности” (сохранение содержимого
регистров Status и W).
Затем, на всякий случай, осуществляется переход в 0-й банк.
В принципе, в данном случае, этот переход не нужен, так как, после разрешения
прерываний от приемника USART, происходит работа только в 0-м банке, но я не стал
убирать эту команду “из идейных соображений”: “враг не дремлет” и лишняя
тренировка бдительности не помешает.
После “соблюдения формальностей”, можно сразу “брать быка за рога”, то есть,
заняться считыванием принятого байта данных в какой-нибудь предварительно
назначенный, под это дело, регистр общего назначения.
В данном случае, байт данных, через регистр W, переписывается в регистр p_temp.

10
Теперь нужно вспомнить о 6-м светодиоде (на принципиальной схеме - HL6), который
“портит строй”.
Он “привязан” к биту №5 принятого байта данных.
Значит, нужно “переправить” бит №5 в защелку вывода RB0, причем, c инверсией.
Посмотрите, как это сделал Петр. По-моему, ничего особо сложного в этом нет.
После этого “укрощения строптивого”, начинает исполняться ПП DALEE, которая
представляет собой обычную процедуру вывода принятого байта данных в защелки
порта А, но опять же, с инверсией.
Примечание: содержимое байта, выводимого в линейку светодиодов, формирует
программа Петра, составленная в Виндах.
Она выдает коды, расчитанные на линейку светодиодов с общим катодом, но
применяется линейка светодиодов с общим анодом.
Это и есть причина необходимости упомянутой выше инверсии.
Далее, следует стандартная процедура выхода из прерывания, но с приятной
особенностью.
Вопрос: “Почему в этой процедуре отсутствует программный сброс флага того вида
прерывания, которое разрешено, то есть, флага прерывания от приемника USART с
названием RCIF (бит №5 регистра PIR1)”?
Дело в том, что флаг RCIF сбрасывается не программно, а аппаратно (RCIF можно
только прочитать).
Этот сброс происходит автоматически, при чтении регистра RCREG.
Ранее было такое чтение?
Было.
Ну и ладушки: “бабу с воза - кобыле легче”.
Далее “все как по писанному” - восстановление содержимого регистров Status и W,
retfie и все дела.
Рабочая точка программы, по стеку, возвращается в “основное тело” программы, после
чего оно (“основное тело”) “просыпается” и “начинаются его рабочие будни” (до
следующего прерывания).
Баста. Работа программы USART.asm объяснена.
Общие впечатления: какая ты маленькая, да удаленькая! И есть-то - всего ничего (58
команд), но “понатыкано в тебе”…
Вывод: “мал золотник, да дорог”.
А теперь давайте осмыслим произошедшее.
Получается, что:
1. При передаче, прерываний нет (прерывания от передатчика USART запрещены), но
флаг прерываний (TXIF) в программе используется (см. “плавающую” задержку).
2. При приеме, прерывания есть (прерывания от приемника USART разрешены), но
флаг прерываний (RCIF) в программе не используется.
Вот такая любопытная комплиментарность прослеживается.
А теперь, для разнообразия, “похулиганю”, а заодно и “подкину пищу для
размышлений”.
В даташите PIC16F628A (и в других тоже) утверждается, что, в асинхронном режиме
работы модуля USART, имеет место быть полный дуплекс.
В основном - да.
А как быть вот с этим случаем?
Ничего не передается.
Принят байт данных и произошел уход в прерывание.
Во время отработки ПП прерывания, мне “взбрело в голову” передать байт данных.
Как Вы думаете, что из этого получится?
Правильно. Ничего не получится, “хоть обнажимайся”.
И в самом деле, пока рабочая точка программы не выйдет из ПП прерывания, ни о
какой передаче байта данных и речи идти не может, так как, в этом случае,
невозможно загрузить байт данных в буфер передатчика (это делается программно) и
соответственно, его передать.
Передать байт данных можно будет только после возврата рабочей точки программы
из ПП прерываний в “основное тело” программы.
Так какой же это полный дуплекс?

11
Полный дуплекс, в его классическом понимании, не накладывает никаких ограничений
на момент передачи, то есть, процедура передачи (и приема тоже) должна
инициироваться случайным событием.
Или, может быть, разработчики вложили в это словосочетание какой-то иной смысл?
Хоть бы спустились со своих небес и растолковали его нам, убогим.
Вот и получается такая “непонимайка”: разработчики говорят, что в асинхронном
режиме работы модуля USART имеет место быть полный дуплекс, а на самом деле,
из-за наличия косвенной фазовой коррекции, имеет место быть псевдоасинхронный
режим работы модуля USART, да к тому же еще и не обеспечивающий полного
дуплекса.
Выводы делайте сами.

Инструкция по пользованию программой USART.exe от Петра Высочанского.

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


подключено предлагаемое устройство.
По умолчанию, будет использоваться последовательный порт COM2.
Если попытка использовать выбранный порт не увенчалась успехом, скорее всего
этот порт используется другой программой или отсутствует в системе.
В любом случае, в верхней части окна будет сообщено о результатах открытия порта.
При успешном открытии, появится надпись "Порт открыт", а в противном случае,
будет надпись "Порт не удалось открыть".
Скорость обмена информацией следует оставить по умолчанию, т. е. 9600 бит в
секунду.
При нажатиях на экранные кнопки "HL1-HL8", можно включать или выключать
соответствующие светодиоды.
Эти кнопки имеют фиксацию в нажатом положении: первый щелчок по кнопке
зафиксирует её, и соответствующий светодиод начнёт светиться.
Повторный щелчок по той же кнопке приведёт к тому, что она будет отпущена и
одноимённый светодиод погаснет.
Теперь, подробнее разберем, что же происходит при нажатии этих кнопок.
А происходит следующее: после нажатия на одну из экранных кнопок "HL1-HL8", её
номер отправляется, последовательным кодом, через выбранный порт, на вход (RXD)
приёмника USART.
Передаваемый код отображается в окне в шестнадцатеричном формате.
Если внимательней присмотреться, то становится понятно, что каждая нажатая кнопка
устанавливает соответствующий бит в единицу, а отпущенная сбрасывает его.
Кнопка HL1 изменяет состояние нулевого бита, HL2 - первого бита и т. д.
Допустим, если передаваемый код в шестнадцатеричном формате выглядит так "81H",
то это соответствует "10000001" в двоичном формате и означает, что на данный
момент нажаты кнопки "HL1" и "HL8", а остальные отпущены.
При нажатии на одну из этих кнопок, происходит опрос состояния всех кнопок, и с
помощью операций "И" и "ИЛИ" формируется передаваемый байт.
Если нажать на одну из кнопок "SB1-SB4" подключённых к контроллеру, в окне
программы появится надпись с названием той кнопки, которая была нажата.

Я собрал устройство, разработанное Петром, и проверил его в работе.


Устройство работает в полном соответствии со сказанным выше.
Выражаю благодарность Петру Высочанскому за помощь в создании этого
подраздела.

"Практикум по конструированию устройств на PIC контроллерах"      http://ikarab.narod.ru       E-mail: karabea@lipetsk.ru

12

Вам также может понравиться