Site Loader

Содержание

Подключение кнопки к AVR — Практическая электроника

Подключение кнопки к AVR не должно у вас вызывать никаких трудностей.

В предыдущей статье мы провели эмуляцию схемы в программе Proteus, помигали светодиодом и научились прошивать наш виртуальный микроконтроллер. Наверняка многим из читателей пришла в голову мысль: «А можно ли помигать светодиодом, использую кнопку, подключенную к МК?

Да, разумеется, это возможно. Реализуется довольно легко. Причем можно сэмулировать кнопку как с фиксацией так и без фиксации. Причем в программе 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 — номера бит к которым подключены кнопки, внимание в константах именно номера бит!!


внешние переменные (размещаются в DSEG, изменяются другой подпрограммой)
  • COUNTER — переменная в DSEG: счетчик
    интервалов, от 20 до 100 гц (в принципе любой частоты, изменяется в
    пределах 0..255 циклически)


переменные драйвера (размещаются в DSEG):
  • 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Время работы двигателя в режиме автозапуска, мин5101520
2Температура окружающей среды для пуска мотора-5-10-20-30
3Время прокручивания стартерного механизма при дистанционном старте двигателя, мс800120018003000
4Контроль работы силового агрегата при автозапускеПо напряжению в электросети автоПо показаниям контроллера давления маслаПо тахометру (требуется программирование холостых оборотов)
5Время работы второго дополнительного канала, с0,81030Постоянный сигнал
6Время работы сигналов сирены или рулевого гудка, мс100101520
7Управление центральным замком при дистанционном запускеЗамки включены и не закрываютсяЗамки отключены и не запираютсяЗамки включены и закрываютсяЗамки отключены и запираются
8Задержка активации стартерного механизма, с2, рекомендовано для бензиновых моторов10, для дизельных силовых агрегатов1010
9Длина сигнала на отпирание и запирание центрального замка, с0,8 на открытие и закрытие3,6 на запирание и отпирание0,8 на закрытие и двойной сигнал по 0,8 на открытиеСигнал запирания — 30, отпирания — 0,8
10Управление блокиратором двигателя или дополнительным каналомИммобилайзер отключен, дополнительный канал работаетБлокиратор выключен, двухэтапное открытие дверных замковБлокиратор включен, третий дополнительный канал работаетДвухэтапное открытие дверных замков при включенном иммобилайзере
11Безопасное вождение транспортного средстваДверные замки не закрываются, но открываются при отключении зажиганияЗакрытие замков в дверях производится через 10 с после включения зажигания, открываются сразуЗакрытие производится через 30 секунд после включения, открытие — моментально
12Автоматическая постановка на защитуФункция отключенаОпция активирована без закрытия дверных замковФункция включена с запиранием дверей
13Учет задержки при работе салонной системы освещения, с1153045
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 .
Сервис denonavr.get_command
Ресиверы

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 для более подробной информации.

Сервис denonavr.set_dynamic_eq

Включение или отключение настройки DynamicEQ.

Атрибут служебных данных Дополнительно Описание
entity_id да Имя объекта, которому нужно отправить команду.Например media_player.marantz
dynamic_eq Истина / ложь для включения / выключения.
Сервис denonavr.update_audyssey

Обновите настройки 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

В рамках автоматической системы регистрации избирателей правомочные избиратели автоматически регистрируются для голосования всякий раз, когда они взаимодействуют с государственными органами (например,г., отделы автотранспортных средств). Избиратели, имеющие право голоса, регистрируются по умолчанию, хотя они могут попросить не регистрироваться. [1] [2]

ОСОБЕННОСТИ

  • По состоянию на 23 декабря 2020 г. 20 штатов и округ Колумбия ввели в действие правила автоматической регистрации избирателей.
  • В 2015 году Калифорния и Орегон стали первыми штатами, в которых были введены правила автоматической регистрации избирателей.
  • В 2016 году Аляска стала первым штатом, который ввел в действие политику автоматической регистрации избирателей с помощью бюллетеней.
  • Автоматическая регистрация избирателей по штату

    По состоянию на 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. 1.0 1.1 Национальная конференция законодательных собраний штатов , «Автоматическая регистрация избирателей», 31 августа 2017 г. Ошибка ссылки: Недействительный тег ; имя «ncsl» определено несколько раз с разным содержанием
    2. 2.0 2,1 2,2 Центр правосудия Бреннана , «Автоматическая регистрация избирателей», 10 февраля 2018 г. Ошибка цитирования: Недействительный тег ; имя «brennancenter» определено несколько раз с разным содержанием
    3. Законодательная информация Калифорнии , «AB 1461», по состоянию на 25 марта 2017 г.
    4. Управление законодательных исследований Коннектикута , «Автоматическая регистрация избирателей в Коннектикуте», 21 декабря 2017 г.
    5. Совет округа Колумбия , «B21-0194 — Поправка к Закону об автоматической регистрации избирателей 2015 г.», по состоянию на 25 марта 2017 г.
    6. 6.0 6,1 6,2 Центр правосудия Бреннана , «Автоматическая регистрация избирателей», 17 апреля 2018 г.
    7. Законодательное собрание штата Орегон , «Законопроект 2177», по состоянию на 25 марта 2017 г.
    8. Генеральная ассамблея Род-Айленда , «H 5702», по состоянию на 20 июля 2017 г.
    9. Vermont General Assembly , «H. 458», по состоянию на 25 марта 2017 г.
    10. Законодательное собрание штата Вашингтон , «HB 2595 — 2017-18», по состоянию на 17 мая 2017 г.
    11. Законодательное собрание Западной Вирджинии , «Законопроект 4013», по состоянию на 25 марта 2017 г.
    12. Demos , «Автоматическая регистрация избирателей; поиск пропавших без вести избирателей в Америке», 20 января 2016 г.
    13. 13.0 13,1 13,2 13,3 Примечание: этот текст дословно цитируется из первоисточника. Любые несоответствия относятся к первоисточнику.
    14. The Heritage Foundation , «Обязательная регистрация избирателей: как универсальная регистрация угрожает честности выборов», 27 марта 2013 г.
    15. 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, чтобы новое разрешение вступило в силу.

    alexxlab

    Добавить комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *