201302021511


Level 1. Архитектура Микроконтроллера AqA (упрощенный PIC16).

  +-----+-----+----------+---------------+-------------------+
  |Адрес|Мнемо|Нач. знач.|Имя            |Перевод            |
  +-----+-----+----------+---------------+-------------------+
  |     |     | 76543210 |               |                   |
  | нет |  W  |[00000000]|Work Register  |Рабочий регистр    |
  |     |     |          |               |                   |
  |     |     | 76543210 |               |                   |
  | нет | PC  |[00000000]|Program Counter|Счетчик команд     |
  |     |     |          |               |                   |
  |     |     |  76543210|               |                   |
  | нет | SP  |[11110111]|Stack Pointer  |Указатель стека    |
  |     |     |          |               |                   |
  |     |     |      ZTC |               |                   |
  | нет | SR  |[00000000]|Status Register|Регистр флажков    |
  |     |     |          |               |                   |
  | 0 - |     | 16 / 08  |Register File  |Файл регистров     |
  | f7h |     |cmd  data |               |общего назначения  |
  |     |     |          |               |                   |
  |     |     | 76543210 |               |                   |
  | f8h | TRSA|[00000000]|TRIS A         |Направление данных |
  |     |     |          |               |порта A (i1/O0)    |
  |     |     | 76543210 |               |                   |
  | f9h | PRTA|[00000000]|Port A         |Порт A             |
  |     |     |          |               |                   |
  |     |     | 76543210 |               |                   |
  | fah | TRSB|[00000000]|TRIS B         |Направление данных |
  |     |     |          |               |порта B (i1/O0)    |
  |     |     | 76543210 |               |                   |
  | fbh | PRTB|[00000000]|Port B         |Порт B             |
  |     |     |          |               |                   |
  |     |     | 76543210 |               |                   |
  | fch | TRSC|[00000000]|TRIS C         |Направление данных |
  |     |     |          |               |порта C (i1/O0)    |
  |     |     | 76543210 |               |                   |
  | fdh | PRTC|[00000000]|Port C         |Порт C             |
  |     |     |          |               |                   |
  |     |     | 76543210 |               |                   |
  | feh | PRE |[00000001]|Prescaler      |Коэффициент таймера|
  |     |     |          |               |                   |
  |     |     | 76543210 |               |                   |
  | ffh | TMR |[00000000]|Timer          |Встроенный таймер  |
  +-----+-----+----------+---------------+-------------------+


Пример. Все команды.

  +-------+-------------------------+------------------------+
  | Aдрес | Метка  Команда  Операнд ; Код операции           |
  +-------+-------------------------+------------------------+
  | 0000  | xx:    db       0x12    ; 0012                   |
  | 0001  |        nop              ; 0000                   |
  | 0002  |        inc      0xe4    ; 0ae4 [e4] теперь 0x01  |
  | 0003  |        dec      0xe5    ; 03e5 [e5] теперь 0xff* |
  | 0004  |        addw     0xe6    ; 3ee6 [w ] теперь 0xe6  |
  | 0005  |        subw     0xe7    ; 3ce7 [w ] теперь 0xff  |
  | 0006  |        andw     0xe8    ; 39e8 [w ] теперь 0xe8  |
  | 0007  |        orw      0xe9    ; 38e9 [w ] теперь 0xe9  |
  | 0008  |        xorw     0xea    ; 3aea [w ] теперь 0x03  |
  | 0009  |        jmp      yy      ; 280a                   |
  | 000a  | yy:    jpz      zz      ; 290b                   |
  | 000b  | zz:    jpc      0x0c    ; 2a0c                   |
  | 000c  |        movw     0xee    ; 30ee [w ] теперь 0xee  |
  | 000d  |        movwr    0xeb    ; 01eb [eb] теперь 0xee  |
  | 000e  |        movrw    xx      ; 0800 [w ] теперь 0x12  |
  | 000f  |        call     ww      ; 2010 [sp] теперь 0xf6  |
  | 0010  | ww:    ret              ; 0800 [sp] теперь 0xf7  |
  +-------+-------+-----------------+------------------------+
  | *) из-за ошибки в симуляторе образован т.н. эксплойт,    |
  |    реальный симулятор устанавливает в ячейку [e5]        |
  |    значение  0xffff, изменяя  таким образом код операции,|
  |    что позволяет программно модифицировать любую команду,|
  |    типичная тактика "хакеров" при написании вирусов и    |
  |    троянов.                                              |
  +----------------------------------------------------------+

Как пользоваться симулятором
---------------------------

  http://softwareforeducation.com
       /wikilekiextra/AQA-Assembler-Simulator.swf

  - Введите код или скопируйте и вставьте его.
  - Нажмите кнопку "A", чтобы собрать код (перевести его
    в двоичный).
  - Нажмите кнопку "S" для пошагового выполнения программы.
  - Нажмите кнопку "/", чтобы запустить программу. 
    Несколько щелчков левой кнопкой мыши увеличит скорость 
    процессора (см. поле Clock Frequency на эмуляторе).
  - Нажмите кнопку "\" для уменьшения скорости процессора.

----------
  
Набор команд

Содержание

  1 AQA RISC процессор
  2 Понимание этой таблицы
  3 Пример для начинающих
    3.1 Мнемоника
    3.2 Операнды
  4 Описание
  5 Эксплуатация
  6 Флажки
  7 Тактовые циклы
  8 K и [R]


AQA RISC процессор

Полный список инструкций, которые понимает процессор.

  - Традиционные процессоры компьютеров это чипы с полным набором команд (CISC), включающих в себя сотни команд.
    
  - Микроконтроллеры это чипы с уменьшенным набором инструкций (RISC). Чип AQA имеет только шестнадцать команд.
    
  - Микроконтроллеры имеют так мало инструкций, что не займет много времени, чтобы изучить их все.
    
  - Команды также очень просты, наподобие:
  
      "Скопировать номер из поля A в поле B".
      "Добавить один в поле W."

Набор команд.

---------------------------------------------------------------
Мнемоника Операнды Описание            Операция      Флажки Clk
---------------------------------------------------------------
----[пустая]------
NOP       нет      Нет операции        нет            нет    1

----[избыточные]--
INC       R        Увеличивает         [R] <- [R] +1  Z      1
                   содержимое R                     
DEC       R        Уменьшает           [R] <- [R] -1  Z      1
                   содержание R
                   
----[функции,2]---
CALL      К        Вызов подпрограммы  [SP] <- PC     нет    2
                                           PC <-K
RET       нет      Возврат из подпрог.  PC <- [SP]    нет    2

----[арифметика,5]
ADDW      K        K Добавить в W       W <- W + K    ZC     1
ANDW      К        "и" К с W            W <- W & K    ZC     1
SUBW      K        K вычесть из W       W <- W-K      ZC     1
ORW       К        "или" K с W          W <- W | K    ZC     1
XORW      K        "xor" K с W          W <- W ^ K    ZC     1

----[прыжки,3]----
JMP       K        Перейти к K (GOTO)   PC <- K       нет    2
JPZ       K        Перейти к K если 0   PC <- К, если Z = 1  2
JPC       K        Перейти к К если     PC <- К, если С = 1  2
                   был перенос
                   
----[переносы,3]--
MOVWR     R        Переместить W в [R] [R] <- W       Z      1
MOVW      K        Переместить K в W    W <- K        Z      1
MOVRW     R        Переместить          W <- [R]      Z      1
                   содержимое [R] в W
---------------------------------------------------------------


Пример для начинающих

Процессор содержит регистр с именем "W", рабочий регистр. Это просто поле, где вы можете хранить числа. Существует мнемоника ADDW. Эта команда добавляет число к тому, что хранится в "W". ADDW имеет один операнд. Это число, которое будет добавлено к W. Если вы хотите добавить "1", симулятор ожидает все числа в шестнадцатеричном формате, так что вы должны ввести 0x1.

  ADDW 0x1
  ADDW 0x2
  ADDW 0x3

Весь этот жаргон и усилия предприняты, чтобы понять, что 0 + 1 + 2 + 3 = 6


Мнемоника

  - Каждая из шестнадцати команд имеет свою легко читаемую человеком мнемонику.
    
  - Каждое мнемонические обозначение представляет собой очень трудно запоминаемый двоичный код, который понятен процессору.
    
Без мнемоники, вы должны изучать и использовать бинарные кодами. Программисты самых первых компьютеров использовали сырые двоичные коды! Ассемблер делает жизнь гораздо проще, переводя понятную человеку мнемонику в двоичные коды.


Операнды

  - Команды выполняют простые задачи.
  - Операнд используется в команде для выполнения своей задачи.
  - В приведенном выше примере, операндами были просто числа, которые добавлялись в "W".
  - Другой часто используемые операнд это номер регистра (адрес), откуда данные считываются или куда записываются.


Операция

Если вы понимаете, что "<-" означает "копируется", колонка "операция" таблицы команд становится яснее. Направление стрелки показывает, что скопироно и куда записывается ответ. Некоторые команды выглядят, как будто что-то копируется в себя. Например ADDW:

  W <= W + K
             
Это означает - добавить K к W и скопивать полученный ответ в W. Исходные данные в W будет перезаписаны (и утрачены). К - это операнд.


Флажки

Процессор имеет регистра статуса (SR), содержащий три флажка. Из приведенной таблицы видно, какие флажки могут быть изменены, когда выполняется каждая из команд.

  - C - флаг переноса. Этот двоичный разряд установлен в единицу, если расчет дает результат слишком большой, чтобы поместиться в восемь бит.
    
  - Т - таймер флага. Он устанавливается, когда таймер достигает нуля после обратного отсчета.
    
  - Z - нулевой флаг. Он устанавливается, когда результат расчета, логической операции или перемещения оставляет 0 в рабочем регистре "W".


Тактовый цикл

  - Большинство команд полностью выполняется за один такт.
  
  - Исключением из этого правила являются команды, которые изменяют содержимое регистр счетчика команд, PC.
    
  - Этот регистр отслеживает с какой инструкцией процессор работает в данный момент.


К и [R]

K, как правило, просто число. Например, в этой команде:
  
  ADDW 0x1 W <= W + K    

K представляет собой число 0x1

Микроконтроллер имеет 256 ячеек памяти называемых файлом регистров. [R] переводится на русский как "содержание регистрового файла по адресу R". Таким образом, команда

  MOVWR 0x12 [R] <= W 
  
означает копирование W в содержимое регистрового файла с адресом 0x12.

----------

Подпрограммы

Содержание

  1 Определение понятия подпрограммы
  2 Примеры
    2.1 Временная задержка
      2.1.1 Метод первый - простой, но не рекомендуется
      2.1.2 Метод второй - заданное время задержки
      2.1.3 Метод третий - переменное время задержки
      2.1.4 Метод четвертый - Использование TMR и PRE


Определение понятия подпрограммы

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

В других языках программирования подпрограммам даются различные имена: процедура: Pascal; функция: C, C + +, Java, C #, PHP; метод: большинство объектно-ориентированных языков; подпрограмма: BASIC, Fortran.

Они выполняют небольшие, четко определенные задачи, такие как: предоставление временной задержки, чтение порта; запись в порт.

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

Пример. Время задержки. Метод первый - простой, но не рекомендуется

Использование нескольких команд NOP, чтобы создать задержку.

  START:
      CALL DELAY
      JMP  START

  DELAY:
      NOP
      NOP
      NOP
      NOP
      RET


Пример. Время задержки. Метод второй - заданное время

  START:
      NOP
      NOP
      NOP
      CALL DELAY
      NOP
      NOP
      JMP  START

  DELAY:
      MOVW 0x10
  REP:
      SUBW 0x1
      JPZ  DONE
      JMP  REP
  DONE:
      RET


Пример. Время задержки. Способ третий - переменное время задержки

  START:
      NOP
      NOP
      MOVW 0x15; установить задержку
      CALL DELAY
      NOP
      NOP
      JMP  START

  DELAY:
      SUBW 0x1
      JPZ  DONE
      JMP  DELAY
  DONE:
      RET


Пример. Время задержки. Метод четвертый - использование TMR и PRE

Полная информация в разделе "таймер и прерывания".

----------

Порты ввода-вывода с тремя состояниями (0, 1, отключен). PORTA, PORTB и PORTC

  - Процессор AQA имеет три порта ввода/вывода, которые называются PORTA, PORTB и PORTC.
  - Разрядность каждого из портов - восемь бит.
  - Выводы портов могут быть настроены как входы или выходы.
  - Для достижения этой цели используется логика с тремя устойчивыми состояниями.

TRISA, TRISB и TRISC

  - Три регистра, определяющие направления данных (вход или выход), называются TRISA, TRISB и TRISC и используются для контроля ввода/вывода на три порта передачи данных: PORTA, PORTB и PORTC.
  - Содержимое в TRIS регистрах управляет направлением данных портов ввода/вывода.
    
      1 = (I)nput  - Вход
      0 = (O)utput - Выход. 
     
    Это логично и легко запомнить.


Пример. Передача данных на четыре светодиода из восьми. 

Нажмите A в зоне [x LEDs A B C] для подключения светодиодов PORTA.

  INIT:
      MOVW    0xF0    ; IIIIOOOO
      MOVWR   TRISA   ; PORTA имеет 4 входа и 4 выхода
  LOOP:
      MOVW    0xAA
      MOVWR   PORTA   ; WORK -> PORTA
      MOVW    0x55    ; 
      MOVWR   PORTA   ; WORK -> PORTA
      JMP     LOOP

Программа отправляет тестовые данные на PORTA: поочередно 0x55 = 01010101 и 10101010 = 0xAA. Поскольку только четыре бита установлены как выходы, то светодиоды в старшей половине байта не мигают: 0x05 = 00000101 и 00001010 = 0x0A.

----------

Опрос датчиков

Опрос - Многократное чтение порта данных и тестирование считанного значения.

   - Процессор производит чтение из порта / датчика через регулярные интервалы времени.
    
   - Это происходит, даже если не было никаких изменений в состоянии подключенного устройства (датчика).
    
   - Каждому из опрашиваемых устройств между опросами выделяется гарантированный или предсказуемый промежуток времени


