
- •Алгебра логики, алгебра Буля. Основные аксиомы.
- •Законы алгебры Буля. Дистрибутивный, коммутативный, ассоциативный.
- •Законы алгебры Буля. Поглощения, двойного отрицания, исключения.
- •Законы алгебры Буля. Де Моргана, идемпотентности.
- •Условное графическое обозначение логических элементов (стандарты).
- •Способы минимизации логических функций. Правило составления карты Карно.
- •Карта Карно для:
- •Для каждого контура выделяем области:
- •Способы минимизации логических функций. Правило составления диаграммы Вейча.
- •Комбинационная схема. Функция дешифратора.
- •Комбинационная схема. Функция шифратора.
- •Комбинационная схема. Функция мультиплексора.
- •Комбинационная схема. Функция демультиплексора.
- •Триггеры. Типы триггеров. Классификация Триггеров.
- •Регистры. Счетчики. Разновидность.
- •Архитектура Микроконтроллера. Структура типовой эвм.
- •Тактовая частота микроконтроллера. Изменения тактовой частоты.
- •Регистры общего назначения (рон) в микроконтроллерах.
- •Регистр признаков. Распиновка битов.
- •Регистры специального назначения. Регистр Программный счетчик.
- •Регистры специального назначения. Регистр указатель Стека.
- •Регистры специального назначения. Таймеры.
- •Регистры специального назначения. Ацп и цап.
- •Виды памяти в микроконтроллерах.
- •Преобразование последовательного кода в параллельный.
- •Преобразование параллельного кода в последовательный.
- •Язык Ассемблера. Синтаксис. Мнемокод.
- •Арифметические команды. Принцип работы.
- •Imul операнд_1[,операнд_2,операнд_3].
- •Логические команды. Принцип работы.
- •Команды вызова подпрограммы, особенности.
- •Команды переходов в программе, особенности.
- •Доказать следующие законы: дистрибутивный, поглощения.
- •1) Доказательство дистрибутивного закона
- •Доказательство закона поглощения
- •Доказать следующие законы: идемпотентности, двойного отрицания.
- •Доказательство закона идемпотентности
- •Доказательство закона двойного отрицания
- •Доказать следующий законы: исключения, коммутативный.
- •Минимизировать произвольную логическую функцию с помощью диаграмм Вейча. Каскадное подключение дешифраторов, увеличение разряда дешифратора на n.
- •Каскадное подключение демультиплексора, увеличение разряда демультиплексора на n.
- •Реализовать rs триггер на элементах или-не.
- •Реализовать rs триггер на элементах и-не.
- •Основные команды по работе с триггерами общего назначения. Основные команды по работе с триггером признаков. Назначение регистра pc. И принцип работы с ним.
- •Назначения регистра sp. И принцип работы с ним.
- •Назначения регистра watchdog. И принцип работы с ним.
- •Работа с Flash-памятью микроконтроллера.
- •Работа с eeprom памятью микроконтроллера. (https://cxem.Net/mc/book.Php )
Назначения регистра sp. И принцип работы с ним.
Стек, или указатель стека – это специальный регистр, который предназначен для организации стековой памяти.
Можно сказать, что стек (точнее стековая память, стек состоит из двух частей: указатель стека и стековая память) – это туннель с тупиком в конце, состоящий из ячеек памяти. По мере заполнения ячеек памяти первые данные уходят в глубь стека, и добраться до них можно, только вытащив сначала последние введенные данные. Допустим, если мы запишем в стек последовательно три числа: 10,20 и 30, то для того, чтобы затем извлечь из стековой памяти число 10, предварительно придется извлечь числа 30 и 20. Т.е., значение запиФ
Назначения регистра watchdog. И принцип работы с ним.
Watchdog Timer (WDT) – это сторожевой таймер (а если перевести дословно, "сторожевой пёс"), который представляет собой аппаратно-реализованную схему контроля над зависанием системы. Это таймер, который периодически сбрасывается контролируемой системой. Если вдруг сброса не произошло за определённый интервал времени после предыдущего сброса данного таймера, то происходит принудительная перезагрузка системы (в нашем случае микроконтроллера).
Например, мы ждём ответа от какой-нибудь шины в виде отслеживания состояния определённого бита регистра. И вдруг произойдёт кратковременное отсоединение провода этой шины. После этого скорей всего произойдёт зависание программы, так как в шине будет сбой, и даже если что-то после и придёт от присоединённого узла, то мы вряд ли уже это отследим изменением состояния бита. Желательно, чтобы после какого-то таймаута система перезагрузилась. Тут-то и приходит нам на помощь WDT, который установлен на определённый интервал. Команду на перезагрузку сторожевого таймера мы расположим в нашем коде после того, как мы дождёмся отклика от шины. А если мы так его и не дождёмся, то мы не дойдём до команды перезагрузки WDT и через заветный интервал времени система будет перезагружена. После этого произойдёт заново инициализация шины и всё будет опять работать нормально.
Работа с Flash-памятью микроконтроллера.
http://s-engineer.ru/assemblernaya-zagotovka-dlya-avr-atmega8/ ТУТ ЛУЧШЕ ПРОЧИТАТЬ, ТАМ НЕМНОГО ВВЕДИ FLASH в поиск
Директива «.cseg» обозначает начало программного сегмента, все что ниже, относиться к коду (или константам, об этом позже). Программатор разместит данный сегмент в FLASH памяти микроконтроллера, а по какому адресу? За это, отвечает следующая директива «.org» с параметром «0x00». В данном случае, её использовать не обязательно, т.к. начала программного кода всегда записывается с адреса 0x00.
.cseg ;данная директива означает, что дальше идет код программы
.org 0x00;данная директива означает, что код программы будет располагаться с 0 ого адреса в FLASH
;ВЕКТОР ПРЕРЫВАНИЙ
rjmp initial ;прерывание от RESET, ссылаемся на обработчик прерывания - initial
rjmp 0 ;rjmp service_INT0 ;внешнее прерывание 0
rjmp 0 ;rjmp service_INT1 ;внешнее прерывание 1
rjmp 0 ;rjmp service_OC2 ;совпадение TCNT2 и OCR2
rjmp 0 ;rjmp service_OVF2 ;переполнение TCNT2
rjmp 0 ;rjmp service_ICP1 ;захват в ICP1
rjmp 0 ;rjmp service_OC1A ;совпадение TCNT1 и OCR1A
rjmp 0 ;rjmp service_OC1B ;совпадение TCNT1 и OCR1B
rjmp 0 ;rjmp service_OVF1 ;переполнение TCNT1
rjmp 0 ;rjmp service_OVF0 ;переполнение TCNT0
rjmp 0 ;rjmp service_SPI ;прерывание от модуля SPI
rjmp 0 ;rjmp service_URXC ;получение байта по USART
rjmp 0 ;rjmp service_UDRE ;опустошение UDR в USART
rjmp 0 ;rjmp service_UTXC ;передача байта по USART
rjmp 0 ;rjmp service_ADCC ;прерывание от АЦП
rjmp 0 ;rjmp service_ERDY ;завершение записи в EEPROM
rjmp 0 ;rjmp service_ACI ;прерывание от компаратора
rjmp 0 ;rjmp service_TWI ;прерывание от модуля TWI
rjmp 0 ;rjmp service_SPMR ;завершение выполнения spm
.org 0x20;данная директива означает, что код программы будет располагаться с слова 0x20 в FLASH или с адреса 0x40 (т.е. с 0x40 байта).
;В FLASH адресация осуществляется по словам, а не по байтам, одно слово равно двум байтам.
;УСТАНОВКА СТЕКА
initial: ldi R16,low(RAMEND) ;скопируем в R16 младщий байт из константы RAMEND, которая определена в m8def.inc и хранит размер SRAM
out SPL,R16 ;скопируем значение из R16 в SPL
ldi R17,high(RAMEND) ;скопируем в R16 старший байт из константы RAMEND, которая определена в m8def.inc
out SPH,R17 ;скопируем значение из R17 в SPH
Директива «.cseg» обозначает начало программного сегмента, все что ниже, относиться к коду (или константам, об этом позже). Программатор разместит данный сегмент в FLASH памяти микроконтроллера, а по какому адресу? За это, отвечает следующая директива «.org» с параметром «0x00». В данном случае, её использовать не обязательно, т.к. начала программного кода всегда записывается с адреса 0x00.
После вектора прерывания следует директива «.org 0x20», она здесь не обязательна, таким образом, я хотел показать, что программный сегмент можно помещать в разные области в памяти FLASH. Первая мысль, что 0x20 это адрес в байтах, но на самом деле в FLASH Atmega адресация происходит по словам (машинная инструкция), одно слово это 2 байта. Выходит, следующий фрагмент кода будет располагаться с 0x40 ого байта. Скомпилированный код, можно запустить в модели ATmega8 в программе Proteus, там же есть возможность посмотреть что находится в FLASH памяти контроллера. Зеленым я обозначил инструкции, которые представляют собой вектор прерывания, а голубым инструкции отвечающие за установка стека. Видно, что между инструкциями есть разрыв в виде 0xFF и инструкции по установки стека начинаются с адрес 0x40, как мы и установили.
Если закомментировать «.org 0x20» и скомпилировать код, инструкции в FLASH буду расположены следующим образом.
Ниже, я разместил небольшую памятку по работе с FLASH и SRAM памятью на ассемблере. В main демонстрируется:
как считать данные из программной памяти FLASH в регистры;
как записывать данные из SRAM в регистры и наоборот, как считывать эти данные из SRAM в регистры.
В памятке опущены моменты как считывать данные из памяти EEPROM, т.к. это отдельное устройство с своими регистрами ввода/вывода. Также я пропустил запись данных в FLASH память самой программой, еще это называют самопрограммирование, данную возможность используют bootloader контроллера при прошивке. Перед записи в FLASH, необходимо выполнить ряд процедур по стиранию, по работе с буфером и т.д. Эти две темы требуют отдельных постов.
; ------------------- ПРОСТО ПОМЕЩАЕМ В РЕГИСТР КОНСТАНТУ ----------------------
ldi r16,'C' ;в регистре r16 будет хранится константа 'C'
; ---------------- КОНЕЦ ПРОСТО ПОМЕЩАЕМ В РЕГИСТР КОНСТАНТУ -------------------
ldi ZH,high(2*PAUSE2) ;второй вариант, значение константы PUASE2 лежит в FLASH (значение и адрес (0x50) мы задали ниже, т.е. данные туда помещаются при прошивке), на который указывает регистр Z
ldi ZL,low(2*PAUSE2) ;повторюсь, в FLASH адресация происходит не по байтно как в EERPROM и SRAM, а словами по 2-а байта, поэтому метка PAUSE находится
;на 0x50 слове, а т.к. ldi работает с адресами то поэтому умножаем на 2 -> "ldi ZH,high(2*PAUSE)"
lpm r17,Z;считываем значение из FLASH в регистр r17
; ----------- КОНЕЦ СЧИТЫВАЕМ ЗНАЧЕНИЕ КОНСТАНТЫ ИЗ FLASH ----------------
; ============== ЗАПИСЫВАЕМ ЗНАЧЕНИЕ ПЕРЕМЕННОЙ В SRAM ===================
ldi YH,high(PAUSE3) ;третий вариант, записываем значение константы PUASE3 лежит из SRAM (область мы выделили ниже размером 1 байт)
ldi YL,low(PAUSE3) ;на адрес где находится константа указывает регистр Y
ldi r18,'S' ;данные для SRAM можно взять откуда угодно, например из портов ввода, из FLASH/EEPROM/SRAM, в резульатате какого нибудь расчета
st Y,r18 ;примитивный способ, мы поместим константу 'S' в r18 и запишем её в SRAM
clr r18 ;очистим регистр, мы его использовали в качестве буфера
clr YH ;очистим регистр YH
clr YL ;очистим регистр YL
; =========== КОНЕЦ ЗАПИСЫВАЕМ ЗНАЧЕНИЕ ПЕРЕМЕННОЙ В SRAM ================
; ----------- СЧИТЫВАЕМ ЗНАЧЕНИЕ ПЕРЕМЕННОЙ ИЗ SRAM ----------------------
ldi YH,high(PAUSE3) ;третий вариант, значение переменной PUASE3 лежит в SRAM (область мы выделили ниже размером 1 байт, значения мы положили кодом выше)
ldi YL,low(PAUSE3) ;на адрес указывает регистр Y
ld r18,Y ;результат кладем в r18
; ----------- КОНЕЦ СЧИТЫВАЕМ ЗНАЧЕНИЕ ПЕРЕМЕННОЙ ИЗ SRAM ----------------
; ============ ПРИ ПРОШИВКЕ МК В FLASH БУДЕТ ПОМЕЩЕНА КОНСТАНТА PAUSE2 С ЗНАЧЕНИЕМ 'F' ===============
.cseg
org 0x50
PAUSE2: .dw 'F'
; =========== КОНЕЦ ПРИ ПРОШИВКЕ МК В FLASH БУДЕТ ПОМЕЩЕНА КОНСТАНТА PAUSE2 С ЗНАЧЕНИЕМ 0xA ==========
; СЕКТОР ДЛЯ SRAM
; ============ ПРИ ПРОШИВКЕ МК В SRAM БУДЕТ ЗАРЕЗЕРВИРОВАНО МЕСТО ПОД ПЕРЕМЕННУЮ PAUSE2 РАЗМЕРОМ 1 БАЙТ ===============
dseg ;данная директива означает, что дальше идет код секция SRAM
org 0x60
PAUSE3:
byte 1 ;резервирование байта в ОЗУ
; ============ КОНЕЦ ПРИ ПРОШИВКЕ МК В SRAM БУДЕТ ЗАРЕЗЕРВИРОВАНО МЕСТО ПОД ПЕРЕМЕННУЮ PAUSE2 РАЗМЕРОМ 1 БАЙТ ===============
резервирует в ОЗУ один байт, к которому можно обращаться по метки PAUSE3 с помощью соответствующих команд ассемблера.
Для секции кода «.cseg», т.е. для FLASH памяти, также возможно резервировать области памяти, но с помощью директив «.db» и «.dw».
«.db» — Резервирует байт, параметр это значение, которое будет находится в данной области. Значение должно быть размером не более одного байта.
«.dw» — Резервирует слово, другими словами 2-а байта, параметр это значение, которое будет находится в данной области. Значение должно быть размером не более 2-ух байт.