Подключение кнопки к AVR — Практическая электроника
Подключение кнопки к AVR не должно у вас вызывать никаких трудностей.
В предыдущей статье мы провели эмуляцию схемы в программе Proteus, помигали светодиодом и научились прошивать наш виртуальный микроконтроллер. Наверняка многим из читателей пришла в голову мысль: «А можно ли помигать светодиодом, использую кнопку, подключенную к МК?
Да, разумеется, это возможно. Реализуется довольно легко. Причем можно сэмулировать кнопку как с фиксацией так и без фиксации. Причем в программе Proteus применить оба типа кнопок можно с помощью одного и того же одинакового макроса кнопки. В каких случаях это может быть полезно? Например, нам требуется осуществить выбор режимов работы устройства. Давайте разберем подробнее, как это реализовать с помощью микроконтроллера
Для того, чтобы иметь наглядное представление, что у нас действительно выбор из двух режимов, мы соберем простенькую схемку на 4 светодиодах с управлением одной кнопкой. При первом варианте у нас поочередно загораются с первого по четвертый светодиоды. При втором варианте то же самое, но в обратной последовательнос
Итак к делу. Так выглядит у нас наша схема в программе Proteus (кликните для увеличения):
В этой схеме мы уже видим отличия от той, которую собирали еще в прошлой статье. В левой части схемы мы видим обозначения кнопки и источника питания +5 вольт.
Как мы уже разобрали, питание и землю мы берем во вкладке «Терминал». Обозначаются они у нас соответственно Power и Ground.
Обозначается у нас питание схемы треугольником с чертой, делящей его по высоте. Рядом, на рисунке, изображено обозначение кнопки. Справа от кнопки мы видим закрашенный красный круг с двухнаправленной стрелочкой. Если во время эмуляции нажать на него, то кнопка у нас зафиксируется и будет постоянно нажата. После повторного нажатия на него фиксация снимается.
Перед использованием нам нужно выбрать кнопку в библиотеке аналогично остальным деталям. Для этого нужно набрать в поле «Маска» слово «but». Затем в поле «Результаты» слово «BUTTON»:
После этого кнопка появиться у нас в списке, вместе с выбранными деталями, применяемыми в проекте.
[quads id=1]
Какие порты у нас используются в проекте. Ниже на рисунке мы видим отходящие линии от портов РA0, РВ0, РВ1, РВ2 и РВ3. К порту В у нас подключены светодиоды, а к порту А — кнопка.
Итак, при нажатии, мы замыкаем цепь соединяющую +5 вольт с портом РА0 и верхним выводом резистора. Для чего у нас здесь вообще установлен резистор? Дело в том, что цепь кнопки должна быть замкнутой. После того как мы установили резистор, ток у нас течет от плюса питания через кнопку, резистор и дальше на землю.
Номинал резистора достаточно взять равным 200 Ом. Итак, когда мы нажимаем кнопку, мы соединяем порт РА0 с +5 вольт питания, и если мы опросим ножку РА0 на наличие напряжения или его отсутствие, мы сможем влиять на выполнение нашей программы.
Скрины с текстом нашей программы я привел ниже:
Итак отличия от прошлого проекта заключаются в том, что все 8 выводов порта РА мы конфигурируем на вход, выводы порта РВ0 — РВ3 мы конфигурируем на выход, а РВ4 — РВ7 на вход.
Затем мы используем в нашей программе проверку условия «if»
Итак, мы видим в строчке после «if», в скобках, условие выполнения. Код ниже выполняется, если на порту PA0 у нас присутствует логический ноль, или ноль вольт. Этот текст в скобках — сдвиг бита порта. Мы разберем в одной из следующих статей, а пока достаточно принять на веру, что этим мы опрашиваем кнопку на
Аналогично, с помощью условия «if» мы опрашиваем кнопку на нажатие. Обратите внимание, текст у нас в скобках изменился. Это означает что если на ножке РА0 у нас логическая единица, мы выполняем условие, то есть текст в фигурных скобках. То есть другими словами, у нас при отжатой кнопке, поочередно загораются и тухнут светодиоды с первого по четвертый, а при нажатии и удерживании, загораются и тухнут с четвертого по первый. Таким образом, мы можем влиять на выполнение программы, с помощью нажатия кнопки, опрашивая наличие на ней логического нуля, или логической единицы
Также прикрепляю архив, в котором находятся файл «сишник», HEX и файл Протеуса.
А вот и видео
Драйвер кнопок устройства — Программирование микроконтроллеров AVR — Каталог статей
Некоторое время назад я делал проект кодера для радиоуправляемых моделей Vcoder и мне понадобилось использовать кнопки для управления работой прошивки.тогда я не сильно задумывался о usability своей прошивки, и написал драйвер который организовывал опрос кнопок анализирую время их удержания.
Фактически алгоритм выглядел так
1. Проверяем нажата ли хоть одна кнопка:
-прочитали байт из порта к которому подключены кнопки
-проверим по маске нажата ли хоть одна кнопка
—если не нажата — то счетчик удержания нажатия кнопки =0, и идем на выход из подпрограммы
2. если хоть одна кнопка нажата то:
— запоминаем состояние порта (битовую конфигурацию нажатых и не нажатых кнопок)
— увеличиваем счетчик проверки удержания кнопки.
3. Если счетчик удержания кнопки достиг некоторого порогового значения — то выставляем флаг того что кнопка нажата и сбрасываем счетчик удержания.
В принципе работал этот принцип примерно так же как работает клавиатура на компьютере: при нажатии на кнопку происходит замер длительности нажатия для устранения дребезга, и если кнопка какое то время не отпускалась то генерируется нажатие, далее по истечении еще какого то промежутка времени, если кнопка не отпускалась то нажатие генерируется снова…
удобно? — тогда показалось что вполне !
драйвер кнопок с таким алгоритмом и был реализован в прошивке VCoder
Но прошло некоторое время и это решение показало себя не очень удобным.
Например, нажатие на кнопку @MENU@ приводит к переходу в меню настроек аппаратуры, а в самом меню к переходу по выбранному пункту меню.. и пользователь аппаратуры зачастую чуть передержав кнопку @MENU@ входил не только в меню, но и в первый его пункт (обычно это был пункт RESET MODEL — который сбрасывал все настройки модели !)
Сначала проблему решали полумерами в виде внедрения диалога проверки в пункт RESET MODEL (требовалось ответить YES для сброса), пункт YES конечно же располагался у кнопки @MENU@…
Потом этот пункт переместили на кнопку @EXIT@, а пункт отказа от сброса (NO) разместили у кнопки @MENU@…
но ясности и простоты это не добавило, всегда находился пользователь который перепутал бы нажимаемые кнопки, либо не вчитывался особо в написанное и все таки сбрасывал настроенную модель…
постепенно пользователи привыкли, однако думаю что моя икота иногда вызывается гневом именно пользователей прошивки Vcoder при работе их с кнопкой @MENU@
Через какое то время я начал писать еще одну прошивку (A-Coder) и тогда решил что с этим нужно что то делать — негоже иметь такие ляпы в такой казалось бы простой задачке как опрос кнопок управления.
И придумался мне следующий функционал:
Должны быть кнопки которые при нажатии генерируют автоповтор (после нажатия и удержания кнопки генерируется повторяющееся коды нажатой кнопки), а должны быть те кто не генерируют (то есть при нажатии и удержании кнопки генерируется только одно нажатие, и повторного, сколько бы мы кнопку не удерживали — не будет)
Первый режим (автоповтор при удержании) я назвал push\hold, второй режим, при котором нажатие генерируется только один раз, независимо от времени удержания — push\up
Этот функционал реализовывался несколько раз и алгоритм каждый раз мне нравился все больше и больше 🙂
предлагаю вам текст этой подпрограммы для использования в ваших проектах
конфигурация подключения кнопок:
PIN_MN_KEY — порт PINx к которому
подключены кнопки, все кнопки управления должны быть подключены к одному
порту, но не обязательно к пинам порта идущим подрядMN_KEY_MASK — битовая маска кнопок порта (соответствующие биты кнопок установлены в «1»)
MN_KEY_UP, MN_KEY_DN, MN_KEY_LF, MN_KEY_RG — номера бит к которым подключены кнопки, внимание в константах именно номера бит!!
COUNTER — переменная в DSEG: счетчик
интервалов, от 20 до 100 гц (в принципе любой частоты, изменяется в
пределах 0..255 циклически)
- KR1_KEY_MASK — входной параметр: маска кнопок которые опрашиваются в режиме push\hold
- KR1_KEY_READ — выходной параметр: зарегистрированный код нажатой кнопки (выходная переменная модуля !)
- KR1_OLD_KEY — временно хранимый код нажатой кнопки
- KR1_PH_ONTIME — количество циклов вызова для регистрации кнопки в режиме push\hold
- KR1_PU_ONTIME — количество циклов вызова для регистрации кнопки в режиме push\up
- KR1_PU_WAIT — вспомогательная переменная, флаг того что кнопка в режиме push\hold еще не отпускалась
; key_reader.asm — модуль чтения нажатых кнопок меню
.equ COUNTER = T1_COUNTER ; имя переменной-счетчика в DSEG
KEY_READER: ; прочитаем состояние кнопок
IN R16 , PIN_MN_KEY
ANDI R16 , MN_KEY_MASK ; маска кнопок меню
; проверим нажата ли хоть одна кнопка
CPI R16 , (1<<MN_KEY_UP)|(1<<MN_KEY_DN)|(1<<MN_KEY_LF)|(1<<MN_KEY_RG)
BREQ KR1_EXIT ; ни одна из кнопок не нажата, идем на выход
; зарегистрировано нажатие какой-то кнопки
LDS R17 , KR1_OLD_KEY ; нажатые кнопки в прошлый период
CP R16 , R17 ; сравним текущие и старые нажатые кнопки
BREQ KR1_TIMER_LIST ; кнопки удерживаются — проверим время
; нажатые кнопки сейчас и нажатые ранее кнопки — отличаются
STS KR1_OLD_KEY , R16 ; сохраним нажатые кнопки
LDS R16 , COUNTER
STS KR1_KEY_COUNTER , R16 ; сохраним момент нажатия
RJMP KR1_END ; идем на выход
KR1_TIMER_LIST: ; кнопка нажата и удерживается, проверим достаточное ли времени прошло для
; регистрации нажатия в обоих режимах сканирования клавиатуры
KR1_TIMER_PH_LIST: ; режим push\hold
; проверка достаточности нажатия в режиме push\hold
MOV R15 , R16 ; сохраним нажатые кнопки меню
LDS R17 , KR1_KEY_MASK ; прочитаем маску чтения push\hold
AND R16 , R17 ; наложим маску
CP R16 , R17 ; есть кнопки нажатые для этого режима?
BREQ KR1_TIMER_PU_LIST ; перейдем к проверке нажатых кнопок в режиме
; push\up
; у нас нажаты кнопки в режиме push\hold
LDS R16 , COUNTER ; загрузим текущий счетчик
LDS R17 , KR1_KEY_COUNTER ; загрузим счетчик когда было зарегистрировано
; нажатие кнопок
SUB R16 , R17 ; определим время нажатия
LDS R17 , KR1_PH_ONTIME ; берем необходимую длительность нажатия
CP R16 , R17
BRLO KR1_TIMER_PH_LIST_NO ; кнопка удерживается недостаточное время, выходим
KR1_REG_KEY_PRESS: ; кнопка удерживается достаточное время, зарегистрируем нажатие
STS KR1_KEY_READ , R15 ; сохраним нажатые кнопки
LDI R16 , (1<<MN_KEY_UP)|(1<<MN_KEY_DN)|(1<<MN_KEY_LF)|(1<<MN_KEY_RG)
STS KR1_OLD_KEY , R16 ; сбросим временный код нажатых кнопок
RJMP KR1_END ; идем на выход
KR1_TIMER_PU_LIST: ; режим push\up
LDS R16 , KR1_PU_WAIT ; проверим не ожидаем ли мы отпускания кнопок
CPI R16 , 1 ; меню после регистрации нажатия
BREQ KR1_PROC_WAIT ; выходим ожидая отпускания кнопок
; проверим нужное время ли удерживается кнопка
LDS R16 , COUNTER ; загрузим текущий счетчик
LDS R17 , KR1_KEY_COUNTER ; загрузим счетчик когда было зарегистрировано
; нажатие кнопок
SUB R16 , R17 ; определим время нажатия
LDS R17 , KR1_PU_ONTIME ; берем необходимую длительность нажатия
CP R16 , R17
BRLO KR1_TIMER_PH_LIST_NO ; кнопка удерживается недостаточное время, выходим
; кнопка удерживается достаточное время установим флаг ожидания отпускания
LDI R16 , 1
STS KR1_PU_WAIT , R16
RJMP KR1_REG_KEY_PRESS ; и зарегистрируем нажатие кнопки
KR1_EXIT: ; выход, по отпусканию кнопок
STS KR1_OLD_KEY , R16 ; сбросим временные нажатые кнопки
LDI R16 , 0
STS KR1_PU_WAIT , R16 ; сбросим флаг ожидания отпускания (уже отпустили)
; для режима push\up
KR1_END: ; выход
KR1_TIMER_PH_LIST_NO: ; выходим по недостаточному времени удержания кнопок
KR1_PROC_WAIT: ; ожидаем отпускание нажатых кнопок в режиме push\up
RET
И следом идет процедура которая считывает код кнопок нажатие которых было зарегистрировано
GET_KEY: ; функция чтения считанной кнопки
PUSH R17
LDS R16 , KR1_KEY_READ
LDI R17 , (1<<MN_KEY_UP)|(1<<MN_KEY_DN)|(1<<MN_KEY_LF)|(1<<MN_KEY_RG)
STS KR1_KEY_READ , R17
POP R17
RET
Файл драйвера на языке ассемблера можно скачать здесь -> http://vg.ucoz.ru/load/iskhodnye_teksty_programm_na_assemblere_avr/drajver_knopok_ustrojstva/4-1-0-8Подключение кнопки к микроконтроллеру | RadioLaba.ru
Кнопку к микроконтроллеру можно подключить двумя основными способами, с подтяжкой линии порта к высокому логическому уровню или низкому через резистор, как показано на картинке ниже.
Я обычно использую первый вариант подключения, можно конечно использовать внутренние подтягивающие резисторы на входах PORTB, но мне еще не доводилось применять такой способ.
В простейшем варианте микроконтроллер все время опрашивает одну или несколько кнопок, при нажатии которых выполняет соответствующую подпрограмму и снова возвращается на опрос кнопок. Подпрограмма обычно выполняется очень быстро, естественно за это время можно не успеть отжать кнопку, вследствие чего подпрограмма выполнится многократно. Чтобы этого не происходило после обнаружения нажатой кнопки необходимо добавить проверку отжатого состояния, но и в этом случае из-за явления дребезга контактов выполнение подпрограммы может начаться до отжатия кнопки. Поэтому после обнаружения нажатой кнопки необходимо добавить временную задержку в 5-20 мс. Проверка отжатого состояния будет многократно выполняться через заданный интервал времени. После обнаружения отжатия выполниться соответствующая подпрограмма, после чего опрос кнопок будет продолжен, но и здесь дребезг после отжатия может еще продолжаться, поэтому можно добавить паузу также перед опросом нажатого состояния кнопки. Я обычно этого не делаю, достаточно паузы во время опроса отжатого состояния кнопки. В итоге у нас получается примерно такой код:
; oproskn1 btfsc knp1 ;опрос 1-ой кнопки goto oproskn2 ;1-ая кнопка не нажата: переход на опрос 2-ой кнопки kn1 call pausknp ;1-ая кнопка нажата: вызов паузы (5-20мс), btfss knp1 ;опрос 1-ой кнопки goto kn1 ;1-ая кнопка не отжата: переход на метку kn1 call program1 ;1-ая кнопка отжата: вызов подпрограммы program1 oproskn2 btfsc knp2 ;опрос 2-ой кнопки goto oproskn1 ;2-ая кнопка не нажата: переход на опрос 1-ой кнопки kn2 call pausknp ;2-ая кнопка нажата: вызов паузы (5-20мс) btfss knp2 ;опрос 2-ой кнопки goto kn2 ;2-ая кнопка не отжата: переход на метку kn2 call program2 ;2-ая кнопка отжата: вызов подпрограммы program2 goto oproskn1 ;переход на метку oproskn1 ;
; oproskn1 btfsc knp1 ;опрос 1-ой кнопки goto oproskn2 ;1-ая кнопка не нажата: переход на опрос 2-ой кнопки kn1 call pausknp ;1-ая кнопка нажата: вызов паузы (5-20мс), btfss knp1 ;опрос 1-ой кнопки goto kn1 ;1-ая кнопка не отжата: переход на метку kn1 call program1 ;1-ая кнопка отжата: вызов подпрограммы program1
oproskn2 btfsc knp2 ;опрос 2-ой кнопки goto oproskn1 ;2-ая кнопка не нажата: переход на опрос 1-ой кнопки kn2 call pausknp ;2-ая кнопка нажата: вызов паузы (5-20мс) btfss knp2 ;опрос 2-ой кнопки goto kn2 ;2-ая кнопка не отжата: переход на метку kn2 call program2 ;2-ая кнопка отжата: вызов подпрограммы program2 goto oproskn1 ;переход на метку oproskn1 ; |
Бывает нужно, чтобы кнопка имела две функции, на короткое и длительное нажатие. В этом случае во время опроса отжатого состояния необходимо добавить таймер времени. После обнаружения нажатого состояния записываем в дополнительный регистр число и уходим на паузу, после возврата декрементируем значение регистра и снова опрашиваем кнопку на предмет отжатого состояния. Этот цикл продолжается до тех пор, пока не отожмется кнопка или значение регистра не станет равным нулю. При обнаружении отжатого состояния до обнуления регистра, выполняется подпрограмма program1, при обнулении выполнится подпрограмма program2. Например, необходимо задать продолжительность длительного нажатия в 1 секунду, а пауза равна 10 мс, тогда в регистр счетчика надо записать число 100.
А если удерживать кнопку в течении 3 секунд, тогда подпрограмма program2 выполнится несколько раз, чтобы избежать этого в конце этой подпрограммы перед возвратом или после возврата нужно добавить опрос отжатого состояния кнопки. Ниже представлен код программы, где кнопка knp1 имеет 2 функции:
;кнопка knp1 имеет 2 функции: на короткое и длительное нажатие ;кнопка knp2 имеет одну функцию на короткое нажатие oproskn1 btfsc knp1 ;опрос 1-ой кнопки goto oproskn2 ;1-ая кнопка не нажата: переход на опрос 2-ой кнопки movlw .100 ;1-ая кнопка нажата: запись числа 100 в регистр shet movwf shet kn1 call pausknp ;вызов паузы (5-20мс) btfsc knp1 ;опрос 1-ой кнопки goto prog1 ;1-ая кнопка отжата: переход на метку prog1 decfsz shet,F ;1-ая кнопка не отжата: декремент регистра shet goto kn1 ;значение регистра не равно 0: переход на метку kn1 call program2 ;значение регистра равно 0: вызов подпрограммы program2 kn11 call pausknp ;вызов паузы (5-20мс) btfss knp1 ;опрос 1-ой кнопки goto kn11 ;1-ая кнопка не отжата: переход на метку kn11, ;ждем отжатия кнопки goto oproskn2 ;1-ая кнопка отжата: переход на метку oproskn2 prog1 call program1 ;вызов подпрограммы program1 oproskn2 btfsc knp2 ;опрос 2-ой кнопки goto oproskn1 ;2-ая кнопка не нажата: переход на опрос 1-ой кнопки kn2 call pausknp ;2-ая кнопка нажата: вызов паузы (5-20мс) btfss knp2 ;опрос 2-ой кнопки goto kn2 ;2-ая кнопка не отжата: переход на метку kn2 call program3 ;2-ая кнопка отжата: вызов подпрограммы program3 goto oproskn1 ;переход на метку oproskn1 ;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | ;кнопка knp1 имеет 2 функции: на короткое и длительное нажатие ;кнопка knp2 имеет одну функцию на короткое нажатие
oproskn1 btfsc knp1 ;опрос 1-ой кнопки goto oproskn2 ;1-ая кнопка не нажата: переход на опрос 2-ой кнопки movlw .100 ;1-ая кнопка нажата: запись числа 100 в регистр shet movwf shet kn1 call pausknp ;вызов паузы (5-20мс) btfsc knp1 ;опрос 1-ой кнопки goto prog1 ;1-ая кнопка отжата: переход на метку prog1 decfsz shet,F ;1-ая кнопка не отжата: декремент регистра shet goto kn1 ;значение регистра не равно 0: переход на метку kn1 call program2 ;значение регистра равно 0: вызов подпрограммы program2 kn11 call pausknp ;вызов паузы (5-20мс) btfss knp1 ;опрос 1-ой кнопки goto kn11 ;1-ая кнопка не отжата: переход на метку kn11, ;ждем отжатия кнопки goto oproskn2 ;1-ая кнопка отжата: переход на метку oproskn2
prog1 call program1 ;вызов подпрограммы program1
oproskn2 btfsc knp2 ;опрос 2-ой кнопки goto oproskn1 ;2-ая кнопка не нажата: переход на опрос 1-ой кнопки kn2 call pausknp ;2-ая кнопка нажата: вызов паузы (5-20мс) btfss knp2 ;опрос 2-ой кнопки goto kn2 ;2-ая кнопка не отжата: переход на метку kn2 call program3 ;2-ая кнопка отжата: вызов подпрограммы program3 goto oproskn1 ;переход на метку oproskn1 ; |
Возможно такое что, кнопка knp1используется внутри самой подпрограммы program2, в этом случае перед ее опросом внутри подпрограммы вначале также следует дождаться отжатия кнопки.
Иногда необходимо чтобы при однократном нажатии кнопки, подпрограмма выполнилась один раз, а при удерживании выполнялась многократно, например, ускоренное приращение числа на цифровом табло. Такую функцию можно реализовать очень просто, необходимо лишь исключить опрос отжатого состояния кнопки. Но здесь имеются свои недостатки, пропадает “дискретность” выполнения подпрограммы, ведь за одно кратковременное нажатие подпрограмма может выполниться несколько раз в зависимости от длительности нажатия, а нам требуется однократное выполнение. Данную функцию можно реализовать на основе предыдущего примера, немного изменив код. После длительного нажатия и выполнения подпрограммы, уходим на паузу, далее однократно выполняем проверку отжатого состояния (а не дожидаемся, пока отпустят кнопку), после чего при условии нажатой кнопки снова выполняем подпрограмму. Этот цикл будет продолжаться пока не отпустят кнопку. Здесь пауза будет определять скорость вызова подпрограммы (скорость приращения числа на цифровом табло). В итоге сохраняется “дискретность”, совместно с ускоренным многократным выполнением подпрограммы при удержании кнопки. Код программы выглядит следующим образом:
;кнопка knp1 имеет 2 функции: на короткое и длительное нажатие с многократным ускоренным ;выполнением подпрограммы program1 ;кнопка knp2 имеет одну функцию на короткое нажатие oproskn1 btfsc knp1 ;опрос 1-ой кнопки goto oproskn2 ;1-ая кнопка не нажата: переход на опрос 2-ой кнопки movlw .100 ;1-ая кнопка нажата: запись числа 100 в регистр shet movwf shet kn1 call pausknp ;вызов паузы (5-20мс) btfsc knp1 ;опрос 1-ой кнопки goto prog1 ;1-ая кнопка отжата: переход на метку prog1 decfsz shet,F ;1-ая кнопка не отжата: декремент регистра shet goto kn1 ;значение регистра не равно 0: переход на метку kn1 kn11 call program1 ;значение регистра равно 0: вызов подпрограммы program1 call pause ;вызов паузы (скорость вызова подпрограммы program1) btfsc knp1 ;опрос 1-ой кнопки goto oproskn2 ;1-ая кнопка отжата: переход на метку oproskn2 goto kn11 ;1-ая кнопка не отжата: переход на метку kn11 для ;повторного выполнения подпрограммы program1 prog1 call program1 ;вызов подпрограммы program1 oproskn2 btfsc knp2 ;опрос 2-ой кнопки goto oproskn1 ;2-ая кнопка не нажата: переход на опрос 1-ой кнопки kn2 call pausknp ;2-ая кнопка нажата: вызов паузы (5-20мс) btfss knp2 ;опрос 2-ой кнопки goto kn2 ;2-ая кнопка не отжата: переход на метку kn2 call program2 ;2-ая кнопка отжата: вызов подпрограммы program3 goto oproskn1 ;переход на метку oproskn1 ;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | ;кнопка knp1 имеет 2 функции: на короткое и длительное нажатие с многократным ускоренным ;выполнением подпрограммы program1 ;кнопка knp2 имеет одну функцию на короткое нажатие
oproskn1 btfsc knp1 ;опрос 1-ой кнопки goto oproskn2 ;1-ая кнопка не нажата: переход на опрос 2-ой кнопки movlw .100 ;1-ая кнопка нажата: запись числа 100 в регистр shet movwf shet kn1 call pausknp ;вызов паузы (5-20мс) btfsc knp1 ;опрос 1-ой кнопки goto prog1 ;1-ая кнопка отжата: переход на метку prog1 decfsz shet,F ;1-ая кнопка не отжата: декремент регистра shet goto kn1 ;значение регистра не равно 0: переход на метку kn1 kn11 call program1 ;значение регистра равно 0: вызов подпрограммы program1 call pause ;вызов паузы (скорость вызова подпрограммы program1) btfsc knp1 ;опрос 1-ой кнопки goto oproskn2 ;1-ая кнопка отжата: переход на метку oproskn2 goto kn11 ;1-ая кнопка не отжата: переход на метку kn11 для ;повторного выполнения подпрограммы program1
prog1 call program1 ;вызов подпрограммы program1
oproskn2 btfsc knp2 ;опрос 2-ой кнопки goto oproskn1 ;2-ая кнопка не нажата: переход на опрос 1-ой кнопки kn2 call pausknp ;2-ая кнопка нажата: вызов паузы (5-20мс) btfss knp2 ;опрос 2-ой кнопки goto kn2 ;2-ая кнопка не отжата: переход на метку kn2 call program2 ;2-ая кнопка отжата: вызов подпрограммы program3 goto oproskn1 ;переход на метку oproskn1 ; |
А теперь рассмотрим случай, когда микроконтроллер непрерывно выполняет какие-либо задачи, в этом случае ожидать отжатие кнопки недопустимо. Здесь можно воспользоваться прерываниями по изменению уровня на входах RB4-RB7 или по входу внешнего прерывания INT.
Для прерываний по входам RB4-RB7 алгоритм следующий: при изменении сигнала с 1 на 0 происходит переход в подпрограмму обработчика прерываний, где необходимо сначала определить, что вызвало прерывание, когда имеется несколько источников прерываний. Когда источник определен, необходимо выяснить на каком именно входе изменился уровень сигнала, определив его, выполняем соответствующие операции внутри самого обработчика прерываний, либо устанавливаем флаг в регистре, который специально выделяем для этих целей. Далее необходимо считать регистр PORTB, для устранения несоответствия ранее сохраненного значения с сигналом на входах порта, иначе флаг прерывания сбросить не удастся. После сброса флага выходим из обработчика прерывания.
Специально выделенный регистр с флагами проверяем в цикле основной программы, где по установленному флагу выполняем какую-либо подпрограмму, после чего сбрасываем флаг.
Опять же из-за дребезга контактов при таком алгоритме прерывания могут генерироваться многократно, добавлять паузу на время дребезга внутри обработчика прерываний бессмысленно, так как теряется процессорное время необходимое для выполнения других задач.
Также в данном алгоритме не учтено повторное возникновение прерывания при отжатии кнопки, смена сигнала с 0 на 1, ведь прерывания по входам RB4-RB7 возникают по переднему и заднему фронту сигнала. Но здесь все просто, одно прерывание можно пропустить, выполняя соответствующие операции только при наличии 0 на входе.
Решить проблему дребезга можно с помощью таймера. После перехода в подпрограмму обработчика прерываний, при смене сигнала с 1 на 0, запрещаем прерывания по входам RB4-RB7, определяем вход, где изменился сигнал, устанавливаем флаг в специально выделенном регистре, запускаем таймер на 5-20 мс и выходим из подпрограммы прерывания. Через установленный промежуток времени, по переполнению таймера возвращаемся в обработчик прерываний, останавливаем таймер, сбрасываем флаг по переполнению, считываем PORTB для устранения несоответствия, сбрасываем флаг и разрешаем прерывания по входам RB4-RB7. При повторном возникновении прерывания в результате отжатия кнопки, весь процесс повторится, за исключением того что, пропускаем выполнение соответствующих операций, так как сигнал на входе равен 1. Код программы представлен ниже:
;предварительно при начальной настройке регистров специального назначения необходимо сбросить ;флаг по переполнению TMR1, флаг прерывания по входам RB4-RB7 ;разрешить прерывание по переполнению TMR1, а также прерывания по входам RB4-RB7 ;регистр flag с флагами кнопок опрашиваем в теле основной программе, не забывая их сбросить org 0004h ;начать выполнение подпрограммы с адреса 0004h btfss PIR1,TMR1IF ;опрос флага прерываний по переполнению TMR1 goto metka1 ;флаг не установлен: переход на метку metka1 — опрос ;других источников прерываний bcf T1CON,TMR1ON ;флаг установлен: остановка таймера TMR1 bcf PIR1,TMR1IF ;сброс флага прерывания по переполнению TMR1 movf PORTB,W ;считывание значения PORTB для устранения несоответствия bcf INTCON,RBIF ;сброс флага прерывания по входам RB4-RB7 bsf INTCON,RBIE ;разрешение прерывания по входам RB4-RB7 retfie ;выход из обработчика прерываний metka1 btfss INCON,RBIF ;опрос флага прерываний по входам RB4-RB7 goto metka2 ;флаг не установлен: переход на метку metka2 — опрос ;других источников прерываний bcf INTCON,RBIE ;флаг установлен: запрет на прерывания по входам RB4-RB7 btfss PORTB,4 ;опрос линии RB4 bsf flag,0 ;0 на линии RB4: установка флага для линии RB4 btfss PORTB,5 ;1 на линии RB4: опрос линии RB5 bsf flag,1 ;0 на линии RB5: установка флага для линии RB5 btfss PORTB,6 ;1 на линии RB5: опрос линии RB6 bsf flag,2 ;0 на линии RB6: установка флага для линии RB6 btfss PORTB,7 ;1 на линии RB6: опрос линии RB7 bsf flag,3 ;0 на линии RB7: установка флага для линии RB7 movlw .224 ;запись числа 45536 в таймер TMR1, пауза 20мс, movwf TMR1L ;частота тактового генератора 4 МГц, movlw .177 ;коэффициент предделителя TMR1 заранее установлен 1:1 movwf TMR1H bsf T1CON,TMR1ON ;включение таймера TMR1 retfie ;выход из обработчика прерываний metka2 …………….. ;опрос других источников прерываний …………….. …………….. retfie ;выход из обработчика прерываний ;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | ;предварительно при начальной настройке регистров специального назначения необходимо сбросить ;флаг по переполнению TMR1, флаг прерывания по входам RB4-RB7 ;разрешить прерывание по переполнению TMR1, а также прерывания по входам RB4-RB7 ;регистр flag с флагами кнопок опрашиваем в теле основной программе, не забывая их сбросить
org 0004h ;начать выполнение подпрограммы с адреса 0004h
btfss PIR1,TMR1IF ;опрос флага прерываний по переполнению TMR1 goto metka1 ;флаг не установлен: переход на метку metka1 — опрос ;других источников прерываний bcf T1CON,TMR1ON ;флаг установлен: остановка таймера TMR1 bcf PIR1,TMR1IF ;сброс флага прерывания по переполнению TMR1 movf PORTB,W ;считывание значения PORTB для устранения несоответствия bcf INTCON,RBIF ;сброс флага прерывания по входам RB4-RB7 bsf INTCON,RBIE ;разрешение прерывания по входам RB4-RB7 retfie ;выход из обработчика прерываний
metka1 btfss INCON,RBIF ;опрос флага прерываний по входам RB4-RB7 goto metka2 ;флаг не установлен: переход на метку metka2 — опрос ;других источников прерываний bcf INTCON,RBIE ;флаг установлен: запрет на прерывания по входам RB4-RB7 btfss PORTB,4 ;опрос линии RB4 bsf flag,0 ;0 на линии RB4: установка флага для линии RB4 btfss PORTB,5 ;1 на линии RB4: опрос линии RB5 bsf flag,1 ;0 на линии RB5: установка флага для линии RB5 btfss PORTB,6 ;1 на линии RB5: опрос линии RB6 bsf flag,2 ;0 на линии RB6: установка флага для линии RB6 btfss PORTB,7 ;1 на линии RB6: опрос линии RB7 bsf flag,3 ;0 на линии RB7: установка флага для линии RB7 movlw .224 ;запись числа 45536 в таймер TMR1, пауза 20мс, movwf TMR1L ;частота тактового генератора 4 МГц, movlw .177 ;коэффициент предделителя TMR1 заранее установлен 1:1 movwf TMR1H bsf T1CON,TMR1ON ;включение таймера TMR1 retfie ;выход из обработчика прерываний
metka2 …………….. ;опрос других источников прерываний …………….. ……………..
retfie ;выход из обработчика прерываний ; |
Честно говоря, такую конструкцию я не применял, не нравится мне все это дело. Вешать кнопки на прерывания лучше всего для пробуждения микроконтроллера из спящего режима.
Гораздо проще и надежнее поместить код опроса кнопок в цикле основной программы, в то место где они будут опрашиваться хотя бы через каждые 100 мс, по мере выполнения других задач. Для предотвращения многократного выполнения подпрограммы при длительном нажатии на кнопку нужно использовать дополнительный регистр с флагами контроля состояния кнопок. Если во время очередного опроса в цикле основной программы кнопка окажется не нажатой, то устанавливаем в 1 соответствующий флаг регистра. При обнаружении нажатия сначала проверяем флаг, если он равен 1, сбрасываем его и выполняем подпрограмму, после чего идем на опрос второй кнопки или далее по циклу основной программы.
При следующем опросе флаг будет равен 0, ничего не делаем, идем также на опрос второй кнопки, или далее по циклу не задерживаясь. Такой пропуск будет происходить до тех пор, пока не отожмем кнопку и флаг снова не установиться в 1. Код выглядит следующим образом:
……………. ……………. ;код основной программы ……………. oproskn1 btfss knp1 ;опрос 1-ой кнопки goto kn1 ;1-ая кнопка нажата: переход на метку kn1 bsf flag,0 ;1-ая кнопка не нажата: устанавливаем флаг 1-ой кнопки goto oproskn2 ;переход на метку oproskn2 kn1 btfss flag,0 ;опрос флага состояния 1-ой кнопки goto oproskn2 ;флаг 1-ой кнопки не установлен: переход на метку oproskn2 bcf flag,0 ;сброс флага состояния 1-ой кнопки call program1 ;вызов подпрограммы program1 oproskn2 btfss knp1 ;опрос 2-ой кнопки goto kn2 ;1-ая кнопка нажата: переход на метку kn1 bsf flag,1 ;1-ая кнопка не нажата: устанавливаем флаг 2-ой кнопки goto metka1 ;переход на метку metka1 kn2 btfss flag,1 ;опрос флага состояния 2-ой кнопк goto metka1 ;флаг 2-ой кнопки не установлен: переход на метку metka1 bcf flag,1 ;сброс флага состояния 2-ой кнопки call program2 ;вызов подпрограммы program2 metka1 …………….. ;дальнейшее исполнение основной программы …………….. ……………..
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | ……………. ……………. ;код основной программы …………….
oproskn1 btfss knp1 ;опрос 1-ой кнопки goto kn1 ;1-ая кнопка нажата: переход на метку kn1 bsf flag,0 ;1-ая кнопка не нажата: устанавливаем флаг 1-ой кнопки goto oproskn2 ;переход на метку oproskn2 kn1 btfss flag,0 ;опрос флага состояния 1-ой кнопки goto oproskn2 ;флаг 1-ой кнопки не установлен: переход на метку oproskn2 bcf flag,0 ;сброс флага состояния 1-ой кнопки call program1 ;вызов подпрограммы program1
oproskn2 btfss knp1 ;опрос 2-ой кнопки goto kn2 ;1-ая кнопка нажата: переход на метку kn1 bsf flag,1 ;1-ая кнопка не нажата: устанавливаем флаг 2-ой кнопки goto metka1 ;переход на метку metka1 kn2 btfss flag,1 ;опрос флага состояния 2-ой кнопк goto metka1 ;флаг 2-ой кнопки не установлен: переход на метку metka1 bcf flag,1 ;сброс флага состояния 2-ой кнопки call program2 ;вызов подпрограммы program2
metka1 …………….. ;дальнейшее исполнение основной программы …………….. …………….. |
Как видно все очень просто, не нужно никаких прерываний и таймеров.
Справочник по программированию «Bascom-AVR» (М.Л. Кулиш)
===================================== Справочник по программированию «Bascom-AVR» ==
‘ | ———————————————————— |
|
|
|
| ‘ШЕСТНАДЦАТИРИЧНЫЕ ЦИФРЫ |
|
|
| |||||
Tabseg0: |
|
|
|
|
|
| ||||||||
&HC0 |
| , &HF9 |
|
|
| ‘ 0 , 1 | -d0 — |
| ||||||
| Data |
|
|
|
| I | ||||||||
| Data | &HA4 |
| , &HB0 |
|
|
| ‘ 2 , 3 I |
| |||||
| Data | &H99 |
| , &H92 |
|
|
| ‘ 4 , 5 D5 | D1 | |||||
| Data | &H82 |
| , &HF8 |
|
|
| ‘ 6 , 7 I | -d6 — | I | ||||
| Data | &H80 |
| , &H90 |
|
|
| ‘ 8 , 9 | I | |||||
| Data | &H88 |
| , &H83 |
|
|
| ‘ A , B I |
| |||||
| Data | &HC6 |
| , &HA1 |
|
|
| ‘ C , D D4 | D2 | |||||
| Data | &H86 |
| , &H8E |
|
|
| ‘ E , F I | -D3- | I | ||||
‘ |
|
|
|
|
|
|
|
|
| ‘ |
|
| [D7] | |
———————————————————————————- |
|
|
| программы клавиатуры |
|
|
|
| ||||||
‘ |
|
|
|
|
|
|
|
| ||||||
‘——————————————————— |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
‘ ————————————— | | |
|
|
|
| AVR-WATCH |
|
|
| | |
|
| ||
‘ |
|
|
|
|
|
|
|
|
| |||||
‘ ——————————— | | | | | — |
|
| — |
| — |
| — | | | | |
|
|
‘ | | | | | | | | | | | | |
|
| ||||||
‘ | | | | | | | | | | | | | |
|
| |||||||
‘ | | | | | — | | | | | — | | | — | | | — | | | | |
|
|
‘ | | | | | | | | | | | | | |
|
| |||||||
‘ | | | | | — |
| [] | — [] |
| — [] |
| — [] | | | |
|
| |
‘ ——————————— | | |
| 1 |
|
| 2 |
| 3 |
| 4 |
| | |
|
|
‘ | | |
|
|
|
|
|
| | |
|
| ||||
‘ | | |
| _ |
|
| _ |
| _ |
| _ |
| | |
|
|
‘ | | |
| |_| |
|
| |_| |
| |_| |
| |_| |
| | |
|
|
‘ | | |
| Reset |
| + |
| + |
| — |
| | |
|
| |
‘ | | |
|
|
|
|
| | |
|
| |||||
‘ | | |
| Min |
|
| Hour |
| Min |
| Min |
| | |
|
|
‘ ————————————— |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
‘выполнение программ обработки кнопок — основной список
‘0: пустой переход из-за того, что кнопки нумеруются с 1-й, а не с 0-й
‘1: Сбросить минуты 2: Добавить час 3: Добавить минуту 4: Убавить минуту
‘———————————————————
Программа обНазначение кнопок выбрано произвольно. Для перехода к программам обработки кнопок работки кнопок используется специальная функция On – Goto с индексированием списка меток. Дает быстрый и экономичный код. Применение функции Select Case не рекомендуется, так как не по-
зволяет вкладывать объемные конструкции.
W_klb:
On Buf_kl Goto Kn , Km1 , Km2 , Km3 , Km4
‘обработать нажатие кнопки |
|
‘——— |
|
Km1: | ‘сбросить минуты |
Rmin = 0 | |
If Rmin > 30 Then | ‘при необходимости округления |
Goto Km2 | ‘скорректировать счетчик минут |
End If |
|
Km1_1: | ‘поставить признак обновления индикации |
Ddat = 255 | |
Kn: |
|
Return |
|
‘——— |
|
Km2: | ‘плюс час |
Incr Rhour | |
If Rhour > 23 Then | ‘при необходимости |
Rhour = 0 | ‘скорректировать счетчик часов |
End If |
|
Goto Km1_1 |
|
‘——— |
|
Km3: | ‘плюс минута |
Incr Rmin | |
If Rmin > 59 Then | ‘при необходимости |
Rmin = 0 | ‘скорректировать счетчик минут |
End If |
|
Goto Km1_1 |
|
‘——— |
|
Km4: | ‘минус минута |
Decr Rmin | |
If Rmin = 255 Then | ‘при необходимости |
Rmin = 59 | ‘скорректировать счетчик минут |
End If |
|
Goto Km1_1 |
|
‘———————————————————————————- |
|
============================================================================= 11
===================================== Справочник по программированию «Bascom-AVR» ==
Первая версия программы готова, она полностью работоспособна, но функционально бедна. Структура программы во всех компонентах открыта для расширения функциональных возможностей. Определив набор добавляемых функций, следует выбрать путь реализации новых задач. Существует несколько подходов:
-простое добавление новых функций по имеющимся правилам работы программы. Этот путь пригоден для небольших добавлений, похожих на уже имеющиеся;
-добавление новых функций по другим правилам построения программы. Необходимость в этом возникает при создании многофункциональных систем и обычно решается создание других разделов с собственной структурой ГЦ;
-добавление сложных функций в виде отдельных модулей, содержащих все необходимые компоненты ввода и отображения данных. Это приемлемый вариант реализации небольшого количества функций при некритичном времени реагирования на внешние воздействия. Примером таких функций могут быть программы тестирования, сохранения данных, обработка протокола установления связи;
-создание новых функций посредством специальных инструментов – утилит. Утилиты – специальные программы, облегчающие реализацию часто повторяющихся операций. Использование утилит для расширения системы наиболее эффективно при реализации большого количества несложных и похожих функций. Рассмотрим примеры построения и применения утилит.
Этап 5. «Создание утилит для расширения функциональных возможностей». Задача этапа – создание набора стандартных программных модулей для выполнения элементарных операций.
Требуемый для расширения набор утилит определяется составом добавляемых функций. Выберем, например, следующий набор расширяемых режимов:
-выбор с помощью меню;
-многофункциональная клавиатура;
-отображение текстовых сообщений.
Для этого нам понадобятся следующие утилиты:
-вывод указанного текстового сообщения на индикатор, например, с помощью индекса;
-останов на фиксированное время с ожиданием нажатия кнопки.
При добавлении этих утилит прошлось расширить список используемых переменных и функций прерывания реального времени. Все изменения в программе можно наблюдать в полном измененном тексте, который будет приведен дальше.
Этап 6. «Расширение функциональных возможностей с помощью утилит».
В программу версии 2 добавлено:
-несколько новых переменных для обеспечения работы новых систем;
-расширена функция программы прерывания таймера 0. Добавлена ветка формирования временных интервалов 64 мс и проверка запрета звукового сигнала;
-расширена функция программы формирования изображения;
-добавлен и выделен отдельно раздел утилит (вспомогательных универсальных программ формирования изображения и управления). Там же расположены расширенные таблицы кодов сегментов и сообщений;
-добавлено начальное сообщение;
-изменены и добавлены функции клавиатуры. Функции, конечно, надуманные, но это демонстрационная программа. Показан один из основных механизмов создания многофункциональной клавиатуры;
-добавлены программы коррекции монтажа индикатора и клавиатуры (при отклонении фактической разводки от теоретической модели.
И так, программа работает и обеспечивает все требуемые режимы работы. Однако работа не закончена. Необходимо привести ее в порядок. Имеется в виду введение последних непринципиальных улучшений и подготовка исходного текста к дальнейшей модернизации, возможно даже, через продолжительное время. Все это можно назвать этапом оптимизации.
Этап 7. «Оптимизация программы».
Прагматичный (лишь бы работало) стиль программирования часто оказывается, безответственным. Практика показывает, что встроенное программное обеспечение часто подвергается доработке в процессе производства и даже эксплуатации. Законченный программный проект в той или иной степени должен удовлетворять возможности дальнейшей доработки или, в крайней случае, должен быть пригоден для заимствования его частей для других проектов. Что нужно для этого сделать? Следующее:
-просмотреть текст программы и одинаковые участки, даже если это всего одна строка, попытаться оформить в качестве отдельной подпрограммы. В приведенной программе такие примеры имеются;
-попробовать свести к одной подпрограмме похожие участки программы, сделав, например, несколько входов с различными параметрами и промежуточное преобразование;
-устранить слишком длинные участки программ, оформив их как функционально законченную подпрограмму. В первую очередь это относится к вычислительным программам;
============================================================================= 12
===================================== Справочник по программированию «Bascom-AVR» ==
-провести подробное комментирование программы. Особенно тщательно описывая, протоколы, форматы данных, условия принятия решение, обязательно применительно к тем физическим процессам, с которыми взаимодействует программа;
-в максимальной степени представить применяемые цифровые константы в символьном виде. Их определение вынести в заголовки и указать их назначение;
-обязательно указать номер версии продукта, разницу в версиях (историю доработок), дату создания (компиляции), версию и тип компилятора.
После оптимизации (и в процессе тоже) необходимо провести повторную компиляцию и проверку функционирования.
ПРОГРАММА 4
Вторая версия программы Содержит все добавления.
‘——————————————
‘ Программа «AVR-WATCH» (версия 2)
‘—————————————— |
| типа ATMEGA8 | |
‘ Микроконтроллер | |||
‘—————————————— |
| Fuses: |
|
‘ Программируемые | — низкочастотный кварцевый резонатор | ||
‘ CKSEL3… | CKSEL0 | = 1001 |
‘CKOPT=0 — внутренние конденсаторы подключены к кварцевому резонатору
‘RSTDISBL=1 — порт PC6 используется как сброс
‘WDTON=1 — сторожевой таймер разрешен
‘SPIEN=0 — последовательное программирование разрешено
‘BOOTSZ1,BOOTSZ0 = 00, BOOTRST=1 — параметры загрузчика
‘EESAVE = 1 — НЕ ОЧИЩАТЬ EEPROM при программировании
‘BODLEVEL=1, BODEN=1 — ПАРАМЕТРЫ СБРОСА
‘SUT1=1,SUT1=0 — ВРЕМЯ СТАРТА
‘——————————————
‘Ресурсы:
‘Генератор RC — внутренний 1 МГц, а к TOSC1 and TOSC2 подключен кристалл 32768 Гц
‘На выходе PB3 (OC2) импульсы длительностью 1 с (0.5 Гц)
‘На выходе PB1 (OC1A) звуковой сигнал
‘Порт Portd выход сегментов
‘ Portc0… | Portc3 — код знакоместа (позиционный) он же порт сканирования клавиатуры | |
‘ Четыре кнопки: Port0… | Portc3 — код сканирования клавиатуры, Portc4 — линия возврата клавиатуры | |
‘—————————————— |
| ‘определить тип микроконтроллера |
$regfile = «m8def.dat» | ||
‘—————————————— |
| ‘признак «обновить данные» |
Dim Ndat As Byte | ||
Dim Ddat As Byte | ‘признак «обновить индикатор» | |
‘——————— |
| ‘режим отображения: 0 — ЧЧММ, 1 — ММСС, 2 — погашен |
Dim Mdisp As Byte | ||
Dim Msnd As Byte | ‘режим звука: 0 — включен, <>0 — выключен | |
‘——————— |
| ‘программный счетчик времени |
Dim S_tim As Byte | ||
Dim W_tim As Byte | ‘счетчик времени задержек | |
Dim R_btim As Byte | ‘счетчик времени звонка | |
‘——————— |
| ‘счетчик секунд |
Dim Rsec As Byte | ||
Dim Rmin As Byte | ‘счетчик минут | |
Dim Rhour As Byte | ‘счетчик часов | |
‘——————— |
| ‘код нажатой кнопки |
Dim Buf_kl As Byte | ||
Dim Buf_pkl As Byte | ‘предварительный код нажатой кнопки | |
Dim R_ckl As Byte | ‘счетчик удержания клавиатуры | |
‘——————— |
| ‘буфер индикации (копия сегментов) |
Dim Buf_dis(4) As Byte | ||
Dim Cnt_dis As Byte | ‘счетчик индикации | |
Dim Tmpb As Byte | ‘временное значение | |
Dim Index As Byte | ‘временное значение | |
Dim Value As Byte | ‘временное значение | |
‘——————— |
| ‘текстовая строка |
Dim Bufr As String * 10 | ||
‘—————————————— |
| ‘генератор 1 МГц, необходим компилятору для правильного |
$crystal = 1000000 | ||
‘ |
| ‘ вычисления задержек и других временных параметров |
|
|
‘назначение векторов прерывания.
On Timer0 Timer0_int Nosave | ‘вектор прерывания | от | таймера 0 |
On Timer2 Timer2_int Nosave | ‘вектор прерывания | от | таймера 2 |
‘—————————————— | ‘режим IDLE — разрешить | ||
Mcucr = &B10000000 |
============================================================================= 13
===================================== Справочник по программированию «Bascom-AVR» ==
‘ТАЙМЕРЫ
Tccr0 = &B00000011 | ‘режим таймера 0: Fкв/64 — часы реального времени | |||
‘ | ——————— |
| ‘режим таймера 1: | |
Tccr1a | = &B01000000 | |||
‘генератор звука 2 кГц с выходом на PB1 (OC1A) | ||||
Tccr1b | = &B00001000 | ‘делитель Fкв / 1 и с выходам Oc1a | ||
Ocr1ah | = 0 : Ocr1al = 250 | ‘и коэффициетном Fкв/250*2 | ||
‘ | ——————— |
| ‘режим таймера 2: генератор секундых импульсов | |
Assr.3 | = 1 : Wait 1 | |||
‘включить НЧ-генератор AS2 и подождать стабилизации амплитуды | ||||
Tcnt2 = 0 : Waitms 10 | ‘очистить счетчик и подождать пока значение | |||
Ocr2 = | 128 : Waitms 10 | ‘перепишется из временного буфера | ||
‘установить значение сравнения | ||||
Tccr2 = &B00010101 | ‘установить коэффициент деления прескалера К=128 | |||
‘и выход секундных импульсов на PB3 (OC2) | ||||
‘ | ———————ПОРТЫ |
| ||
‘ | ‘направление линий порта B: 1 — на вывод | |||
| Ddrb = &B00001010 | |||
Portb = &B11111111 | ‘исходное состояние линий B: hhhh2h2h | |||
‘ | Ddrc———————= &B00001111 | ‘направление линий порта C: 1 — на вывод | ||
Portc = &B11111111 | ‘исходное состояние линий C: hhhh2111 | |||
‘ | Ddrd———————= &B00000000 | ‘направление линий порта D: 1 — на вывод | ||
Portd = &B11111111 | ‘исходное состояние линий D: hhhhhhhh | |||
‘ |
|
| ‘* h — высокий уровень, подтянутый через резистор | |
———————прерывания. |
| |||
‘ |
| |||
Timsk = &B010000001 | ‘разрешить прерывание от переполнения таймера 0 | |||
Enable | Timer0 | |||
Enable | Timer2 | ‘разрешить прерывание от переполнения таймера 2 | ||
Enable | Interrupts | ‘разрешить прерывания. | ||
‘ | ———————Index = 1 : Gosub Dis_tr | ‘ВЫВОД СООБЩЕНИЯ СООБЩЕНИЯ (НОМЕР ВЕРСИИ) | ||
| Wait 1 | ‘подождать | ||
‘ГЛАВНЫЙ ЦИКЛ |
| |||
Mc: | Ndat <> 0 Then |
| ||
| If | ‘очистить «обновить данные» | ||
|
| Ndat = 0 | ||
|
| Gosub New_data | ‘обработать данные | |
|
| Goto Mc |
| |
| End If |
| ||
| If | Ddat <> 0 Then | ‘очистить «обновить индикатор» | |
|
| Ddat = 0 | ||
|
| Gosub New_led | ‘обновить индикатор | |
|
| Goto Mc |
| |
| End If |
| ||
| If | Buf_kl <> 0 Then |
| |
‘следующая строка добавляется при необходимости | ||||
‘ |
| Gosub Tr_klb | ‘скорректировать номер кнопок | |
|
| Gosub W_klb | ‘обработать нажатие | |
|
| Buf_kl = 0 | ‘очистить оработанное нажатие | |
|
| Goto Mc |
|
End If Idle
Goto Mc ‘———————————————————————————-
‘ОБРАБОТКА ПРОГРАММ ГЛАВНОГО ЦИКЛА
‘———————
‘обработать данные времени по истечении секунды
New_data:
Incr Rsec | 59 Then | ‘плюс секунда | |
If Rsec > | ‘при необходимости | ||
Rsec = | 0 | : Goto Ndata1 | ‘скорректировать счетчик секунд |
End If |
|
|
|
Goto Ndata3 |
|
| |
Ndata1: |
|
| ‘плюс минута |
Incr Rmin | 59 Then | ||
If Rmin > | ‘при необходимости | ||
Rmin = | 0 | : Goto Ndata2 | ‘скорректировать счетчик минут |
End If |
|
|
|
Goto Ndata3 |
|
| |
Ndata2: |
|
| ‘плюс час |
Incr Rhour |
|
| |
If Rhour > 23 Then | ‘при необходимости | ||
Rhour = 0 |
| ‘скорректировать счетчик часов | |
End If |
|
|
|
Ndata3: |
|
| ‘поставить признак обновления индикации |
Ddat = 255 |
|
|
============================================================================= 14
===================================== Справочник по программированию «Bascom-AVR» ==
Return ‘———————————————————————————-
Здесь проведена оптимизация Подпрограммы Add_vtmpb и Add_sz появились в результате оптимизации исходно текста
‘обновить индикатор по завершению одной из операций в соответствии с текущим состоянием
New_led: |
|
|
|
|
|
|
| ‘очистить строку | ||||
| Bufr = «» |
|
|
|
|
|
| |||||
| If Mdisp = 1 Then |
|
|
|
|
| ‘выбрать вариант обработки индикатора | |||||
|
| Goto Nled2 |
|
|
|
|
|
| ‘на формирования отображения ММСС | |||
| Elseif Mdisp = 2 Then |
|
|
|
| ‘на гашение | ||||||
|
| Goto Nled3 |
|
|
|
|
|
| ||||
| End If |
|
|
|
|
|
|
|
|
| ||
‘сформировать символьное изображение времени в виде ЧЧММ | ||||||||||||
| Tmpb = Rhour : Gosub Add_vtmpb |
| ‘добавить значение часов | |||||||||
‘ | Tmpb = Rmin : Gosub Add_vtmpb |
|
| ‘добавить значение минут | ||||||||
——— |
|
|
|
|
|
|
|
|
|
| ||
Nled1: |
|
|
|
|
|
|
|
| ‘получить код первого знакоместа | |||
‘ | Gosub Asc_seg : Buf_dis(1) = Tmpb |
| ||||||||||
Gosub Asc_seg2 : Buf_dis(2) = Tmpb | ‘получить код второго знакоместа | |||||||||||
‘ | ||||||||||||
Gosub Asc_seg2 : Buf_dis(3) = Tmpb | ‘получить код третьего знакоместа | |||||||||||
‘ | ||||||||||||
Gosub Asc_seg2 : Buf_dis(4) = Tmpb | ‘получить код четвертого знакоместа | |||||||||||
| ||||||||||||
Return |
|
|
|
|
|
|
|
|
|
| ||
‘——— |
|
|
|
|
|
|
|
|
|
|
| |
‘сформировать символьное изображение времени в виде ММСС | ||||||||||||
Nled2: |
|
|
|
|
|
|
|
| ‘добавить значение минут | |||
| Tmpb = Rmin : Gosub Add_vtmpb |
|
| |||||||||
| Tmpb = Rsec : Gosub Add_vtmpb |
|
| ‘добавить значение секунд | ||||||||
‘ | Goto Nled1 |
|
|
|
|
|
|
|
| |||
|
|
|
|
|
|
|
|
|
|
| ||
‘погасить индикатор |
|
|
|
|
|
|
| |||||
Nled3: |
|
|
|
|
|
|
|
| ‘погасить все сегменты | |||
| Buf _ dis(1) = 255 |
|
|
|
|
| ||||||
| Buf _ dis(2) = &HFF |
|
|
|
|
|
|
| ||||
| Buf _ dis(3) = &B11111111 |
|
|
|
| |||||||
| Buf _ dis(4) = 255 |
|
|
|
|
|
|
| ||||
Return |
|
|
|
|
|
|
|
|
|
| ||
‘——— |
|
|
|
|
|
|
|
|
|
|
| |
‘п/п результат оптимизации |
|
|
|
|
| |||||||
Add_vtmpb: |
|
|
|
|
|
|
| ‘если значение выражается одной цифрой | ||||
| If Tmpb < 10 Then |
|
|
|
|
| ||||||
|
| Gosub Add_sz |
|
|
|
|
| ‘добавить символ лидирующего нуля | ||||
| End If |
|
|
|
|
|
|
| ‘добавить значение | |||
| Bufr = Bufr + Str(tmpb) |
|
| |||||||||
Return |
|
|
|
|
|
|
|
|
|
| ||
‘——— |
|
|
|
|
|
|
|
|
|
|
| |
Add_sz: |
|
|
|
|
|
|
|
| ‘добавить символ лидирующего нуля | |||
| Bufr = Bufr + «0» |
|
|
|
|
| ||||||
Return |
|
|
|
|
|
|
|
|
|
| ||
‘———————————————————————————- |
|
|
| программы клавиатуры |
|
|
| |||||
‘ |
|
|
|
|
|
| ||||||
‘——————————————————— |
|
|
|
|
|
|
|
|
|
|
| |
‘ ————————————— | | |
|
| AVR-WATCH |
|
|
| | | ||||
‘ |
|
|
|
|
| |||||||
‘ ——————————— | | | | | — | — |
|
| — | — |
| | | | | |
‘ | | | | | | | | | | | |||||||
‘ | | | | | | | | | | | | | | | | ||||||
‘ | | | | | — | — | | | | | — | — | | | | | | | |
‘ | | | | | | | | | | | | | | | | ||||||
‘ | | | | | — [] | — [] |
| — [] | — [] | | | | ||||
‘ ——————————— | | |
| 1 | 2 |
|
| 3 | 4 |
|
| | | |
‘ | | |
|
|
|
|
| | | |||||
‘ | | |
| _ | _ |
|
| _ | _ |
|
| | | |
‘ | | |
| |_| | |_| |
|
| |_| | |_| |
|
| | | |
‘ | | | Reset | + |
|
| + | Shift |
| | | |||
‘ | | |
|
|
| | | |||||||
‘ | | |
| Min | Hour |
| Min |
|
|
| | | ||
‘ ————————————— |
|
|
|
|
|
|
|
|
|
|
|
‘выполнение программ обработки кнопок — основной список
‘0: пустой переход из-за того, что кнопки нумеруются с 1-й, а не с 0-й
‘1: Сбросить минуты 2: Добавить час 3: Добавить минуту 4: Второе назначение
‘ | | | _ | _ | _ | _ | | |
‘ | | | |_| | |_| | |_| | |_| | | |
============================================================================= 15
===================================== Справочник по программированию «Bascom-AVR» ==
‘ | | | ЧЧММ | ММСС | ON/OFF | ON/OFF | | |
‘ | | | | | ||||
‘ | | | Формат | врем. | Sound | Disp | | |
‘—————————————
‘выполнение программ обработки кнопок — дополнительный список
‘0: пустой переход из-за того, что кнопки нумеруются с 1-й, а не с 0-й
‘1: Отображать ЧЧММ 2: Отображать ММСС 3: Вкл.Выкл. Звук 4: Вкл.Выкл. Индикацию
‘———————————————————
W_klb:
On Buf_kl Goto Kn , Km1 , Km2 , Km3 , Km4 ‘———————————————-
W_skl:
On Buf_kl Goto Km1_1 , Ks1 , Ks2 , Ks3 , Ks4 ‘———
Km1:
Rsec = 0 : Rmin = 0 | ‘сбросить секунды и минуты |
If Rmin > 30 Then | ‘при необходимости округления |
Goto Km2 | ‘скорректировать счетчик минут |
End If |
|
Km1_1: | ‘поставить признак обновления индикации |
Ddat = 255 | |
Kn: |
|
Return |
|
‘——— |
|
Km2: | ‘плюс час |
Incr Rhour | |
If Rhour > 23 Then | ‘при необходимости |
Rhour = 0 | ‘скорректировать счетчик часов |
End If |
|
Goto Km1_1 |
|
‘——— |
|
Km3: | ‘плюс минута |
Incr Rmin | |
If Rmin > 59 Then | ‘при необходимости |
Rmin = 0 | ‘скорректировать счетчик минут |
End If |
|
Goto Km1_1 |
|
‘———
‘ переключить режим второго назначения кнопок
Km4: | ‘выдать приглашение » SH « |
Index = 2 : Gosub Dis_tr | |
Gosub Waitklc | ‘ожидание нажатий 2.5 с |
If Buf_kl <> 0 Then | ‘есть нажания кнопки? |
Goto W_skl | ‘да — переходим к обработке списка |
End If | ‘на обновление индикации |
Goto Km1_1 | |
‘——— |
|
Ks1: | ‘установить режим отображения ЧЧММ |
Mdisp = 0 | |
Goto Km1_1 | ‘на обновление индикации |
‘——— |
|
Ks2: | ‘установить режим отображения ММСС |
Mdisp = 1 | |
Goto Km1_1 | ‘на обновление индикации |
‘———
Совет | Необходимо выбирать такие способы обработки управляющих переменных, чтобы ложные значения |
| не могли создаваться, а при появлении исключались автоматически. Пример тому обработка пере- |
| менной Msnd. Избыточности кода при этом не происходит. |
Ks3: | ‘изменить режим звука на противоположенный |
If Msnd <> 0 Then | |
Msnd = 0 |
|
Else |
|
Msnd = 255 |
|
End If | ‘на обновление индикации |
Goto Km1_1 | |
‘——— |
|
Ks4: | ‘изменить режим гашения на противоположенный |
If Mdisp <> 2 Then | |
Mdisp = 2 | ‘установить режим гашения |
Else | ‘снять режим гашения |
Mdisp = 0 | |
End If | ‘на обновление индикации |
Goto Km1_1 | |
‘———————————————————————————- |
|
‘обработка прерывания таймера 0 |
|
============================================================================= 16
===================================== Справочник по программированию «Bascom-AVR» ==
‘используется как часы реального времени с частотой 244 Гц (4 мс)
‘для этого нужно организовать схему деления 1 МГц/64/64 = 0,000244140625 МГц
Timer0_int: |
|
$asm | ‘сохраним регистры |
Push R31 | |
In R31 , Sreg |
|
Push R31 |
|
Push R30 |
|
‘—— | ‘переустановим счетчик |
Ldi R31 , 192 | |
Out Tcnt0 , R31 |
|
‘——————— | ‘вывод в индикатор |
Rcall Led_out | |
Rcall In_kl | ‘опрос клавиатуры |
‘——————— |
|
‘обработка счетчика времени | ‘считать счетчик |
Lds R31 , {s_tim} | |
Dec R31 | ‘уменьшить |
Sts {s_tim} , R31 | ‘сохранить |
Andi R31 , &h0f | ‘маска |
Brne Intt2_4 | ‘каждое 16 прерывание (64 мс) обрабатываем еще два счетчика |
‘——————— |
|
‘обработка счетчика переменных временных интервалов | |
Lds R31 , {w_tim} | ‘считать счетчик |
Dec R31 | ‘может уменьшаться только от 127 до нуля. |
Brmi Intt2_1 |
|
Sts {w_tim} , R31 |
|
‘——————— |
|
‘обработка счетчика времени звонка |
|
Intt2_1: | ‘проверим, а звонок разрешен? |
Lds R31 , {Msnd} | |
And R31 , R31 | ‘если не равен 0 — переход на отключение |
Brne Intt2_2 | |
‘разрешен | ‘считаем счетчик времени звонка |
Lds R31 , {r_btim} | |
And R31 , R31 | ‘если он равен 0 — переход |
Breq Intt2_2 | |
Dec R31 | ‘уменьшить |
Sts {r_btim} , R31 | ‘и разрешить пищать |
Ldi R31 , &B00001001 | |
Rjmp Intt2_3 |
|
Intt2_2: | ‘запретить пищать |
Ldi R31 , &B00001000 | |
Intt2_3: | ‘в регистр управления таймером 2 |
Out Tccr2 , R31 | |
‘—— |
|
Intt2_4: | ‘восстановим регистры |
Pop R30 | |
Pop R31 |
|
Out Sreg , R31 |
|
Pop R31 |
|
$end Asm |
|
Return |
|
‘———————————————-
‘обработка прерывания таймера 2. Происходит 1 раз в секунду
Timer2_int: |
| ||
$asm | push R31 | ‘сохраним регистры | |
‘ | |||
In R31 , Sreg |
| ||
‘ | Push R31 |
| |
‘—— | ldi R31 , 255 |
| |
‘ | Sts {ndat} , R31 |
| |
Pop R31 | ‘восстановим регистры | ||
‘ | |||
‘ | Out Sreg , R31 |
| |
| Pop R31 |
| |
| Reti |
|
$end Asm Return
‘———————————————————————————-
‘ВВОД ДАННЫХ С КЛАВИАТУРЫ
‘клавиатура опрашивается при выводе очередного знакоместа на индикатор
‘код кнопки совпадает с номером знакоместа. Осуществляется подавление дребезга
‘срабатывание фиксируется при удержании более 6 циклов опроса
In_kl: |
|
|
$asm | ,{Buf_kl} | ‘пока буфер клавиатуры не опустеет |
Lds R31 | ||
And R31 | , R31 |
|
============================================================================= 17
===================================== Справочник по программированию «Bascom-AVR» ==
Breq Inkl |
| ‘сканирование не проводится | ||
Ret |
|
|
|
|
‘——— |
|
|
| |
‘ НАЧИНАЕМ |
|
| ||
Inkl: | R31 | , | {r_ckl} | ‘подготовим счетчика нажатий к обработке |
Lds | ||||
Sbic Pinc | , 4 | ‘считать состояние линии опроса кнопки | ||
Rjmp N_st |
| ‘нет нажатия — переход | ||
‘——— |
| ЕСТЬ |
| |
‘ НАЖАТИЯ |
| |||
Y_st: | R31 | , | 6 | ‘если равен 6 — нажатие уже было зафиксировано |
Cpi | ||||
Breq Y_st1 |
| ‘на выход без запоминания. | ||
Inc | R31 |
|
| ‘иначе нужен инкремент |
Sts | {r_ckl} , R31 | ‘и сохранить | ||
Cpi | R31 | , | 6 | ‘меньше 6 — тоже выход без действий |
Brne y_st1 |
| |||
‘——— |
| ЗАФИКСИРОВАТЬ |
| |
‘ НАЖАТИЕ | ‘звонить 60 мс | |||
Ldi | R31 | , | 3 | |
Sts | {r_btim} , R31 | ‘преобразуем код знакоместа (от 0 до 3) | ||
Lds | R31 | , | {Cnt_dis} | |
Inc | R31 |
|
| ‘в код кнопки (от 1 до 4) |
Sts | {Buf_kl} , R31 |
| ||
Y_st1: |
|
|
|
|
Ret |
|
|
|
|
‘——— |
| НЕТ |
| |
‘ НАЖАТИЯ |
| |||
N_st: | R31 | , | R31 | ‘проверим счетчик «удержания» |
And | ||||
Breq N_st1 |
| ‘не равен нулю | ||
Dec | R31 |
|
| ‘декремент |
Sts | {r_ckl} , R31 | ‘и сохранить | ||
N_st1: |
|
|
|
|
Ret |
|
|
|
|
$end Asm |
|
|
|
|
‘———————————————————————————- | ||||
‘данные | константы позволяют учесть и скорректированит «нерегулярность» монтажа индикатора | |||
Const N_scn = | &B11110000 | ‘ МАСКА СКАНИРОВАНИЯ ДЛЯ ИНДИКАТОРА С ОА | ||
Const N_sc1 = | &B11111110 | ‘ МАСКА ДЛЯ ПОДСВЕТКИ 1-ГО ЗНАКОМЕСТА | ||
Const N_sc2 = | &B01111101 | ‘ МАСКА ДЛЯ ПОДСВЕТКИ 2-ГО ЗНАКОМЕСТА | ||
Const N_sc3 = | &B11111011 | ‘ МАСКА ДЛЯ ПОДСВЕТКИ 3-ГО ЗНАКОМЕСТА | ||
Const N_sc4 = | &B11110111 | ‘ МАСКА ДЛЯ ПОДСВЕТКИ 4-ГО ЗНАКОМЕСТА | ||
‘—————————— |
| |||
‘обслуживание | светодиодного 7-сегментного индикатора | |||
Led_out: |
|
|
|
|
$asm | R31 | , | {Cnt_dis} | ‘считать значение счетчика сканирования |
Lds | ||||
Inc | R31 |
|
|
|
Andi R31 , 3 | ‘и сохранить | |||
Sts | {Cnt_dis} , R31 | |||
‘——— | , | 1 |
| |
Cpi | R31 |
| ||
Breq Led_1 |
|
| ||
‘——— | , | 2 |
| |
Cpi | R31 |
| ||
Breq Led_2 |
|
| ||
‘——— | , | 3 |
| |
Cpi | R31 |
| ||
Breq Led_3 |
|
| ||
Led_0: |
|
|
|
|
‘——— | , | {buf_dis} |
| |
Lds | R30 | ‘ ЗНАЧЕНИЕ ДЛЯ ПОДСВЕТКИ 1-ГО ЗНАКОМЕСТА | ||
Ldi | R31 | , | N_sc1 | |
Rjmp Led_e |
|
| ||
‘——— |
|
|
| |
Led_1: | R30 | , | {buf_dis+1} |
|
Lds | ‘ ЗНАЧЕНИЕ ДЛЯ ПОДСВЕТКИ 2-ГО ЗНАКОМЕСТА | |||
Ldi | R31 | , | N_sc2 | |
Rjmp Led_e |
|
| ||
‘——— |
|
|
| |
Led_2: | R30 | , | {buf_dis+2} |
|
Lds | ‘ ЗНАЧЕНИЕ ДЛЯ ПОДСВЕТКИ 3-ГО ЗНАКОМЕСТА | |||
Ldi | R31 | , | N_sc3 | |
Rjmp Led_e |
|
| ||
‘——— |
|
|
| |
Led_3: | R30 | , | {buf_dis+3} |
|
Lds | ‘ ЗНАЧЕНИЕ ДЛЯ ПОДСВЕТКИ 4-ГО ЗНАКОМЕСТА | |||
Ldi | R31 | , | N_sc4 |
============================================================================= 18
===================================== Справочник по программированию «Bascom-AVR» ==
Led_e: | Portd , R30 |
|
Out |
| |
In R30 , Portc | ‘ МАСКА СКАНИРОВАНИЯ | |
Ori | R30 , N_scn | |
And | R30 , R31 |
|
Out | Portc , R30 |
|
Ret |
|
|
$end Asm |
|
|
‘———————————————————————————- |
| УТИЛИТЫ |
‘ |
| |
‘———————————————————————————- |
|
|
‘ВЫВОД СООБЩЕНИЯ СООБЩЕНИЯ, НОМЕР КОТОРОГО УКАЗАН Index | ||
Dis_tr: | Value = 1 To 4 | ‘определим число считываемых символов |
For | ||
| Tmpb = Index * 4 | ‘вычислить индекс, указывающих на начало сообщения |
| Tmpb = Tmpb + Value | ‘вычислить индекс, указывающих на текущий символ |
| Decr Tmpb | ‘коррекция индекса |
| Tmpb = Lookup(tmpb , Tr_led) | ‘считать из таблицы код символа |
| Gosub Pos_seg | ‘преобразовать в код сегментов |
| Buf_dis(index) = Tmpb | ‘записать в буфер индикации |
Next Index |
| |
Return |
|
|
‘———————————————————————————- |
|
|
‘П/П ВЫБОРА ИЗ ТАБЛИЦЫ КОДА ЧИСЛА В 7-СЕГМЕНТНОМ КОДЕ ИЗ ASCII (ВТОРОГО СИМВОЛА) | ||
Asc_seg2: | ‘сдвинуть строку влево на одну позицию | |
Bufr = Mid(bufr , 2) |
‘———
‘П/П ВЫБОРА ИЗ ТАБЛИЦЫ КОДА ЧИСЛА В 7-СЕГМЕНТНОМ КОДЕ ИЗ ASCII
Asc_seg: |
|
|
|
| ‘считать первый символ строки | ||||
| Tmpb = Asc(bufr) |
|
|
| |||||
‘ | Tmpb = Tmpb — &h40 |
|
|
| ‘преобразовать ASCII в число | ||||
——— |
|
|
|
| 7-СЕГМЕНТНЫЙ КОД |
| |||
‘П/П ПРЕОБРАЗОВАНИЯ ПОЗИЦИОННОГО КОДА В |
| ||||||||
Pos_seg: |
|
|
|
| ‘считать из таблицы, используя число как смещение | ||||
| Tmpb = Lookup(tmpb , Tabseg0) |
| |||||||
‘при необходимости подключить следующую | строчку |
|
| ||||||
‘ | Gosub Tr_seg |
|
|
| ‘исправить монтаж сегментов индикатора | ||||
Return |
|
|
|
|
|
|
|
| |
‘——— |
|
|
|
|
| ДЛЯ КОРРЕКЦИИ «НЕПРАВИЛЬНОГО» МОНТАЖА | |||
‘П/П ПЕРЕСЫПКИ БИТОВ 7-СЕГМЕНТНОГО КОДА | |||||||||
Tr_seg: |
|
|
|
| : Value.2 = Tmpb.5 | ‘например «отзеркалить» | |||
| Value.0 = Tmpb.7 : Value.1 = Tmpb.6 | ||||||||
| Value.3 = Tmpb.4 : Value.4 = Tmpb.3 | : Value.5 = Tmpb.2 : Value.6 = Tmpb.1 : Value.7 = Tmpb.0 | |||||||
‘ | Tmpb = Value : Return |
|
|
|
|
|
| ||
|
|
|
|
|
|
|
|
| |
‘ТАБЛИЦА РАСПОЛОЖЕНИЯ СЕГМЕНТОВ ИНДИКАТОРА — ПРОТОТИПА |
| ||||||||
‘——— |
| D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
‘ |
| ||||||||
‘ |
| ¦————————————————h2 | g1 | f1 | e1 | d1 | c1 | b1 | a1 |
‘BUF_DIS(4) | |||||||||
‘BUF_DIS(3) | ¦ h3 | g2 | f2 | e2 | d2 | c2 | b2 | a2 | |
‘BUF_DIS(2) | ¦ h4 | g3 | f3 | e3 | d3 | c3 | b3 | a3 | |
‘BUF_DIS(1) | ¦ h5 | g4 | f4 | e4 | d4 | c4 | b4 | a4 | |
‘——————————————- |
|
|
|
|
|
|
|
|
|
‘РАСПОЛОЖЕНИЕ СЕГМЕНТОВ НА ПОЛЕ ИНДИКАТОРА
‘===============================================
‘ ¦ | -a4- |
| -a3- |
| -a2- |
| -a1- |
| ¦ |
|
‘ ¦ | I | I | I | I | ¦ |
| ||||
‘ ¦ I | I | I | I | ¦ |
| |||||
‘ ¦ | f4 | b4 | f3 | b3 | f2 | b2 | f1 | b1 | ¦ |
|
‘ ¦ I | I | I | I | I | I | I | I | ¦ |
| |
‘ ¦ | -g4- | I | -g3- | I | -g2- | I | -g1- | I | ¦ |
|
‘ ¦ I | I | I | I | ¦ |
| |||||
‘ ¦ | e4 | c4 | e3 | c3 | e2 | c2 | e1 | c1 | ¦ |
|
‘ ¦ I | I | I | I | I | I | I | I | ¦ |
| |
‘ ¦ | -d4- | [h5] | -d3- |
| -d2- | [h3] | -d1- |
| ¦ |
|
‘ ¦ |
|
| [h4] |
| [h2]¦ |
| ||||
‘ ¦ |
|
|
|
|
|
|
|
| ¦ |
|
‘ | =============================================== |
| ||||||||
‘———————————————————— |
|
|
|
| , СВЕЧЕНИЕ «0» |
|
|
| ||
‘ ТАБЛИЦА КОДОВ СЕГМЕНТОВ |
|
|
| |||||||
‘———————————————————— |
|
| ‘ШЕСТНАДЦАТИРИЧНЫЕ ЦИФРЫ ОТ | 0(00h) ДО 15(0Fh) | ||||||
Tabseg0: |
| |||||||||
|
|
|
|
| ‘ 0 , | 1 | -d0 — |
| ||
| Data &HC0 , &HF9 |
|
|
| I | |||||
| Data &HA4 , &HB0 |
|
|
| ‘ 2 , | 3 | I | |||
| Data &H99 , &H92 |
|
|
| ‘ 4 , | 5 | D5 | D1 | ||
| Data &H82 , &HF8 |
|
|
| ‘ 6 , | 7 | I | I | ||
| Data &H80 , &H90 |
|
|
| ‘ 8 , | 9 | -d6 — |
|
============================================================================= 19
===================================== Справочник по программированию «Bascom-AVR» ==
| Data | &H88 | , &H83 | ‘ A | , B I | I | |
| Data | &HC6 | , &HA1 | ‘ C | , D D4 | D2 | |
| Data | &H86 | , &H8E | ‘ E | , F I | I | |
‘ |
|
|
| ‘ |
| -D3- | [D7] |
|
| ‘ДРУГИЕ СИМВОЛЫ (УСЛОВНАЯ | НУМЕРАЦИЯ) |
| |||
| Data | &HAF |
| ||||
|
| ‘ R | *(16) |
| |||
| Data | &HE3 |
| ‘ U | *(17) |
| |
| Data | &HC7 |
| ‘ L(18) |
|
| |
| Data | &HFF |
| ‘ ПРОБЕЛ(19) |
| ||
| Data | &H0B |
| ‘ H | *(20) |
| |
| Data | &HB7 |
| ‘ =(21) |
|
| |
| Data | &HF7 |
| ‘ _(22) |
|
| |
| Data | &HC3 |
| ‘ ЛЕВАЯ ЧАСТЬ БУКВЫ «W»(23) | |||
| Data | &HE1 |
| ‘ ПРАВАЯ ЧАСТЬ БУКВЫ «W»(24) | |||
| Data | &H0C |
| ‘ P(25) |
|
| |
| Data | &HFB |
| ‘ I | *(26) |
| |
| Data | &H07 |
| ‘ T | *(27) |
| |
| Data | &HAB |
| ‘ П | *(28) |
| |
| Data | &HA3 |
| ‘ O | *(29) |
| |
| Data | &HE7 |
| ‘ L | *(30) |
| |
| Data | &H09 |
| ‘ H(31) |
|
| |
| Data | &H9C |
| ‘ ГРАДУС(32) |
| ||
| Data | &HAF |
| ‘ ФРОНТ -(33) |
| ||
| Data | &HBB |
| ‘ СПАД ¬(34) |
| ||
| Data | &HBF |
| ‘ МИНУС -(35) |
| ||
‘ПРИМЕЧАНИЕ. * — МАЛЫЕ СИМВОЛЫ |
|
|
|
| |||
‘———————————————————— |
|
|
|
| символов таблицы Tabseg0 | ||
‘сообщения индикатора, записанные в номерах | |||||||
Tr_led: | 17 , | 22 , 1 , 2 | ‘ «v_12» (0) |
| |||
| Data |
| |||||
| Data | 19 , | 5 , 31 , 19 | ‘ « | SH » (1) |
| |
| Data | 14 , | 16 , 12 , 5 | ‘ «ErCS» (2) |
| ||
| Data | 19 , | 0 , 15 , 15 | ‘ « | OFF» (3) |
| |
| Data | 19 , | 0 , 18 , 19 | ‘ « | OL » (4) |
| |
| Data | 19 , | 18 , 0 , 19 | ‘ « | LO | » (5) |
|
‘ | Data | 19 , | 23 , 24 , 19 | ‘ « | W | » (6) |
|
|
|
|
|
|
|
| |
‘ожидание нажатий 2.5 с |
|
|
|
| |||
Waitklc: |
|
| ‘задать время ожидания 2500=64 мс * 40 | ||||
| W_tim = 40 |
| |||||
| Buf_kl = 0 |
| ‘очистим регистр клавиатуры от кода предыдущего нажати | ||||
‘цикл ожидания нажатий |
|
|
|
| |||
Do | If Buf_kl | <> 0 Then | ‘есть нажания кнопки? | ||||
| Goto Wtklend | ‘да | — на выход |
| |||
| End If |
|
|
|
|
| |
| Idle |
|
| ‘или истечения разрешенного времени 2.5 с | |||
Loop Until W_tim = 0 | |||||||
Wtklend: |
|
|
|
|
|
| |
‘следующая строка добавляется при необходимости |
|
| |||||
‘ | Gosub Tr_klb | ‘скорректировать номер кнопокReturn | |||||
‘——— |
|
|
|
|
|
|
|
‘П/П ПЕРЕСЫПКИ НОМЕРОВ КНОПОК — ПЕРЕХОД ОТ ФИЗИЧЕСКИХ НОМЕРОВ К ЛОГИЧЕСКИМ | |||||||
Tr_klb: |
|
|
|
|
|
| |
| Buf_kl = Lookup(Buf_kl , tklb) : Return |
|
|
| |||
Tklb: | 0 , 4 , 3 , 2 , 1 |
| ‘таблица перекодировки, например, наоборот | ||||
‘ | Data |
| |||||
|
|
|
|
|
|
|
============================================================================= 20
Обработка нажатий тактовой кнопки. » Хабстаб
Обычно первая программа программиста — выводит на экран строку “Hello word”, а эмбеддер мигает светодиодом, может ещё и кнопку прикрутить и с её помощью изменять состояние светодиода. Вот как раз про кнопку и хотел рассказать, обычно кнопку, которая что-либо переключает, называют тактовой кнопкой и подключают её по одной из схем, изображённых ниже.На двух верхних схемах подтягивающие резисторы не изображены, но этот не значит, что их нет, просто они находятся внутри микросхемы.
Но гораздо более интересный вопрос заключается в том, как опрашивать кнопку, чтобы не пропускать нажатия? Вариант первый — в цикле опрашивать вывод, к которому подключена кнопка, этот способ будет работать пока программа небольших размеров (вкл-выкл светодиод), но по мере разрастания программы начнут пропускаться нажатия. Второй вариант, это настроить таймер, чтобы он переполнялся каждые 30 ms, а по переполнению возникало прерывание и в нём опрашивались выводы, к которым подключены кнопки, ну или кнопка. Почему время опроса 30 ms? Дело в том что кнопка подвержена дребезгу, а такой временной интервал между опросами, позволяет его не чувствовать, давайте рассмотрим этот момент подробнее.
Стрелки на картинке — это моменты возникновения прерываний, на верхней картинке изображен самый простой вариант развития событий, за счёт паузы между опросами, мы проскакиваем дребезг.
На средней картинке прерывание возникает в момент дребезга и как-будто бы кнопка не была нажата, но нас это не смущает, при следующем опросе кнопки фиксируем нажатие.
На нижней картинке прерывание снова возникает в момент дребезга, фиксируем нажатие и проскакиваем дребезг.
С отпусканием кнопки всё происходит по тому же сценарию и ещё если кнопка сильно дребезжит время между опросами можно увеличить.
Вот мы в прерывании, давайте рассмотрим варианты обработки нажатия. Первый выставляем флаг, что кнопка нажата, дальше в основном цикле проверяем его и там же сбрасываем, второй — заводим переменную и инкрементируем, её значение в прерывании если кнопка нажата, по отпусканию кнопки проверяем сколько натикало, то есть длительность удержания. Если натикало хотя бы один, то фиксируем короткое нажатие, если больше 10 — фиксируем длинное нажатие. Ещё раз поясню отличие первого способа от второго, в первом способе воздействие на систему происходит в момент нажатия кнопки, во втором — в момент отпускания, а какой способ выбрать решает сам программист, в зависимости от поставленной задачи.
Eщё можно попробовать реализовать двойное нажатие, и здесь мне видется два варианта, первый — после того как отпустили кнопку запускаем таймер и определённый промежуток времени ждём второго нажатия, если оно произошло, то фиксируем double_click. Второй способ — вести лог нажатий, то есть если кнопка была нажата и отпущена, то в нашей переменной будет храниться 0b00000010, если удерживается в течение 3 опросов, то 0b00000111, реализовать это просто: в прерывании сдвигаем значение переменной на одну позицию влево и в последний разряд записываем текущее состояние. Потом экспериментально(быстро нажимая два раза на кнопку) находим несколько значений переменной при двойном нажатии, например, у нас получилось 0b00110011, записываем это значение в double_click, теперь, для того чтобы определить двойное нажатие сравниваем значение нашей переменной с double_click. Первый вариант точно работает, а второй — просто мысли вслух.
ОБРАБОТКА ВНЕШНИХ ПРЕРЫВАНИЙ МК AVR
В качестве входов внешних прерываний используются входы портов с альтернативной функцией: PD2, PD3 – для прерываний INTO, INT1 и РЕО – для прерывания INT2 в микроконтроллере ATmega8515. Запросы внешних прерываний INTO, INT1 могут быть представлены низким уровнем сигнала прерывания (L), переходом от высокого уровня сигнала к низкому (HL – по отрицательному фронту), переходом от низкого уровня сигнала к высокому (LH – по положительному фронту), запрос INT2 только переходами (LH) и (HL). В зависимости от типа запроса в регистре управления микроконтроллера MCUCR необходимо установить биты ISCxO и ISCxl согласно табл. 2.1 для каждого из прерываний INTx (х = 0,1) и определить бит ISC2 в регистре EMCUCR для прерывания
INT2. При ISC2 = О прерывание осуществляется по отрицательному фронту, при ISC2 = I – по положительному.
Далее подготовим программу переключения светодиодов с использованием внешнего прерывания от кнопки STOP.
Согласно поставленным условиям, в блок инициализации микроконтроллера внесем ряд изменений:
– добавим вектор прерываний;
– указатель стека установим на последнюю ячейку ОЗУ;
– разрешим внешнее прерывание INTO (по сигналу О на линии 2 порта PD) и прерывания вообще.
Поскольку внешнее прерывание INTO представлено сигналом на входе порта PD2, в качестве кнопки STOP используем кнопку
SW2 и программируем PD2 на ввод. Пример программы 2.2 приведен ниже. Задержка представлена подпрограммой DELAY. Программа работает аналогично 2.1, но нажатие кнопки STOP вызывает прерывание.
Программа 2.2
;Программа 2.2 для поочередного переключения светодиодов ;при нажатии на кнопку START (SWO). После нажатия на кноп- ;ку STOP (SW2) переключение прекращается и возобновляется ;с места остановки при повторном нажатии на кнопку START
г
.include «8515def.inc» ;файл определений для AT90S8515
;.include «m8515def. ;выключение
out FORTH,temp ; светодиодов
brts LEFT ;переход, если флаг Т установлен
sbrs reg_led,О ;пропуск следующей команды, если
; 0-й разряд reg_led установлен set ;Т=1
гог reg_led ;сдвиг reg_led вправо
rjmp LOOP
LEFT: sbrs reg_led,7 ;пропуск следующей команды, если
; 7-й разряд reg_led установлен clt ;Т=0
го1 reg_led ;сдвиг reg_led влево
rjmp LOOP
;; Обработка прерывания от кнопки STOP*** STOP_PRESSED:
WAITSTART_2: ;ожидание
sbic PIND,START ; нажатия
rjmp WAITSTART_2 ; кнопки START
reti
;*** Задержка *** DELAY:Idi rl7,2 dl: Idi rl8,2 d2: dec rl8 brne d2 dec rl7 brne dl ret
Задание 2. Проверить работу программы с помощью отладчика AVR Studio 4. Изменить параметры задержки, чтобы длительность задержки составила 0,5 с. Запрограммировать микроконтроллер и проверить работу программы.5-6-7-6-5…
б) в четных разрядах;
в) в нечетных разрядах;
г) последовательно увеличивая количество включенных (выключенных) светодиодов до восьми и затем уменьшая до нуля.
Отладив программу, загрузите ее в микроконтроллер и проверьте работу.
Задание 4. Изменить программу, добавив внешнее прерывание ESfTl (сигнал на линии PD3, адрес прерывания 002, бит 7 регистра маски GIMSK или GICR) от кнопки START. Открыв при отладке программы окно памяти данных, проверить работу стека, размещаемого в памяти с адреса $025F. Отлаженную программу загрузить в микроконтроллер и проверить ее работу.
Обработка кнопочного регистра с индикацией состояния
Ввод данных от кнопок рассмотрим на примере программы 2.3, выполняющей последовательный опрос и индикацию нажатия кнопок SWx (х = 0,1,2,3) кратковременным включением соответствующего светодиода LEDx, а также включением светодиодов LEDx (х = 4, 5, 6, 7) и выключением после повторного нажатия кнопок SWx (х = 4, 5, 6, 7).
Обратите внимание на использование в программе макроопределений для проверки состояния кнопок. При каждом нажатии кнопки значение соответствующего бита в слове состояния младшей и старшей групп кнопок (st_L, st_H) меняется на противоположное (командой еог) и сохраняется. Для вывода на светодиоды формируется байт вывода reg led.
Программа 2.3
;Программа 2.3 для обработки нажатий кнопок и индикации их ;состояний
.include «8515def.inc» ;файл определений для AT90S8515 ;.include «m8515def.inc» ;файл определений для ATmega8515
.def temp = г16 ;временный регистр
.def st_L = rl7 ;состояние младшей группы SW_0123
.def st_H = rl8 ;состояние старшей группы SW_4567
.def sw_cod = г22 ;код состояния замкнутой кнопки
.def reg_led = г23 ;регистр состояния светодиодов
.macro testH_sw ;макроопределение
sbic FIND, @0 ;проверка кнопки SWx(х=4,5,б,7)
rjmp quit ; и установка
bid sw_cod, @0 ; бита замкнутой кнопки
еог st_H,sw_cod ;переключение бита состояния
mov reg_led,st_H ;байт для индикации
com reg_led ;инвертирование для вывода
out PORTB,reg_led ; на светодиоды
с1г reg_led ;очистка
clr sw_cod
rcall DELAY ;задержка
wait: sbis FIND, @0 ;кнопка отпущена?
rjmp wait quit: nop .endmacro testH_sw
.macro testL_sw ;макроопределение
sbic PIND,@0 ;проверка кнопки SWx(x=0,1,2,3)
rjmp quit ; и установка
bid sw_cod,@0 ; бита замкнутой кнопки
eor st_L,sw_cod ;переключение бита состояния
mov reg_led,sw_cod ;байт
or reg_led,st_H ; для индикации
com reg_led ;инвертирование для вывода
out PORTB,reg_led ; на светодиоды
clr sw_cod
rcall DELAY_0 ;короткая задержка
ori reg_led,OxOf ; перед гашением
out PORTB,reg_led ; светодиодов младшей группы
quit: nop .endmacro testL_sw .org $000
rjmp init ;***Инициализация***
INIT: Idi temp,low(RAMEND) ;установка
out SPL,temp ; указателя стека
Idi temp,high(RAMEND) ; на последнюю
out SPH,temp ; ячейку ОЗУ
ser temp ;настройка
out DDRB,temp ; порта PB
out PORTB,temp ; на вывод
clr temp ;настройка
out DDRD,temp ; порта PD
ser temp ; на
out PORTD,temp ; ввод
clr sw_cod ;очистка кода кнопки
clr st_L ;очистка операнда
clr st_H
clr reg_led
set ; T=1
input: testL_sw 0 testL_sw 1 testL_sw 2 testL sw 3
testH_sw 4 testH_sw 5 testH_sw б testH_sw 7 rjmp input Задержка *** DELAY_0: Idi r21,255 dO: dec r21 brne dO ret
Задержка *** DELAY: Idi rl9,10 dl: Idi r20,255 d2: Idi r21,255 d3: dec r21 brne d3 dec r20 brne d2 dec rl9 brne dl ret
Задание 5. Ha основе 2.3 разработать программу «кодового замка», которая после набора 4-разрядного PIN-кода с помощью кнопок SWO – SW3 и ввода данных, например с помощью кнопки SW5, осуществляет сравнение с паролем и включает светодиод LED7 при правильном вводе. При трех неправильных попытках введения PIN-кода кнопочная клавиатура должна быть заблокирована, а все светодиоды включены.
Число нажатий на кнопку Override | Описание функции | Кнопка 1 брелока | Кнопка 2 | Кнопка 3 | Кнопка 4 |
1 | Время работы двигателя в режиме автозапуска, мин | 5 | 10 | 15 | 20 |
2 | Температура окружающей среды для пуска мотора | -5 | -10 | -20 | -30 |
3 | Время прокручивания стартерного механизма при дистанционном старте двигателя, мс | 800 | 1200 | 1800 | 3000 |
4 | Контроль работы силового агрегата при автозапуске | По напряжению в электросети авто | По показаниям контроллера давления масла | По тахометру (требуется программирование холостых оборотов) | |
5 | Время работы второго дополнительного канала, с | 0,8 | 10 | 30 | Постоянный сигнал |
6 | Время работы сигналов сирены или рулевого гудка, мс | 100 | 10 | 15 | 20 |
7 | Управление центральным замком при дистанционном запуске | Замки включены и не закрываются | Замки отключены и не запираются | Замки включены и закрываются | Замки отключены и запираются |
8 | Задержка активации стартерного механизма, с | 2, рекомендовано для бензиновых моторов | 10, для дизельных силовых агрегатов | 10 | 10 |
9 | Длина сигнала на отпирание и запирание центрального замка, с | 0,8 на открытие и закрытие | 3,6 на запирание и отпирание | 0,8 на закрытие и двойной сигнал по 0,8 на открытие | Сигнал запирания — 30, отпирания — 0,8 |
10 | Управление блокиратором двигателя или дополнительным каналом | Иммобилайзер отключен, дополнительный канал работает | Блокиратор выключен, двухэтапное открытие дверных замков | Блокиратор включен, третий дополнительный канал работает | Двухэтапное открытие дверных замков при включенном иммобилайзере |
11 | Безопасное вождение транспортного средства | Дверные замки не закрываются, но открываются при отключении зажигания | Закрытие замков в дверях производится через 10 с после включения зажигания, открываются сразу | Закрытие производится через 30 секунд после включения, открытие — моментально | |
12 | Автоматическая постановка на защиту | Функция отключена | Опция активирована без закрытия дверных замков | Функция включена с запиранием дверей | |
13 | Учет задержки при работе салонной системы освещения, с | 1 | 15 | 30 | 45 |
14 | Время отключения света в салоне или управление электростеклоподъемниками | Свет активируется на 20 секунд после отключения защиты | Освещение включается на 30 с после отключения охраны | Закрытие стеклоподъемников в течение 20 с после включения защитного режима | Поднятие стекол в течение 30 секунд после активации охранной функции |
15 | Тип блокировки и единицы измерения температуры салона | Градусы Цельсия, блокировка нормально разомкнута | Фаренгейт, тип блокировки аналогичен | Градусы Цельсия, нормально замкнутая блокировка | Градусы Фаренгейта с такой же блокировкой |
16 | Турботаймер двигателя | Отключен | 1 минута | 3 мин | 5 мин |
Polling vs Interrupt — Какой подход вам подходит?
Введение
Существует два основных подхода к решению задачи в программировании микроконтроллера — метод опроса и прерывание. В этой статье мы укажем на разницу между прерыванием и опросом.
Пример
Рассмотрим сценарий: Предположим, вы ждете своего друга. Есть два способа узнать это, когда приедет ваш друг. Во-первых, вы ждали его / ее у двери, и как только он / она придет, вы узнаете.Не круто, правда? Что ж, есть еще один способ. Вы можете закрыть дверь и продолжить работу, которую вы делали. Как только он / она придет, он / она позвонит в дверь, и вы узнаете о прибытии вашего друга. Итак, первый метод, который я упомянул, — это метод опроса, а другой метод называется методом прерывания.
Метод опроса
В методе опроса микроконтроллер непрерывно проверяет состояние регистра и выполняет задачу в соответствии с состоянием регистра.Первый случай в примере выше. Примером этого метода является то, что мы сделали в Button Counter. В этой программе счетчика кнопок я запрограммировал микроконтроллер на проверку состояния PIN0 регистра PORT D, чтобы определить, нажата конкретная кнопка или нет. Я дал условия в инструкциях IF-else о том, как действовать, если кнопка нажата. Излишне говорить, что при использовании метода опроса ваш микроконтроллер не делает ничего, кроме проверки состояния устройства или регистра.Итак, если вы не хотите делать ничего другого, кроме проверки состояния устройства или регистрации, вы можете выбрать эту опцию, в противном случае вам следует использовать метод прерывания.
Метод прерывания
Обычно оборудование очень медленное с точки зрения скорости обработки микроконтроллера. Следовательно, если мы реализуем метод опроса, это замедлит скорость микроконтроллера и, следовательно, производительность. Следовательно, нам нужен другой тип подхода, который выполняет задачу — The Interrupt Method. В этом методе микроконтроллер не выполняет непрерывную проверку состояния устройства или состояния регистров. Вместо этого устройство или регистр посылают микроконтроллеру сигнал о готовности. Микроконтроллер останавливает все, что он выполняет, и начинает выполнять программу, которую вы написали для прерываний (Interrupt Service Routine-ISR). После выполнения ISR микроконтроллер возобновляет выполнение программы с того места, где он остановился.
Преимущества прерывания перед опросом
- Первое преимущество — производительность микроконтроллера намного лучше при использовании метода прерывания, чем метода опроса.
- В методе опроса микроконтроллер постоянно проверяет, готово ли устройство или нет, но вероятность потери данных больше при опросе, чем при прерывании. Это связано с тем, что микроконтроллер проверяет регистр в соответствии с предоставленными часами. Но устройство может отправлять данные в микроконтроллер в любое время. Чтобы упростить это — предположим, временной период микроконтроллера составляет 1 секунду. Это означает, что он проверяет регистр каждые 1 секунду.Но что, если данные прибывают через 1,5 секунды? В то время как в методе прерывания шансы потери данных очень минимальны.
Теперь выбор за вами. Я лично предпочитаю метод прерывания опросу, но я читал какую-то статью, и в ней было написано, что прерывание увеличивает риск несинхронности с остальной частью программы. Также говорят, что отладить программу прерывания несложно. И да, опрос немного проще реализовать и понять, чем прерывание .
На этом статья заканчивается — если вам это нравится, вы можете стать членом нашей группы рассылки, чтобы никогда не пропустить обновление статьи. Ознакомьтесь также с другими статьями.
СвязанныеЦифровые порты ввода / вывода на AVR
8-битные микроконтроллерыAVR® управляют приложениями через свои цифровые входы и выходы (I / O). Эти контакты могут контролировать любое напряжение, присутствующее на входе с высоким импедансом, и ток питания или потребителя в качестве цифрового выхода высокого или низкого напряжения.Эти контакты обычно объединяются в группы по восемь и называются портами. AVR использует алфавит для именования этих портов, например: PortA, PortB и т. Д. Контакты PortA обозначаются как PA0 — PA7.
Все порты AVR имеют настоящую функцию чтения-изменения-записи при использовании в качестве обычных цифровых портов ввода-вывода. Это означает, что направление одного вывода порта может быть изменено без непреднамеренного изменения направления любого другого. То же самое применимо при изменении значения привода (если он сконфигурирован как выход) или включения / выключения подтягивающих резисторов (если он сконфигурирован как вход).Каждый выходной буфер имеет симметричные характеристики возбуждения с высокой пропускной способностью как приемника, так и источника.
Штыревой драйвер достаточно надежен, чтобы напрямую управлять светодиодными дисплеями. Все выводы портов имеют индивидуально выбираемые подтягивающие резисторы с постоянным сопротивлением напряжения питания. Все контакты ввода / вывода имеют защитные диоды как для VCC, так и для заземления, как показано на рисунке.
Каждый порт состоит из трех регистров:
- DDRx — Регистр направления данных
- PORTx — Выходной регистр контактов
- PINx — регистр ввода вывода
, где x = имя порта (A, B, C или D)
Эти регистры определяют настройку цифровых входов и выходов.Контакты ввода / вывода также могут использоваться совместно с внутренними периферийными устройствами. Например, аналого-цифровой (АЦП) преобразователь может быть подключен к выводу ввода-вывода вместо цифрового вывода. В этом случае регистры контактов ввода / вывода устанавливают его как трехпозиционный вход с высоким импедансом.
- Биты DDxn доступны по адресу ввода / вывода DDRx
- бит PORTxn по адресу ввода / вывода PORTx
- битов PINxn по адресу ввода / вывода PINx
Где n = номер штыря в регистре порта
DDxn
Биты DDxn в регистре DDRx выбирают направление этого вывода.Если DDxn записывается в «1», Pxn конфигурируется как выходной контакт. Если DDxn записывается в ‘0’, Pxn конфигурируется как входной вывод.
ПОРТxn
Биты PORTxn в регистре PORTx имеют две функции. Они могут управлять выходным состоянием вывода и настройкой входного вывода.
В качестве вывода:
Если в бит записана «1», когда вывод настроен как вывод вывода, вывод порта переводится в высокий уровень. Если в бит записан «0», когда вывод сконфигурирован как вывод, вывод порта переводится в низкий уровень.
Как вход:
Если в бит записана «1», когда контакт настроен как входной, активируется подтягивающий резистор. Если в бит записан «0», когда вывод сконфигурирован как входной вывод, вывод порта является трехзначным.
PINxn
Биты PINxn в регистре PINx используются для чтения данных с вывода порта. Когда вывод настроен как цифровой вход (в регистре DDRx) и включен подтягивающий сигнал (в регистре PORTx), бит будет указывать состояние сигнала на выводе (высокий или низкий).
Примечание: Если порт является выходом, то чтение регистра PINx даст вам данные, которые были записаны на контакты порта.
В качестве входа с тремя состояниями:
Когда регистр PORTx отключает подтягивающий резистор, вход становится тройным, оставляя контакт слева в плавающем состоянии. В этом состоянии даже небольшой статический заряд на окружающих объектах может изменить логическое состояние вывода. Если вы попытаетесь прочитать соответствующий бит в регистре вывода, его состояние невозможно предсказать.
Все выводы PORTA установлены как входы с включенными подтягиваниями, а затем считываются данные из PORTA:
DDRA = 0x00; // делаем ПОРТУ всех входов
ПОРТА = 0xFF; // разрешаем все подтягивания
data = PINA; // считываем выводы PORTA в переменные данные
PORTB настроен на три состояния входов:
DDRB = 0x00; // делаем PORTB все входы
PORTB = 0x00; // отключаем подтягивания и переводим все контакты в трехфазное состояние
PORTA нижний ниббл задан как выходы, верхний ниббл как входы с включенными подтягиваниями:
DDRA = 0x0F; // вывод более низких выводов, ввод более высоких выводов
ПОРТА = 0xF0; // выходные контакты установлены в 0, входные контакты позволяют подтягивать
Доступен пример проекта, управляющий выводом ввода / вывода вместе с простой отладкой.
Проект цифрового ввода-выводана AVR Xplained 328PB
Пример проекта, упомянутый в видео
[| Пример ввода / вывода со ссылкой на видео]]
Переключение между входом и выходом
При переключении между трехсостоянием ({DDxn, PORTxn} = 0b00) и высоким выходом ({DDxn, PORTxn} = 0b11) , промежуточное состояние с включенным подтягиванием {DDxn, PORTxn} = 0b01 ) или выходной низкий уровень ({DDxn, PORTxn} = 0b10) должно произойти.
Обычно состояние с включенным подтягиванием полностью приемлемо, поскольку среда с высоким импедансом не заметит разницы между сильным высоким драйвером и подтягиванием. Если это не так, бит PUD в регистре MCUCR может быть установлен для отключения всех подтягиваний во всех портах.
Переключение между входом с подтягиванием и низким выходом создает ту же проблему. В качестве промежуточного шага необходимо использовать либо трехуровневое состояние
({DDxn, PORTxn} = 0b00) , либо высокое выходное состояние ({DDxn, PORTxn} = 0b11).
Отключить отмену подтягиваний
Бит запрета подтягивания PUD в регистре MCUCR может отменять настройки DDRx и PORTx .
Когда этот бит записан в единицу, подтягивания в портах ввода / вывода отключены, даже если регистры DDxn и PORTxn настроены на включение подтягиваний ({DDxn, PORTxn} = 0b01) .
Переключение контакта ввода / вывода
Запись «1» в PINxn переключает значение PORTxn независимо от значения DDRxn.Инструкцию по сборке SBI можно использовать для переключения одного единственного бита в порту.
Не подключенные контакты
Если некоторые контакты не используются, мы рекомендуем вам убедиться, что эти контакты имеют определенный уровень, даже если большинство цифровых входов отключены в режимах глубокого сна. Следует избегать плавающих входов, чтобы снизить потребление тока во всех других режимах, в которых включены цифровые входы (сброс, активный режим и режим ожидания).
Самый простой способ обеспечить определенный уровень неиспользуемого штифта — включить внутреннее подтягивание.В этом случае подтягивание будет отключено во время сброса. Если важно низкое энергопотребление во время сброса, мы рекомендуем использовать внешний подтягивающий или понижающий. НЕ рекомендуется подключать неиспользуемые контакты напрямую к VCC или GND, поскольку это может вызвать чрезмерные токи, если контакт случайно настроен как выход.
Проект электронной машины для голосования (EVM) на базе микроконтроллераAVR со схемой и кодом
Всякий раз, когда мы идем голосовать на выборах, мы приходим к электронным машинам для голосования.В этом проекте мы собираемся спроектировать и разработать простую машину для голосования с использованием микроконтроллера ATmega32A . Хотя мы можем использовать контроллер, чтобы получить машину для голосования более 32 человек, для простоты мы собираемся сделать систему голосования для четырех человек. У нас будет четыре кнопки для четырех человек, и всякий раз, когда нажимается кнопка, Голосование идет за соответствующего человека, и количество голосов, поданных каждым человеком, отображается на ЖК-дисплее.
Необходимые компонентыОборудование:
АТМЕГА32
Блок питания (5в)
ПРОГРАММАТОР AVR-ISP
JHD_162ALCD (ЖК-дисплей 16×2)
Конденсатор 100 нФ (пять штук), конденсатор 100 мкФ (подключен к источнику питания)
кнопка (пять штук),
Резистор10КОм (пять штук).
Программное обеспечение:
Атмель студия 6.1
прогисп или флеш магия.
Принципиальная схема и рабочее объяснениеКак показано на приведенной выше схеме электронного устройства для голосования , PORTA микроконтроллера ATMEGA32 подключается к порту данных ЖК-дисплея 16×2. Здесь следует не забыть отключить связь JTAG в PORTC ATMEGA, изменив байты предохранителя, если кто-то хочет использовать PORTC в качестве обычного порта связи.В ЖК-дисплее 16×2 всего 16 контактов, если есть подсветка, если нет подсветки, будет 14 контактов. Можно включить или оставить контакты подсветки. Теперь в 14 контактах 8 контактов данных (7-14 или D0-D7), 2 контакта источника питания (1 и 2 или VSS и VDD или gnd & + 5v), 3 контакта rd для контроля контрастности (VEE-контролирует толщину символов. должен быть показан), 3 контакта управления (RS, RW и E).
В схеме вы можете заметить, что я взял только два управляющих контакта, так как это дает гибкость для лучшего понимания.Бит контраста и READ / WRITE используются нечасто, поэтому их можно замкнуть на массу. Это переводит ЖК-дисплей в режим максимальной контрастности и чтения. Нам просто нужно управлять контактами ENABLE и RS, чтобы отправлять символы и данные соответственно.
Подключения, которые выполняются для ЖК-дисплея, приведены ниже:
PIN1 или VSS — земля
PIN2 или VDD или VCC — питание +5 В
PIN3 или VEE — заземление (дает максимальный контраст лучше всего для новичков)
PIN4 или RS (выбор регистра) — PD6 uC
PIN5 или RW (чтение / запись) — земля (переводит ЖК-дисплей в режим чтения, что упрощает обмен данными для пользователя)
PIN6 или E (включить) — PD5 uC
PIN7 или D0 — PA0 из uC
PIN8 или D1 — PA1 из uC
PIN9 или D2 — PA2 из uC
PIN10 или D3 — PA3 из uC
PIN11 или D4 — PA4 uC
PIN12 или D5 — PA5 из uC
PIN13 или D6 — PA6 из uC
PIN14 или D7 — PA7 из ОК
В схеме вы можете видеть, что мы использовали 8-битную связь (D0-D7), однако это не обязательно.Мы можем использовать 4-битную связь (D4-D7), но с 4-битной коммуникационной программой становится немного сложнее, поэтому я просто выбрал 8-битную связь.
Итак, просто наблюдая за таблицей выше, мы подключаем 10 контактов ЖК-дисплея к контроллеру, в котором 8 контактов — это контакты данных, а 2 контакта — для управления. Здесь присутствуют пять кнопок, четыре для увеличения голосов кандидатов и пятая для обнуления голосов кандидата.
Конденсаторы, представленные здесь, предназначены для устранения дребезга кнопок.Если их удалить, контроллер может считать больше одного при каждом нажатии кнопки. Резисторы, подключенные к контактам, предназначены для ограничения тока, когда кнопка нажата, чтобы опустить контакт к земле.
Всякий раз, когда нажимается кнопка, соответствующий вывод контроллера опускается на землю, и, таким образом, контроллер распознает, что определенная кнопка нажата, и соответствующее действие должно быть предпринято, это может быть увеличение голосов кандидатов или сброс голосов в зависимости от нажатой кнопки.
Когда кнопка, представляющая соответствующего человека, нажата, контроллер выбирает ее и увеличивает номер соответствующего человека в своей памяти, после того, как приращение показывает соответствующее количество людей на ЖК-дисплее 16×2.
Работа этой электронной машины для голосования на базе микроконтроллера объясняется шаг за шагом кода C ниже,
Сетевые ресиверы Denon AVR— домашний помощник
Платформа denonavr
позволяет управлять сетевыми приемниками Denon с помощью Home Assistant.Возможно, ваше устройство поддерживается платформой Denon.
Известных поддерживаемых устройств:
- Denon AVR-X1000
- Denon AVR-X1100W
- Denon AVR-X1200W
- Denon AVR-X1300W
- Denon AVR-X1400H
- Denon AVR-X1500H
- Denon AVR-X1600H
- Denon AVR-X2000
- Denon AVR-X2100W
- Denon AVR-X2200W
- Denon AVR-X2300W
- Denon AVR-X2400H
- Denon AVR-X2500H
- Denon AVR-X2700H
- Denon AVR-X3000
- Denon AVR-X3200W
- Denon AVR-X3300W
- Denon AVR-X3400H
- Denon AVR-X3600H
- Denon AVR-X3700H
- Denon AVR-X4100W
- Denon AVR-X4300H
- Denon AVR-X4400H
- Denon AVR-X4500H
- Denon AVR-X6500H
- Denon AVR-1912
- Denon AVR-2312CI
- Denon AVR-3311CI
- Denon AVR-3312
- Denon AVR-3313CI
- Denon AVR-4810
- Denon AVR-S650H
- Denon AVR-S710W
- Denon AVR-S720W
- Denon AVR-S750H
- Denon AVR-S960H
- Denon DN-500AV Модель
- Marantz M-CR510 Модель
- Marantz M-CR511 Модель
- Marantz M-CR603 Модель
- Marantz M-CR610 Модель
- Marantz M-CR611
- Маранц SR5006
- Маранц SR5008
- Marantz SR5011
- Marantz SR6007 — SR6012
- Marantz SR8015
- Marantz NR1504
- Marantz NR1506
- Marantz NR1602
- Marantz NR1604
- Marantz NR1607
- Marantz NR1710
- Другие ресиверы Denon AVR (непроверенные)
- Ресиверы Marantz (опытные)
Если вашей модели нет в списке, протестируйте ее, если все работает правильно, добавьте ее в список, щелкнув ссылку Изменить эту страницу на GitHub выше.
Если у вас есть что-то еще, использующее IP-контроллер для вашего Denon AVR 3808CI, например, ваш контроллер URC, он не будет работать! В некоторых моделях есть ошибка или проблема с безопасностью, когда только одно устройство может управлять функциями IP.
Конфигурация
Добавление сетевых ресиверов Denon AVR в экземпляр Home Assistant может быть выполнено через пользователя. интерфейс, используя эту кнопку Моя:
Сетевые ресиверы Denon AVRмогут быть автоматически обнаружены Home Assistant.Если экземпляр был найден, он будет отображаться как «Обнаружен» , который вы можете выбрать, чтобы правильно настроить прочь.
Шаги ручной настройкиЕсли ничего не обнаружено автоматически, не волнуйтесь! Вы можете настроить ввод вручную для интеграции:
- Перейдите к своему экземпляру Home Assistant.
- На боковой панели щелкните Конфигурация .
- В меню конфигурации выберите: Интеграции .
- В правом нижнем углу нажмите на Добавить интеграцию , кнопка.
- В списке найдите и выберите «Сетевые ресиверы Denon AVR» .
- Следуйте инструкциям на экране, чтобы завершить настройку.
IP-адрес устройства, например 192.168.1.32. Если не установлен, используется автоматическое обнаружение.
Если True, все источники отображаются в списке источников, даже если они отмечены как удаленные в приемнике.Если False, удаленные источники не отображаются. У некоторых приемников есть ошибка, которая помечает все источники как удаленные в интерфейсе. В этом случае этот вариант может помочь.
Указывает, должна ли быть активирована зона 1. Зоны отображаются как дополнительные медиаплееры с той же функциональностью, что и основная зона устройства.
Указывает, должна ли быть активирована зона 2. Зоны отображаются как дополнительные медиаплееры с той же функциональностью, что и основная зона устройства.Некоторые ресиверы не поддерживают вторую зону.
Указывает, следует ли обновить настройки Audyssey. Для некоторых приемников это может занять до 10 секунд.
Несколько примечаний:
- Дополнительной возможностью управления ресиверами Denon AVR со встроенным веб-сервером является использование интерфейса HTTP с платформой
denonavr
. - Платформа
denonavr
поддерживает некоторые дополнительные функции, такие как обложки альбомов, пользовательские имена источников ввода и автоматическое обнаружение. Приемники - Marantz, похоже, имеют довольно похожий интерфейс. Таким образом, если у вас есть один, попробуйте.
- Для удаленного включения приемников Marantz с помощью Home Assistant в настройках приемника должна быть включена функция автоматического перехода в режим ожидания.
- Звуковой режим: команда для установки определенного звукового режима отличается от значения текущего звукового режима, сообщаемого приемником (sound_mode_raw). Существует структура «ключ-значение» (sound_mode_dict), которая сопоставляет режим сырого звука с одной из возможных команд для установки режима звука (например, {‘MUSIC’: [‘PLII MUSIC’]}.Если вы получили предупреждение «Не удается сопоставить звуковой режим», откройте проблему в библиотеке denonavr, указав, какой режим необработанного звука не может быть сопоставлен, чтобы его можно было добавить в соответствующий словарь. Вы можете найти текущий режим сырого звука в Developer Tools -> States .
Ресиверы
Denon AVR поддерживают простой текстовый сетевой интерфейс для отправки команд приемнику по сети. Вы можете получить доступ к этому интерфейсу через denonavr .get_command
сервис. Кроме того, на этот интерфейс можно отправлять коды дистанционного управления через ИК-порт.
Список сетевых команд, поддерживаемых различными ресиверами Denon AVR, можно найти здесь. Список ИК-кодов можно найти здесь.
Чтобы использовать эти команды, вызовите службу denonavr.get_command
и добавьте конкретную команду к пути /goform/formiPhoneAppDirect.xml?
:
Атрибут служебных данных | Дополнительно | Описание |
---|---|---|
entity_id | № | Имя объекта, которому нужно отправить команду.Например media_player.marantz |
команда | № | Команда для отправки на устройство, например, /goform/formiPhoneAppDirect.xml?VSMONI2 |
Так, например, приведенная выше команда /goform/formiPhoneAppDirect.xml?VSMONI2
переключит HDMI на выход 2 (если ваш ресивер поддерживает это). Отправка ИК-кода работает так же, поэтому команда /goform/formiPhoneAppDirect.xml?RCKSK0410370
включает отключение звука.
Платформа denonavr поддерживает стандартные элементы управления медиаплеером, такие как turn_on
и volume_up
. Таким образом, вызов службы media_player.turn_on
эквивалентен вызову denonavr.get_command
с командой /goform/formiPhoneAppDirect.xml?PWON
. См. Media_player для более подробной информации.
Включение или отключение настройки DynamicEQ.
Атрибут служебных данных | Дополнительно | Описание |
---|---|---|
entity_id | да | Имя объекта, которому нужно отправить команду.Например media_player.marantz |
dynamic_eq | № | Истина / ложь для включения / выключения. |
Обновите настройки Audyssey. Для некоторых приемников это может занять до 10 секунд.
Атрибут служебных данных | Дополнительно | Описание |
---|---|---|
entity_id | да | Имя объекта, которому нужно отправить команду.Например media_player.marantz |
Разница между прерыванием и опросом
Прерывание:
Прерывание — это аппаратный механизм, в котором устройство замечает CPU, что оно требует его внимания. Прерывание может произойти в любой момент. Таким образом, когда ЦП получает сигнал прерывания через строку запроса прерывания индикации, ЦП останавливает текущий процесс и отвечает на прерывание, передав управление обработчику прерывания, который обслуживает устройство.
Опрос:
Опрос — это не аппаратный механизм, это протокол, в котором ЦП постоянно проверяет, требует ли устройство внимания. Везде, где устройство сообщает блоку процесса, что ему нужна аппаратная обработка, при опросе блок процесса продолжает спрашивать устройство ввода-вывода, требуется ли ему обработка ЦП. ЦП непрерывно проверяет каждое подключенное к нему устройство на предмет выявления того, требует ли какое-либо устройство внимания со стороны оборудования.
Каждое устройство имеет бит готовности команды, который указывает состояние этого устройства, т.е.е., есть ли какая-то команда быть мертвой аппаратно или нет. Если бит команды готов, то это некоторая команда, которая не работает, иначе, если бит равен нулю, то это не команды.
Давайте посмотрим, что разница между прерыванием и опросом:
S.NO | Прерывание | Опрос |
---|---|---|
1. | В прерывании устройство замечает, что процессор требует внимание. | Принимая во внимание, что при опросе ЦП постоянно проверяет, требует ли устройство внимания. |
2. | Прерывание — это не протокол, это аппаратный механизм. | Хотя это не аппаратный механизм, это протокол. |
3. | При прерывании устройство обслуживается обработчиком прерывания. | Во время опроса устройство обслуживается ЦП. |
4. | Прерывание может произойти в любое время. | В то время как ЦП постоянно проверяет устройство с регулярной или надлежащей периодичностью. |
5. | В прерывании строка запроса прерывания используется как индикатор, указывающий, что устройство требует обслуживания. | Во время опроса бит готовности команды используется как индикация, указывающая на то, что устройство требует обслуживания. |
6. | При прерываниях процессор просто нарушает работу, когда какое-либо устройство его прерывает. | С другой стороны, при опросе процессор тратит бесчисленное количество циклов процессора, многократно проверяя готовность к командам каждого устройства. |
Вниманию читателя! Не прекращайте учиться сейчас. Ознакомьтесь со всеми важными концепциями теории CS для собеседований SDE с помощью курса CS Theory Course по доступной для студентов цене и подготовьтесь к работе в отрасли.
Автоматическая регистрация избирателей — Ballotpedia
На этой странице описаны регулярные правила голосования в 50 штатах. Информация может не относиться к выборам 3 ноября 2020 г. из-за временных изменений в связи с коронавирусом. Нажмите здесь , чтобы прочитать об изменениях, внесенных в выборы 2020 года.Голосование по штатам |
---|
Закон об удостоверениях личности избирателей |
Заочное / заочное голосование |
Голосование по почте |
Досрочное голосование |
Законы о пересчете |
Выберите состояние из меню ниже, чтобы узнать больше. |
AlabamaAlaskaArizonaArkansasCaliforniaColoradoConnecticutDelawareFloridaGeorgiaHawaiiIdahoIllinoisIndianaIowaKansasKentuckyLouisianaMaineMarylandMassachusettsMichiganMinnesotaMississippiMissouriMontanaNebraskaNevadaNew HampshireNew JerseyNew MexicoNew YorkNorth CarolinaNorth DakotaOhioOklahomaOregonPennsylvaniaRhode IslandSouth CarolinaSouth DakotaTennesseeTexasUtahVermontVirginiaWashingtonWest VirginiaWisconsinWyomingSubmit |
ОСОБЕННОСТИ
Автоматическая регистрация избирателей по штату
По состоянию на 23 декабря 2020 года в 20 штатах и округе Колумбия были введены в действие правила автоматической регистрации избирателей. См. Карту ниже. [1] [2]
Поддержка и противодействие
Поддержка
Лиз Кеннеди, Лью Дейли и Бренда Райт в отчете за 2016 год, опубликованном Demos, утверждали, что автоматическая регистрация избирателей способствует гражданскому участию, уменьшая барьеры, которые в противном случае могли бы помешать гражданам осуществлять свои конституционные права на участие в политической жизни: [12]
“ | Наша текущая система регистрации избирателей, разработанная как система «саморегистрации» или инициируемая избирателями, создает препятствия для регистрации, которые не служат какой-либо важной цели в условиях демократии.Демос считает, что полноценное участие в выборах в значительной степени зависит от достижения всеобщей регистрации избирателей с помощью автоматической системы регистрации. Автоматическая регистрация избирателей (AVR) основана на Законе о национальной регистрации избирателей 1993 года (NVRA) и других реформах регистрации избирателей, направленных на повышение общей эффективности системы регистрации избирателей. Автоматическая регистрация избирателей использует информацию, уже хранящуюся в файлах различных государственных органов, для выявления лиц, имеющих право голоса, и добавления их в списки избирателей или обновления информации об избирателях в безбумажном процессе.Благодаря всеобъемлющей и инклюзивной системе AVR у штатов есть возможность сделать большой скачок в праве голоса, построив современную справедливую систему регистрации, которая нам нужна и которую мы заслуживаем. [13] | ” |
—Лиз Кеннеди, Лью Дейли и Бренда Райт |
Центр правосудия Бреннана в отчете за 2017 год утверждал, что автоматическая регистрация избирателей может уменьшить количество ошибок и неэффективность избирательного процесса: [2]
“ | Автоматическая регистрация избирателей вносит два преобразующих, но простых изменения в регистрацию избирателей: правомочные граждане, которые взаимодействуют с государственными органами, регистрируются для голосования, если они не откажутся, и агентства передают информацию о регистрации избирателей в электронном виде должностным лицам избирательных комиссий.Эти два изменения создают плавный процесс, который более удобен и менее подвержен ошибкам как для избирателей, так и для государственных чиновников. Эта политика увеличивает количество регистраций, очищает списки, делает голосование более удобным и снижает вероятность мошенничества с избирателями, при этом снижая затраты. [13] | ” |
— Центр правосудия Бреннана |
Оппозиция
Ханс фон Спаковски в отчете за 2013 год, опубликованном Фондом наследия, утверждал, что автоматическая регистрация избирателей представляет угрозу для честности выборов, поскольку увеличивает вероятность неприемлемого участия в выборах.Он также утверждал, что автоматическая регистрация нарушает конституционные права граждан: [14]
“ | Обязательная регистрация избирателей (MVR), ранее называвшаяся «универсальной» регистрацией, может значительно повредить целостность американской системы регистрации избирателей. Концепция «модернизации регистрации избирателей», предусматривающая автоматическую регистрацию лиц с помощью информации, содержащейся в различных существующих государственных базах данных, привела бы к хаосу в существующей системе.В частности, модернизация системы регистрации избирателей может привести к регистрации большого числа избирателей, не имеющих права голоса, а также к множественной или двойной регистрации одних и тех же лиц. В сочетании с сопутствующим предложением, согласно которому государства разрешают всем лицам, не прошедшим автоматическую регистрацию, регистрироваться и голосовать в день выборов, MVR представляет собой надежную формулу для регистрации и мошенничества с избирателями, которые могут нанести ущерб честности выборов. Автоматическая регистрация людей для голосования без их разрешения также нарушит их основное право выбирать, хотят ли они участвовать в U.С. Политический процесс. В самом деле, эта новая схема угрожает одной из самых заветных свобод американцев: свободе, которую правительство должно оставить в покое. [13] | ” |
—Ганс фон Спаковский |
Эмбер Филлипс, написавшая в 2016 году для The Washington Post , утверждала, что политика автоматической регистрации избирателей может усилить существующее преимущество политической партии в штате: [15]
“ | Автоматическая регистрация избирателей в основном приносит пользу демократам.Или, по крайней мере, это принесет пользу партии, контролирующей государство, которая реализует программу. Когда этой осенью в Калифорнии обсуждалась автоматическая регистрация избирателей, Филип Бамп из The Fix привел доводы в пользу того, что усиление регистрации избирателей в штате, ориентированном на демократов, просто увеличит число избирателей-демократов в большей степени, чем республиканцев. По предварительным данным, именно так и было в Орегоне. Из 437 автоматически зарегистрированных избирателей, которые сделали следующий шаг и фактически заполнили карточку, чтобы выбрать партийную принадлежность, около 49 процентов выбрали Демократическую партию, 30 процентов выбрали республиканскую и 5 процентов выбрали независимую.Госсекретарь Орегона отмечает, что это практически отражает нынешний партийный раскол избирателей в штате. [13] | ” |
—Эмбер Филлипс |
См. Также
- ↑ 1.0 1.1 Национальная конференция законодательных собраний штатов , «Автоматическая регистрация избирателей», 31 августа 2017 г. Ошибка ссылки: Недействительный тег
- ↑ 2.0 2,1 2,2 Центр правосудия Бреннана , «Автоматическая регистрация избирателей», 10 февраля 2018 г. Ошибка цитирования: Недействительный тег
- ↑ Законодательная информация Калифорнии , «AB 1461», по состоянию на 25 марта 2017 г.
- ↑ Управление законодательных исследований Коннектикута , «Автоматическая регистрация избирателей в Коннектикуте», 21 декабря 2017 г.
- ↑ Совет округа Колумбия , «B21-0194 — Поправка к Закону об автоматической регистрации избирателей 2015 г.», по состоянию на 25 марта 2017 г.
- ↑ 6.0 6,1 6,2 Центр правосудия Бреннана , «Автоматическая регистрация избирателей», 17 апреля 2018 г.
- ↑ Законодательное собрание штата Орегон , «Законопроект 2177», по состоянию на 25 марта 2017 г.
- ↑ Генеральная ассамблея Род-Айленда , «H 5702», по состоянию на 20 июля 2017 г.
- ↑ Vermont General Assembly , «H. 458», по состоянию на 25 марта 2017 г.
- ↑ Законодательное собрание штата Вашингтон , «HB 2595 — 2017-18», по состоянию на 17 мая 2017 г.
- ↑ Законодательное собрание Западной Вирджинии , «Законопроект 4013», по состоянию на 25 марта 2017 г.
- ↑ Demos , «Автоматическая регистрация избирателей; поиск пропавших без вести избирателей в Америке», 20 января 2016 г.
- ↑ 13.0 13,1 13,2 13,3 Примечание: этот текст дословно цитируется из первоисточника. Любые несоответствия относятся к первоисточнику.
- ↑ The Heritage Foundation , «Обязательная регистрация избирателей: как универсальная регистрация угрожает честности выборов», 27 марта 2013 г.
- ↑ The Washington Post , «Как спорить об автоматической регистрации избирателей, пока Орегон набирает обороты», 13 февраля 2016 г.
Harman Kardon AVR 260 Руководство пользователя — Страница 19 из 54
19
АНГЛИЙСКИЙ
КОНФИГУРАЦИЯ СИСТЕМЫ
Выбор аудио и видео входа
Заводские настройки входов по умолчанию
см. В Таблице A1 в приложении. каждый источник.Вы можете назначить любой доступный вход любому источнику с помощью меню информации об источнике
, доступ к которому можно получить, нажав кнопку настроек АРН W
и выбрав строку «Настройка источника», или нажав кнопку «Информация о настройках»
W
для прямого доступа.
Когда выбран источник, AVR проверяет назначенный цифровой аудиовход
на наличие сигнала. Если он присутствует, будет выбран цифровой вход. В противном случае AVR
выберет аналоговый аудиовход, указанный в строке Audio Auto Polling в
меню Setup Source.Если вы не хотите, чтобы AVR выбирал аналоговый аудиовход
для источника, измените эту настройку на Off.
AVR также выберет назначенный источник видеосигнала. В AVR нет источников «только аудио»
, кроме радио, которое использует специальное экранное меню
. Если видеосигнал отсутствует, дисплей останется черным. Вы можете
выполнить сопряжение аудиоустройства с видеосигналом аудио / видео устройства с помощью меню «Информация об источнике»
, как описано в разделе «Начальная настройка».Источники могут совместно использовать аудиовходы или видеовходы
в соответствии с вашим приложением.
Настройка источников
Меню «Информация об источнике» используется для назначения правильных физических аудио- и видеосоединений
каждому источнику. Он также обеспечивает доступ к множеству других настроек
, многие из которых могут быть изменены позже, когда вы более знакомы с
с AVR.
Следующие настройки не являются необязательными и должны быть скорректированы сейчас, чтобы включить воспроизведение
каждого источника: видеовход от источника, аудиовход от источника
и разрешение для отображения.
Другие настройки можно изменить в любое время для повышения производительности.
Чтобы отобразить меню «Информация об источнике», нажмите кнопку «Параметры информации» (на передней панели
7
или на пульте дистанционного управления W). Появится экран, аналогичный показанному на рисунке 2.
К этому экрану также можно получить доступ из главного меню, выбрав строку Setup
Source и выбрав источник из выдвигающегося меню.
Рисунок 2 — Меню источника настройки
Звуковые эффекты : Выберите эту строку, чтобы отобразить подменю «Звуковые эффекты»,
, где вы можете: настроить элементы управления низкими и высокими частотами; отрегулируйте триммер LFE;
активируйте сохраненные настройки EzSet / EQ или настройте ночной режим.
рекомендуется оставить в этом подменю с настройками по умолчанию и вернуть в него
позже, если ваша система требует какой-либо тонкой настройки. См. Раздел «Дополнительные функции
» для получения дополнительной информации.
Видеорежимы : Выберите эту строку, чтобы отобразить подменю «Видеорежимы», где
вы выбираете из предварительно запрограммированных или пользовательских настроек изображения и выполняете настройки изображения
. Рекомендуется оставить заводские настройки
по умолчанию. Сначала необходимо настроить изображение на видеодисплее, а
это меню используется только для точной настройки.См. Дополнительную информацию в разделе «Расширенные функции» для
.
Surround Mode : Выберите эту строку, чтобы отобразить подменю Surround Mode,
, где вы можете запрограммировать желаемый режим объемного звука для различных типов аналоговых программ
, включая фильмы, музыку и игры. Вы также можете указать
конкретный стереорежим (в зависимости от количества желаемых каналов) и режим виртуального объемного звучания
, если ваша система использует меньше, чем полный набор из семи основных динамиков
(плюс сабвуфер).
Цифровые сигналы объемного звука, такие как программы Dolby Digital и DTS,
автоматически воспроизводятся в их собственных форматах, хотя вы можете изменить
режим объемного звука в любое время. Информацию о режимах объемного звука, доступных в цифровых программах, см. В разделе «Расширенные функции»
.
В заводском режиме автоматического выбора по умолчанию AVR проанализирует исходный сигнал
и выберет оптимальный режим воспроизведения. На заводе AVR
был запрограммирован на использование режима Logic 7 Movie для оптимального воспроизведения фильмов,
включая телевизионные программы; Logic 7 Music режим для музыкальных записей, например
как компакт-диски; и режим Logic 7 Game при использовании игровой приставки.
Аудиоформат из источника : Эта строка носит исключительно информационный характер. Когда воспроизводится цифровая программа
, здесь указывается ее формат. Когда воспроизводятся аналоговые аудиопрограммы
, эта строка указывает НЕТ АУДИОВХОДА, имея в виду только цифровые входы
.
Видеовход от источника : Выберите эту строку, чтобы назначить источнику правильный видеовход
. Вернитесь к Таблице A5 в приложении, где вы отметили
физический видеовход, к которому подключен источник, и выберите здесь вход.
Аудиовход от источника : Выберите эту строку, чтобы назначить источнику правильный аналоговый
или цифровой аудиовход. Вернитесь к Таблице A5 в приложении,
, где вы отметили физический аудиовход, к которому подключен источник, и
выберите здесь вход. Если были выполнены и аналоговые, и цифровые аудиоподключения
, выберите здесь цифровой вход и выберите аналоговый вход в строке Audio
Auto Polling ниже.
ПРИМЕЧАНИЕ : Для источников, подключенных к входу HDMI, настройки видео- и аудиовхода
должны указывать на одно и то же подключение HDMI.
Разрешение дисплея : Эта строка отражает разрешение вывода видео,
, которое зависит от возможностей видеодисплея.
ПРИМЕЧАНИЕ : При использовании системы экранного меню AVR мы рекомендуем
выбрать разрешение видеовыхода 720p или выше для лучшей читаемости и
для предоставления графики, упрощающей некоторые параметры конфигурации. В зависимости от выбранного разрешения
меню, отображаемое вашей системой, может отличаться по внешнему виду
.
Если дисплей подключен к композитному или S-Video монитору AVR
•
Output, разрешение вывода видео должно быть вручную установлено на 576i для просмотра
любого контента, включая собственные меню AVR. Разрешение AVR по умолчанию
установлено на 576i.
Поскольку изображение отсутствует, если разрешение установлено выше, чем возможности дисплея
, или если система HDMI не выбирает автоматически наилучшее разрешение
, в этих случаях необходимо отрегулировать разрешение, нажав кнопку разрешения
на передней панели. затем нажимайте кнопки вверх / вниз 3, пока правильная настройка
не появится в нижней строке дисплея сообщений
на передней панели, и подтвердите нажатием кнопки OK 5.На дисплее теперь отображается ОТМЕНА, и вы должны прокрутить
, чтобы отобразить на дисплее ПРИНЯТЬ с помощью кнопок вверх / вниз 3
, а затем нажмите OK, чтобы новое разрешение вступило в силу.