Опрос это ...

   - Простой код
  
   - Не очень эффективно, поскольку опрос происходит, даже если показания датчика не изменились
    
   - Безопасно и надежно, потому что измерения происходят в гарантированные интервалы времени


Пример на симуляторе

Нажмите на "A" в зоне [х SWITCHES ABC]  для подключения восьми входных переключатей к порту PORTA. Наблюдайте за изменением значения в регистре "W", по мере того, как вы изменяете состояние переключателей. Также обратите внимание на задержки, которые могут быть критичны для некоторых программ управления.

   INIT:
       MOVW  0xFF ; 11111111
       MOVWR TRISA; установить восемь бит PORTA как входы

   START:
       MOVRW PORTA; читать из PORTA
       NOP
       NOP
       NOP
       NOP
       NOP
       NOP
       JMP START

----------

Арифметика и логика

Процессор AQA имеет следующие арифметические и логические команды, действующие на рабочий регистр "W" ...

Арифметика

   ADDW K    Добавить K к W и сохранить результат в W.
   SUBW K    Вычесть K из W и сохранить результат в W.

Логика и маскирование битов

   ANDW K     "И"   К с W результат сохранить в W.
   ORW  K     "ИЛИ" К с W результат сохранить в W.
   XORW K     "XOR" К с W результат сохранить в W.

Арифметика в регистровом файле 

Есть еще две команды, которые действуют на регистровый файл

  INC [R]  добавить один к числу, хранящемуся в регистре R.
  DEC [R]  вычесть одно из числа, хранящегося в регистре R.
  
----------

Программное обеспечение битовых масок

Содержание

  1 Маскирование битов
    1.1 аппаратные битовые маски
    1.2 Программные битовые маски
  2 Полезный инструмент разработки / практическая задача


Маскирование битов

Когда порту назначены задачи как ввода, так и вывода, нужно читать порт, при этом игнорируя любые данные, которые могут быть на выходных контактах.

  Используется команда ANDW .


Аппаратные битовые маски

В случае использования элемента "И", один вход может быть задействован для открытия и закрытия ворот, а другой подключен к данным.

  0: Output, (выход) ворота закрыты.
  1: Input,  (вход)  ворота открыты.


Программные битовые маски

Программно используется маска наподобие 0xF0 = 11110000. Биты нумеруются следующим образом 76543210.

  Бит 7 сто'ит 128. Это MSB или самый старший бит.
  Бит 0 сто'ит   1. Это LSB или младший бит.
  
   7     6    5    4    3    2    1    0
  2   + 2  + 2  + 2  + 2  + 2  + 2  + 2  =

  128 + 64 + 32 + 16 + 8  + 4  + 2  + 1  = 255

Пример

  ANDW 0xF0; Хранить биты 7,6,5 и 4; игнорировать 3,2,1 и 0.

Нажмите на "A" в зоне [х SWITCHES ABC] для подключения переключателей к порту PORTA. Нажмите кнопку "B" в зоне [х LEDS ABC] для подключения светодиодов к порту PORTB. Программа опрашивает порт PORTA, маскирует биты и пишет в порт PORTB. Оказывают влияние только левые четыре переключателя.

  INIT:
      MOVW 0xF0   ; 11110000
      MOVWR TRISA ; PORTA I / O
      MOVW 0x00   ; 00000000
      MOVWR TRISB ; PORTB I / O

  MAIN:
      MOVRW PORTA ; опросить порт PORTA
      ANDW 0xF0   ; маска с 11110000
      MOVWR PORTB ; писать замаскированные данные в порт PORTB
      JMP MAIN    ; повторить выполнение основной программы


Полезный инструмент разработки / практическая задача

  - Отсоедините светодиоды от порта PORTB и подключите семисегментный дисплей вместо них.
  - Измените TRISA, чтобы получить восемь входов.
  - Уберите битовую маску из программы, так как вам нужно использовать все восемь бит.

  INIT:
      MOVW 0xFF   ; 11111111
      MOVWR TRISA ; PORTA I/O
      MOVW 0x00   ; 00000000
      MOVWR TRISB ; PORTB I/O

  MAIN:
      MOVRW PORTA ; опрос порта PORTA
      MOVWR PORTB ; писать данные в порт PORTB
      JMP MAIN    ; повторить выполнение основной программы

Поэкспериментируйте с переключателями, чтобы выяснить, какие двоичные данные необходимы для отображения цифр от 0 до 9 на обоих - левом и правом дисплеях.

  ПРОСТО:        Запишите эти данные и используйте их, чтобы написать программу, которая считает от 0 до 9.

  ОЧЕНЬ ТЯЖЕЛО:  Написать программу для счета от 00 до 99.


----------

Запись в порт

Пример 0. Последовательно мигающие светодиоды

  ; Подсоединить LED-ы к порту PORTB
  
  INIT:
      MOVW    0x00    ; восемь выходов
      MOVWR   TRISB   ; направление данных

  START: 
      MOVW    0x55    ; управляюшие данные
      MOVWR   PORTB   ; записать в порт
      NOP             ; сделать задержку в 1 такт
      NOP             ; сделать задержку в 1 такт
     
      MOVW    0xAA    ; управляюшие данные
      MOVWR   PORTB   ; записать в порт
   
      JMP     START   ; выполняется 2 такта

  ЗАДАЧА: Написать бегущую волну справа налево.      

      
Пример 1. Светофор

  ; Подсоединить TRAFFIC LIGHTS к порту PORTC

      MOVW    0x00    ; восемь выходов
      MOVWR   TRISC   ; направление данных
  START:
      MOVW    0x55    ; это число неверное
      MOVWR   PORTC   ; записать управляющие данные
      NOP             ; 1 такт задержки
      NOP             ; 1 такт задержки            

      MOVW    0xA     ; это число неверное
      MOVWR   PORTC   ; записать управляющие данные
      NOP             ; 1 такт задержки
      NOP             ; 1 такт задержки            

      MOVW    0xC     ; это число неверное
      MOVWR   PORTC   ; записать управляющие данные
      NOP             ; 1 такт задержки
      NOP             ; 1 такт задержки            

      MOVW    0x2     ; это число неверное
      MOVWR   PORTC   ; записать управляющие данные

      JMP     START   ; 2 такта задержки

  ЗАДАЧА: Создать откорректированные управляющие данные для светофора. Проверить полученные данные.
      
      
Пример 2. Нагреватель с обратной связью и термостат.

  ; Соединить нагреватель (D7 THE HEATER) с портом PORTA
  ; Соединить термостат (D0 THERMOSTAT) с портом PORTA

          MOVW    0X1     ; 00000001
          MOVWR   TRISA   ; Установить PORTA I/O
  LOOP:
          MOVRW   PORTA   ; читать порт нагревателя
          ANDW    0x1     ; игнорировать биты 2 TO 7
          SUBW    0x1     ; проверить, содержит ли "W" 1
          JPZ     TOOHOT  ; слишком жарко
          JMP     TOOCOLD ; слишком холодно

  TOOHOT:
  ; ===== Add two lines here ==============
                          ; Выключение нагревателя
                          ; Записать число в порт нагревателя
          JMP     LOOP

  TOOCOLD:
  ; ===== Add two lines here ==============
                          ; Включение нагревателя
                          ; Записать число в порт нагревателя
          JMP     LOOP

  Задача: Напишите четыре отсутствующие строки для включения и выключения обогревателя.
      
      
Пример 3. Семисегментный индикатор .

  INIT:
      MOVW 0xFF   ; 11111111
      MOVWR TRISA ; PORTA I/O
      MOVW 0x00   ; 00000000
      MOVWR TRISB ; PORTB I/O

  MAIN:
      MOVRW PORTA ; опрос порта PORTA
      MOVWR PORTB ; писать данные в порт PORTB
      JMP MAIN    ; повторить выполнение основной программы


  ; подключить семисегментный индикатор к порту C

      MOVW    0X00   ; сделать 8 разрядов порта PORTC выходами
      MOVWR   TRISC 
      MOVWR   PORTC  ; очистить правый индикатор
      MOVW    0X80   ; очистить левый индикатор
      MOVWR   PORTC
  START:
      MOVW    0X05
      MOVWR   PORTC
      MOVW    0X85
      MOVWR   PORTC

      MOVW    0X0
      MOVWR   PORTC
      MOVW    0X80
      MOVWR   PORTC
          
      JMP     START

  Задача: Считать от 0 до 9 (просто).
  Задача: Считать от 0 до 99 (очень сложно).


Пример 4. Управляющая схема Н-моста
---------

  ;                                            + +12V
  ;                                   S0 --    | S1 --
  ; Управление Мотором при помощи   +----  ----+----  ----+
  ; Н-моста (H-BRIDGE).             |                     |
  ; Присоединить Н-мост и           +---------(M)---------+
  ; переключатели (SWITCHES)        | S2 --      S3 --    |
  ; к порту PORTB                   +----  ----+----  ----+
  ;                                            | 
  ;                                            - -12V
      MOVW    0XF0    ; 4 входа и 4 выхода
      MOVWR   TRISB   ; Установить направление для порта PORTB
  START:
      MOVRW   PORTB   ; 
      ANDW    0X70    ; битовая маска
      SUBW    0X10    ; проверить что S4 замкнут
      JPZ     FORWARD ; перепрыгнуть, если замкнут
      
      JMP     COAST   ; свободный ход

  FORWARD:
      MOVW    0X09    ; замкнуть S0 и S3
      MOVWR   PORTB
      JMP     START

  COAST:
      MOVW    0X0     ; открыть все переключатели 
      MOVWR   PORTB   ; (S0, S1, S2, S3).
      JMP     START

  ЗАДАЧА: Заставить мотор вращаться по и против часовой стрелки.
  ЗАДАЧА: Установит переключатели в режим торможения.


Пример 5. Устройство управления положением перфоленты.
---------

  ; -<-----------------------------------------
  ;                   D0
  ;   ПЕРФОЛЕНТА      ...
  ;                   D6
  ;                   D7 левый
  ; -<-----------------------------------------
  ;
  ; Устройство управления положением перфоленты

      MOVW    0X3F    ; OOIIIIII
      MOVWR   TRISC   ; направление данных

  FORWARD:
      MOVW    0X40    ; Поднять бит 6
      MOVWR   PORTC   ; Идти вправо
  F_REP:
      MOVRW   PORTC   ; Опросить PORTC
      ANDW    0X3F    ; Битовая маска
      SUBW    0X0F    ; Проверка положения
      JPZ     BACKWARD; Положение найдено
      JMP     F_REP   ; Положение не найдено

  BACKWARD:
      MOVW    0X80    ; Поднять бит 7
      MOVWR   PORTC   ; Идти влево
  B_REP:
      MOVRW   PORTC   ; Опросить PORTC
      ANDW    0X3F    ; Битовая маска
      SUBW    0X03    ; Проверка положения
      JPZ     FORWARD ; Положение найдено
      JMP     B_REP   ; Положение не найдено

  ЗАДАЧА: Включить реверс, если он проскакивает и достигает конца шкалы.
        
             
Пример 6. Шаговый двигатель
---------

  ; Подсоединить STEPPER к порту PORTB
  ; Подсоединить 7-SEG к порту PORTC
  ; 3   0   1   2   3   0   1   2       магнит статора, бит
  ; 355 80  115 150 185 250 285 320     градусов
  ; С   С   С   С   С   С   С   С       статор
  ; Р  Р  Р  Р  Р  Р  Р  Р  Р  Р  Р     ротор

  START:
        MOVW    0x00
        MOVWR   0xf2

  MORE:
        CALL    TICK
        MOVW    0x1
        MOVWR   PORTB

        CALL    TICK
        MOVW    0x2
        MOVWR   PORTB

        CALL    TICK
        MOVW    0x4
        MOVWR   PORTB

        CALL    TICK
        MOVW    0x8
        MOVWR   PORTB 

        JMP     MORE

  TICK:
        MOVRW   0xf2
        MOVWR   0xf0
        CALL    DISPLAYF0      
        INC     0xf2
        MOVRW   0xf2
        ANDW    0x0f
        SUBW    0x0a
        JPC     STEPOUT
        MOVRW   0xf2
        ANDW    0xf0
        ADDW    0x10
        MOVWR   0xf2
        ANDW    0xf0
        SUBW    0xa0
        JPC     STEPOUT
        MOVW    0x00
        MOVWR   0xf2
  STEPOUT:
        RET
        
  DISPLAYF0:
        MOVWR   0xf1
        ANDW    0x0f
        MOVWR   0xf0
        CALL    QRYR0
        MOVRW   0xf1
        ANDW    0xf0
        MOVWR   0xf0
        CALL    QRYL0
        RET
              
  QRYR0:         
        MOVRW   0xf0
        SUBW    0x00
        JPZ     MATCHR0
        JMP     QRYR1
  MATCHR0:
        MOVW    0x7d 
        MOVWR   PORTC
        
  QRYR1:
        MOVRW   0xf0
        SUBW    0x01
        JPZ     MATCHR1
        JMP     QRYR2
  MATCHR1:
        MOVW    0x05 
        MOVWR   PORTC
        
  QRYR2:
        MOVRW   0xf0
        SUBW    0x02
        JPZ     MATCHR2
        JMP     QRYR3
  MATCHR2:
        MOVW    0x5b 
        MOVWR   PORTC
        
  QRYR3:
        MOVRW   0xf0
        SUBW    0x03
        JPZ     MATCHR3
        JMP     QRYR4
  MATCHR3:
        MOVW    0x4f 
        MOVWR   PORTC
        
  QRYR4:
        MOVRW   0xf0
        SUBW    0x04
        JPZ     MATCHR4
        JMP     QRYR5
  MATCHR4:
        MOVW    0x27 
        MOVWR   PORTC
        
  QRYR5:
        MOVRW   0xf0
        SUBW    0x05
        JPZ     MATCHR5
        JMP     QRYR6
  MATCHR5:
        MOVW    0x6e 
        MOVWR   PORTC
        
  QRYR6:
        MOVRW   0xf0
        SUBW    0x06
        JPZ     MATCHR6
        JMP     QRYR7
  MATCHR6:
        MOVW    0x7e 
        MOVWR   PORTC
        
  QRYR7:
        MOVRW   0xf0
        SUBW    0x07
        JPZ     MATCHR7
        JMP     QRYR8
  MATCHR7:
        MOVW    0x45 
        MOVWR   PORTC
        
  QRYR8:
        MOVRW   0xf0
        SUBW    0x08
        JPZ     MATCHR8
        JMP     QRYR9
  MATCHR8:
        MOVW    0x7f 
        MOVWR   PORTC
        
  QRYR9:
        MOVRW   0xf0
        SUBW    0x09
        JPZ     MATCHR9
        JMP     QRYRG
  MATCHR9:
        MOVW    0x6f 
        MOVWR   PORTC
        
  QRYRG:
        RET


  QRYL0:         
        MOVRW   0xf0
        SUBW    0x00
        JPZ     MATCHL0
        JMP     QRYL1
  MATCHL0:
        MOVW    0xfd 
        MOVWR   PORTC
        
  QRYL1:
        MOVRW   0xf0
        SUBW    0x10
        JPZ     MATCHL1
        JMP     QRYL2
  MATCHL1:
        MOVW    0x85 
        MOVWR   PORTC
        
  QRYL2:
        MOVRW   0xf0
        SUBW    0x20
        JPZ     MATCHL2
        JMP     QRYL3
  MATCHL2:
        MOVW    0xdb 
        MOVWR   PORTC
        
  QRYL3:
        MOVRW   0xf0
        SUBW    0x30
        JPZ     MATCHL3
        JMP     QRYL4
  MATCHL3:
        MOVW    0xcf 
        MOVWR   PORTC
        
  QRYL4:
        MOVRW   0xf0
        SUBW    0x40
        JPZ     MATCHL4
        JMP     QRYL5
  MATCHL4:
        MOVW    0xa7 
        MOVWR   PORTC
        
  QRYL5:
        MOVRW   0xf0
        SUBW    0x50
        JPZ     MATCHL5
        JMP     QRYL6
  MATCHL5:
        MOVW    0xee 
        MOVWR   PORTC
        
  QRYL6:
        MOVRW   0xf0
        SUBW    0x60
        JPZ     MATCHL6
        JMP     QRYL7
  MATCHL6:
        MOVW    0xfe 
        MOVWR   PORTC
        
  QRYL7:
        MOVRW   0xf0
        SUBW    0x70
        JPZ     MATCHL7
        JMP     QRYL8
  MATCHL7:
        MOVW    0xc5 
        MOVWR   PORTC
        
  QRYL8:
        MOVRW   0xf0
        SUBW    0x80
        JPZ     MATCHL8
        JMP     QRYL9
  MATCHL8:
        MOVW    0xff 
        MOVWR   PORTC
        
  QRYL9:
        MOVRW   0xf0
        SUBW    0x90
        JPZ     MATCHL9
        JMP     QRYLG
  MATCHL9:
        MOVW    0xef 
        MOVWR   PORTC
        
  QRYLG:
        RET

  ЗАДАЧА: Заставить двигатель вращаться в обратном направлении.
  ЗАДАЧА: Заставить двигатель вращаться с половинным шагом.


Пример 7. Суммирующий ЦАП
---------
               
  ; MSB o---/\/\/-----+---/\/\/---
  ;          10K      |    10K
  ;   6 o---/\/\/-----+
  ;                   |
  ;        . . .      |   Op.Amp
  ;                   |  +-----+
  ; LSB o---/\/\/-----+--+ -   |
  ;                      |     +--o
  ;                   +--+ +   |
  ;                   |  +-----+
  ;                  ---
  ;                  
  ; Подсоединить DAC к порту PORT A

      movw    0x0
  start:
      movwr   porta
      addw    0x1
      jmp     start

Коэффициент усиления наиболее по входу MSB равен единице. Напряжения на цифровом выходе микроконтроллера:

   0 Вольт = Низкий уровень (0).
   5 Вольт = Высокий уровень (ffh).

  ЗАДАЧА: Выяснить разрешение (шаг дискретизации) этого ЦАПа.
  ЗАДАЧА: Рассчитать неуказанные значения входных резисторов.
  ЗАДАЧА: Сколько выходных уровней доступны для этого ЦАПа.


Пример 8. Цифровой компаратор на базе ЦАПа

  ;                усилитель  фоторезистор
  ;                   +VDC o  ||    
  ;      +-----+   |\      |  vv    |\
  ; 7 o--+ ЦАП |   | \     +/\/\/+  | \
  ; 6 o--+     |   |  \          |  |  \
  ; 5 o--+     +---+ - \  +------)--+ - \
  ; 4 o--+     |   | k=1\_|      |  |    \_/\/\/--+--- 0 .. 5V
  ; 3 o--+     | +-+ +  /  +/\/\/+--+ +  /        | 
  ; 2 o--+     | | |   /   |        |   /       --+-+
  ; 1 o--+     | | |  /    |        |  /         / \|
  ; 0 o--+     | | | /     |        | /          -+- 
  ;      +-----+ | |/      |        |/            |
  ;             ---       ---                    ---
  ;                                 компаратор    стабилитрон
  ;
  ; Подсоединить цифровой компаратор к порту PORTA 

          jmp     init

  count:  db      0x00
  delay:  db      0x30
  mask:   db      0x80

  init:
          movrw   mask
          movwr   trisa
          movw    0x0
          movwr   count
  s:
          movrw   count
          movwr   porta
          movrw   porta
          andw    0x80
          jpz     pause
          inc     count
          jmp     s

  pause:
          movrw    delay
  rep:
          subw    0x1
          jpz     init
          jmp     rep

----------

Таймер и прерывания

Содержание

  1 Прерывания
  2 Прерывание таймера
  3 Регистры таймера TMR и PRE
  4 Пример Таймера 


Прерывания это ...

  - Аппаратные или программные сигналы, которые вызывают 
    прерывание выполняемой подпрограммы.
  - Происходят только в том случае, когда это необходимо.
  - Более эффективно, чем опрос но время выполнения 
    подпрограммы прерывания менее предсказуемо.
  - Труднее программировать чем опрос.
  - Следствия прерывания ...
      * Исходный процесс приостанавливается и адрес возврата
        сохраняется в стеке.
      * Выполняется код прерывания.
      * Исходный процесс возобновляется используя адрес 
        возврата извлекаемый из стека.


Прерывание таймера 

Большинство процессоров имеют встроенные таймеры, которые могут быть использованы для переключения процессов в момент окончания интервала таймера.


Регистры таймера TMR и PRE

Микроконтроллер AQA содержит регистр таймера называемый TMR. AQA симулятор отображает этого регистра по адресу 0xFF файла регистров.

Существует также регистр-предделитель, PRE, отображаемый в памяти на по адресу 0xFE.

  - Если PRE содержит ноль, TMR ничего не делает.
  - Если PRE содержит 10 (например), счетчик увеличивается на каждый тактовый импульс. Когда счетчик доходит до 10, 1 вычитается из TMR и счетчик сбрасывается в ноль. Это уменьшает TMR на единицу на каждом одиннадцатом тактовом импульсе.
  - Если PRE содержит несколько большее число N, счетчик отсчитывает от нуля до N, а затем вычитает 1 из TMR.
  - Таким образом, тактовая частота делится на PRE + 1 и используется для уменьшения значения в TMR.
      
Когда TMR достигает нуля, флажок T (SR) устанавливается в единицу и остается установленным до тех пор, пока нулевое значение не будет присвоено TMR.


Пример таймера

Оцените грубо, сколько времени требуется прежде чем запустится код контролируемый Таймером. Измените этот код сохранив 8 в PRE вместо 1. Запустите измененный код и обратите внимание, что таймер считает много медленнее и события таймера встречаются реже.

  START:
      MOVW  0x1  ; Копия 1 в ...
      MOVWR PRE  ; ... предделитель
      MOVW  0x08 ; Копировать 8 в ...
      MOVWR TMR  ; ... Таймер

  POLL:
      MOVRW SR   ; Копировать SR в W
      ANDW  0x02 ; битовая маска
      JPZ   POLL

  ; Этот код выполняется, когда TMR достигает нуля
      NOP
      NOP
      NOP
      NOP
      JMP   START

----------

Ссылки

  http://www.softwareforeducation.com/wikileki/index.php?title=Subroutines
  http://www.softwareforeducation.com/wikileki/index.php?title=IO_Ports
  http://www.softwareforeducation.com/wikileki/index.php?title=Polling_Sensors
  http://www.softwareforeducation.com/wikileki/index.php?title=Bit_Masks_Software
  http://www.softwareforeducation.com/wikileki/index.php?title=Arithmetic_and_Logic
  http://www.softwareforeducation.com/wikileki/index.php?title=Bit_Masks_Software
  http://www.softwareforeducation.com/wikileki/index.php?title=Port_Writing
  http://www.softwareforeducation.com/wikileki/index.php?title=Timers_and_Interrupts
  http://www.softwareforeducation.com/wikileki/index.php?title=ReviseOmatic
