Обратное проектирование МК

Взлом микроконтроллеров - MikaTech

Наши ценности и цели

О MikaTech

Время пролетело быстро, с того дня, как мы выполнили наш первый проект по обратному проектированию МК 8051 в 1998 году, до того дня, когда мы создали нашу лабораторию обратного проектирования стоимостью в миллион долларов в 2012 году, прошло 14 лет. Теперь мы начинаем наш новый бизнес по разработке встроенных систем визуализации, надеемся, что сможем прослужить еще 10 лет.

подпись Peter Lee Со-основатель и генеральный директор

Архитектура и программирование МК 8051 для обратного проектирования 3

Глава 5: Язык ассемблера

Введение

Инженерам-аппаратчикам приходилось идти на компромиссы, чтобы оставаться конкурентоспособными в разработке встраиваемых систем. В отличие от обычных электронных схем, которым для работы требуется только монтаж и питание, микроконтроллеры дополнительно требуют программирования для выполнения поставленных задач. К счастью, архитектуры микроконтроллеров не развились до такой степени, чтобы требовать разнообразных языков высокого уровня; практически все семейства микроконтроллеров изначально понимают только машинный язык. Эта стандартизация дает большие преимущества. Обратной стороной является то, что машинный язык, состоящий исключительно из двоичных нулей и единиц, не понятен разработчикам-людям и расшифровывается только специалистами по аппаратному проектированию. Для устранения коммуникационного разрыва между аппаратным обеспечением микроконтроллера и программистами-людьми был создан язык ассемблера — первый человекочитаемый язык программирования низкого уровня.

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

Программа-ассемблер принимает человекочитаемые мнемоники ассемблера и надежно преобразует их в двоичный исполняемый выходной файл. Этап компиляции, преобразующий исходный код ассемблера в машинный код, является критическим, поскольку результирующий HEX-файл представляет собой поток двоичных значений, которые может интерпретировать только аппаратное обеспечение микроконтроллера. Исходный код ассемблера не может выполняться непосредственно на микроконтроллере, если только этот скомпилированный HEX-файл не будет записан в программную память устройства. Здесь в игру вступает последний компонент рабочего процесса разработки — программатор микросхем. Это компактное аппаратное устройство, подключаемое к настольному ПК через стандартный порт связи и имеющее разъем для установки целевой микросхемы микроконтроллера для прошивки.

5.1 Элементы языка ассемблера

Язык ассемблера следует структурным правилам, аналогичным естественным языкам, включая зарезервированные слова, строгие правила форматирования и стандартизированный синтаксис. Четыре основных фундаментальных строительных блока исходного кода ассемблера перечислены ниже:

  • Метки (Labels)
  • Мнемоники инструкций
  • Директивы ассемблера
  • Строки комментариев
Элементы ассемблера

Синтаксис языка ассемблера

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

  • Одна строка исходного кода ассемблера может содержать максимум 255 символов ASCII;
  • Каждая компилируемая строка должна начинаться с метки, мнемоники инструкции или директивы ассемблера;
  • Весь текст после точки с запятой «;» в любой строке рассматривается как человекочитаемый комментарий и полностью игнорируется ассемблером во время компиляции;
  • Все различные компоненты в одной строке (метки, инструкции, операнды, директивы) должны быть разделены по крайней мере одним пробелом. Клавиша TAB широко используется вместо одиночных пробелов для аккуратного выравнивания меток, мнемоник и директив в вертикальные столбцы для улучшения читаемости кода.

Числовые литералы

За исключением устаревшей восьмеричной системы счисления, язык ассемблера поддерживает числовые значения, записанные в трех различных форматах:

Десятичные числа

Если суффикс основания не указан, ассемблер интерпретирует все числовые литералы как десятичные значения. Десятичная запись использует цифры от 0 до 9. Поскольку хранилище микроконтроллера выделяет максимум два байта для общего хранения чисел, наибольшее представимое десятичное значение в коде ассемблера равно 65535. Для явного обозначения десятичного значения может быть добавлен суффикс «D», например: 1234D.

Шестнадцатеричные числа

Шестнадцатеричная запись является наиболее часто используемым форматом для встроенного программирования. Шестнадцатеричная система счисления использует шестнадцать уникальных символов: цифры 0–9 и буквы A–F. Максимальное двухбайтовое шестнадцатеричное значение — FFFF, что эквивалентно десятичному значению 65535. Чтобы отличить шестнадцатеричные литералы от десятичных, к числу добавляется суффикс «h» (верхний или нижний регистр), например, 54h.

Двоичные числа

Двоичные литералы часто используются, когда необходимо явно определить отдельные битовые состояния регистров ЦП, так как каждая двоичная цифра непосредственно соответствует одной аппаратной битовой позиции. Двоичная запись использует только цифры 0 и 1. Максимальный двухбайтовый двоичный литерал — 1111111111111111. Для отличия двоичных значений от других числовых форматов добавляется суффикс «b» (верхний или нижний регистр), например: 01100101B.

Операторы

Многие условные директивы ассемблера и операнды инструкций принимают математические и логические выражения вместо фиксированных статических значений. Пример условного блока показан ниже:

IF (VERSION>1)
   LCALL Table_2
   USING VERSION+1
ENDIF
   ...

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

Символ оператора Описание операции Пример выражения Вычисленный результат
+ Сложение 10+5 15
- Вычитание 25-17 8
* Умножение 7*4 28
/ Целочисленное деление (отбрасывает остаток) 7/4 1
MOD Остаток от деления 7 MOD 4 3
SHR Побитовый сдвиг вправо 1000B SHR 2 0010B
SHL Побитовый сдвиг влево 1010B SHL 2 101000B
NOT Побитовое логическое НЕ (дополнение до 1) NOT 1 1111111111111110B
AND Побитовое логическое И 1101B AND 0101B 0101B
OR Побитовое логическое ИЛИ 1101B OR 0101B 1101B
XOR Побитовое исключающее ИЛИ 1101B XOR 0101B 1000B
LOW Извлечь младшие 8 бит 16-битного значения LOW(0AADDH) 0DDH
HIGH Извлечь старшие 8 бит 16-битного значения HIGH(0AADDH) 0AAH
EQ, = Сравнение на равенство 7 EQ 4 или 7=4 0 (Ложь)
NE,<> Сравнение на неравенство 7 NE 4 или 7<>4 0FFFFH (Истина)
GT, > Сравнение «больше чем» 7 GT 4 или 7>4 0FFFFH (Истина)
GE, >= Сравнение «больше или равно» 7 GE 4 или 7>=4 0FFFFH (Истина)
LT, < Сравнение «меньше чем» 7 LT 4 или 7<4 0 (Ложь)
LE,<= Сравнение «меньше или равно» 7 LE 4 или 7<=4 0 (Ложь)

Пользовательские символы

Пользовательские символические имена могут быть присвоены регистрам ЦП, константным значениям, адресам памяти и точкам входа в подпрограммы в коде ассемблера, что значительно упрощает читаемость и сопровождение исходного кода. Например, если вывод GPIO P0.3 подключен к физической кнопке, которая запускает полную остановку процесса (кнопка STOP), логика кода становится гораздо более интуитивной, если битовому адресу P0.3 присвоено описательное имя «pushbutton_STOP». Как и в других языках программирования, строгие правила именования регулируют допустимые пользовательские символы:

  • Допустимые символы включают буквы латинского алфавита (A-Z, a-z), десятичные цифры (0–9) и два специальных символа: подчеркивание «_» и вопросительный знак «?». Язык ассемблера полностью нечувствителен к регистру для имен символов.

Два приведенных ниже символа обрабатываются ассемблером как идентичные:

Serial_Port_Buffer
SERIAL_PORT_BUFFER
  • Во избежание неоднозначности с числовыми литералами каждый допустимый символ должен начинаться с буквы, подчеркивания или вопросительного знака; цифры не могут использоваться в качестве первого символа.
  • Имя символа может содержать до 255 символов, но ассемблер учитывает только первые 32 символа для различения уникальных идентификаторов. Пример ниже демонстрирует это поведение: первые два символа помечаются как дублирующиеся определения (ошибка компиляции), а третий и четвертый распознаются как различные идентификаторы:
START_ADDRESS_OF_TABLE_AND_CONSTANTS_1
START_ADDRESS_OF_TABLE_AND_CONSTANTS_2
TABLE_OF_CONSTANTS_1_START_ADDRESS
TABLE_OF_CONSTANTC_2_START_ADDRESS
  • Некоторые зарезервированные ключевые слова не могут использоваться в качестве пользовательских имен символов, поскольку они являются предопределенными мнемониками инструкций, директивами ассемблера или встроенными идентификаторами аппаратных регистров. Например, пользователь не может определить символ с именем «A» или «DPTR», поскольку эти имена соответствуют собственным регистрам ЦП.

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

A AB ACALL ADD
ADDC AJMP AND ANL
AR0 AR1 AR2 AR3
AR4 AR5 AR6 AR7
BIT BSEG C CALL
CJNE CLR CODE CPL
CSEG DA DATA DB
DBIT DEC DIV DJNZ
DPTR DS DSEG DW
END EQ EQU GE
GT HIGH IDATA INC
ISEG JB JBC JC
JMP JNB JNC JNZ
JZ LCALL LE LJMP
LOW LT MOD MOV
MOVC MOVX MUL NE
NOP NOT OR ORG
ORL PC POP PUSH
R0 R1 R2 R3
R4 R5 R6 R7
RET RETI RL RLC
RR RRC SET SETB
SHL SHR SJMP SUBB
SWAP USING XCH XCHD
XDATA XOR XRL XSEG

Метки

Метка — это специализированный тип символа, представляющий человекочитаемый псевдоним для физического адреса памяти в программной ROM или данных RAM. Метки всегда помещаются в самом начале строки исходного кода. Инструкции перехода, ветвления и вызова подпрограмм были бы чрезвычайно громоздкими для написания и сопровождения без меток. Стандартный рабочий процесс использования меток прост:

  • Присвойте описательную метку первой строке подпрограммы или целевому адресу инструкции перехода;
  • Ссылайтесь на имя метки непосредственно в инструкциях перехода и вызова подпрограмм вместо ручного ввода сырых 16-битных числовых адресов памяти.

Во время компиляции ассемблер автоматически разрешает каждую метку в соответствующий абсолютный адрес памяти и подставляет числовое значение в скомпилированный машинный код.

Директивы ассемблера

В отличие от мнемоник инструкций ЦП, которые компилируются в исполняемый машинный код, хранящийся в программной памяти микроконтроллера, директивы ассемблера являются собственными командами, интерпретируемыми только программным обеспечением ассемблера и не влияющими на поведение аппаратного обеспечения микроконтроллера во время выполнения. Некоторые директивы обязательны для каждого корректного проекта на ассемблере, в то время как другие существуют исключительно для упрощения рабочих процессов разработки или ускорения процессов компиляции.
Директивы занимают ту же вертикальную колонку, что и мнемоники инструкций в исходном коде, и одна строка исходного кода может содержать только одну директиву ассемблера.

Директива EQU

Директива EQU связывает фиксированное числовое значение с пользовательским именем символа для повторного использования во всем исходном файле. Пример использования:

MAXIMUM EQU 99

После этого определения каждое вхождение символа «MAXIMUM» в исходном коде будет заменено литеральным значением 99 во время компиляции. Каждый символ может быть определен только один раз с помощью EQU, поэтому объявления EQU почти всегда помещаются в начало файла ассемблера для глобальной настройки констант.

Директива SET

Директива SET также сопоставляет числовое значение с символическим псевдонимом. Ее ключевое отличие от EQU заключается в том, что SET позволяет многократно переопределять один и тот же символ несколько раз в исходном файле:

SPEED SET 45
SPEED SET 46
SPEED SET 57

Директива BIT

Директива BIT присваивает пользовательское имя символа определенной битово-адресуемой ячейке памяти, при этом целевой битовый адрес должен находиться в диапазоне 0–255. Примеры определений:

TRANSMIT BIT PSW.7 ;Присвоить псевдоним "TRANSMIT" биту 7 регистра состояния PSW
OUTPUT BIT 6 ;Присвоить псевдоним "OUTPUT" битовому адресу 06h
RELAY BIT 81 ;Присвоить псевдоним "RELAY" битовому адресу 81h (соответствует выводу 1 порта 0)

Директива CODE

Директива CODE связывает пользовательский символ с фиксированным адресом программной памяти. Поскольку максимальное адресное пространство стандартной программной памяти 8051 составляет 64 КБ, допустимые адреса находятся в диапазоне от 0 до 65535. Пример:

RESET CODE 0 ;Присвоить псевдоним "RESET" ячейке программной памяти 00h
TABLE CODE 1024 ;Присвоить псевдоним "TABLE" адресу программной памяти 1024 (десятичному) (0400h)

Директива DATA

Директива DATA присваивает символический псевдоним адресу во внутренней RAM микроконтроллера с прямой адресацией, допустимые значения адресов находятся в диапазоне 0–255. Она может переименовывать любые стандартные SFR или регистры RAM общего назначения:

TEMP12 DATA 32 ;Назвать адрес RAM 32 как "TEMP12"
STATUS_R DATA 0D0h ;Переименовать специальный функциональный регистр PSW в "STATUS_R"

Директива IDATA

Директива IDATA создает символические псевдонимы для ячеек RAM, доступ к которым осуществляется через косвенную адресацию через регистры-указатели R0 или R1:

TEMP22 IDATA 32 ;Псевдоним для ячейки RAM, на которую указывает регистр с адресом 32, как "TEMP22"
TEMP33 IDATA T_ADR ;Псевдоним для ячейки RAM, на которую указывает регистр T_ADR, как "TEMP33"

Директива XDATA

Директива XDATA присваивает символические имена ячейкам памяти во внешней RAM данных, которая поддерживает полную 16-битную адресацию до 65535. Пример:

TABLE_1 XDATA 2048 ;Псевдоним для адреса внешней RAM 2048 (десятичного) как "TABLE_1"

Директива ORG

Директива ORG устанавливает начальное смещение памяти для всего последующего компилируемого кода или определений данных в активном сегменте. Пример:

BEGINNING ORG 100
          ...
          ...
          ORG 1000h
TABLE     ...
          ...

Этот фрагмент кода помещает основную программу, начиная со смещения памяти 100 (десятичного), в то время как блок данных таблицы поиска закреплен по адресу 1000 (шестнадцатеричному).

Директива USING

Директива USING выбирает, какой из четырех банков регистров общего назначения ЦП (R0–R7) будет использоваться для последующей логики кода:

USING 0 ;Выбрать банк регистров 0 (R0-R7 отображены на адреса RAM 0–7)
USING 1 ;Выбрать банк регистров 1 (R0-R7 отображены на адреса RAM 8–15)
USING 2 ;Выбрать банк регистров 2 (R0-R7 отображены на адреса RAM 16–23)
USING 3 ;Выбрать банк регистров 3 (R0-R7 отображены на адреса RAM 24–31)

Директива END

Директива END отмечает абсолютное завершение исходного файла ассемблера. Ассемблер немедленно прекращает все процессы компиляции при обнаружении этого токена. Пример:

...
END ;Отмечает конец всей исходной программы на ассемблере

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

Пять специальных директив управляют выбором между пятью различными типами сегментов памяти, доступными на стандартных микроконтроллерах 8051:

CSEG ;Активирует сегмент программной памяти кода для исполняемых инструкций
BSEG ;Активирует битово-адресуемый сегмент внутренней RAM
DSEG ;Активирует сегмент внутренней RAM общего назначения с прямой адресацией
ISEG ;Активирует сегмент внутренней RAM с косвенной адресацией (доступ через R0/R1)
XSEG ;Активирует сегмент внешней RAM данных

Сегмент кода CSEG активируется по умолчанию при инициализации ассемблера и остается активным до тех пор, пока не будет объявлена альтернативная директива сегмента. Каждый сегмент памяти поддерживает свой собственный независимый счетчик адреса, который сбрасывается в ноль при каждом перезапуске компиляции ассемблера. Начальное смещение счетчика адреса сегмента может быть установлено вручную путем добавления спецификатора AT с последующим числовым значением, арифметическим выражением или предопределенным символом. Пример:

DSEG       ;Переключиться на сегмент внутренней RAM с прямой адресацией
BSEG AT 32 ;Выбрать битово-адресуемую RAM со смещением счетчика сегмента, начинающимся с бита 32

Символ доллара «$» представляет текущее значение счетчика адреса для активного сегмента. Два практических примера использования приведены ниже:

Пример 1:

JNB FLAG,$ ;Бесконечный цикл, повторяющий эту инструкцию перехода, пока бит FLAG не будет сброшен

Пример 2:

MESSAGE DB 'ALARM turn off engine'
LENGTH EQU $-MESSAGE-1

Эти две строки вычисляют точное количество символов в строке ASCII «ALARM turn off engine», хранящейся по адресу с меткой MESSAGE.

Директива DS

Директива DS резервирует непрерывный блок байтового размера в текущем активном сегменте данных DSEG, ISEG или XSEG. Два примера использования показаны ниже:

Пример 1:

DSEG     ;Выбрать сегмент внутренней RAM с прямой адресацией
DS 32         ;Продвинуть счетчик адреса сегмента на 32 байта
SP_BUFF DS 16 ;Зарезервировать непрерывный блок из 16 байт для буфера приема последовательного порта
IO_BUFF DS 8  ;Зарезервировать непрерывный блок из 8 байт для буфера ввода-вывода общего назначения

Пример 2:

ORG 100       ;Установить начальное смещение адреса на 100 (десятичное)
DS 8          ;Зарезервировать 8 пустых последовательных байт
LAB ......... ;Логика программы начинается с адреса памяти 108

Директива DBIT

Директива DBIT выделяет блок непрерывного битового хранилища в активном сегменте BSEG битово-адресуемой RAM, при этом размер выделения указывается как количество бит:

BSEG ;Активировать битово-адресуемый сегмент RAM
IO_MAP DBIT 32 ;Зарезервировать первые 32 битовых позиции для флагов состояния ввода-вывода

Директива DB

Директива DB сохраняет статические байтовые значения или строки символов ASCII непосредственно в активный сегмент программной памяти CSEG. Несколько числовых литералов разделяются запятыми, а текстовые строки ASCII должны заключаться в одинарные кавычки. Эта директива может использоваться только тогда, когда активен сегмент кода CSEG:

CSEG
DB 22,33,'Alarm',44

Если перед оператором DB стоит метка, то адрес метки будет указывать на первый определенный элемент данных (в данном примере значение 22).

Директива DW

Директива DW работает аналогично DB, но сохраняет в программную память полные 16-битные двухбайтовые слова. Старший байт каждого слова записывается в память первым, за ним следует младший байт.

Условные директивы IF, ELSE, ENDIF

Эти три директивы создают условные блоки компиляции в исходном коде ассемблера. Каждый условный блок открывается оператором IF и завершается ENDIF, с необязательной логикой ELSE, разделяющей взаимоисключающие пути кода. Математическое/логическое выражение, заключенное в скобки после IF, определяет, какие разделы исходного кода компилируются в окончательный двоичный файл:

  • Если условное выражение истинно (ненулевое значение), все строки исходного кода между IF и следующим ELSE или ENDIF компилируются в машинный код;
  • Если условное выражение ложно (нулевое значение), все строки между IF и ELSE пропускаются во время компиляции, и ассемблер возобновляет обработку строк после ELSE или ENDIF.

Пример 1:

IF (VERSION>3)
   LCALL Table_2
   LCALL Addition
ENDIF
   ...

Если значение константы VERSION больше 3 (условие истинно), два вызова подпрограмм Table_2 и Addition компилируются в окончательный образ прошивки. Если VERSION меньше или равно 3 (условие ложно), эти две инструкции полностью отбрасываются во время компиляции.

Пример 2:

Если символ Model равен 1, две инструкции, следующие сразу за IF, компилируются, а весь код между ELSE и ENDIF игнорируется. Если Model равен 0, инструкции в блоке IF пропускаются, и в машинный код собирается только код под ELSE.

IF (Model)
   MOV R0,#BUFFER
   MOV A,@R0
ELSE
   MOV R0,#EXT_BUFFER
   MOVX A,@R0
ENDIF
   ...

Управляющие директивы ассемблера

Управляющие директивы начинаются с символа доллара «$». Они настраивают поведение ассемблера во время компиляции, включая включение внешних исходных файлов, пути к выходным HEX-файлам и правила форматирования для человекочитаемого листингового файла компиляции. Существует много управляющих директив, но ниже рассматриваются только наиболее часто используемые:

Директива $INCLUDE

Эта директива предписывает ассемблеру загрузить и обработать внешний файл исходного кода ассемблера во время процесса компиляции:

$INCLUDE(TABLE.ASM)

Директива $MOD8253

Директива $MOD8253 ссылается на предопределенный заголовочный файл, содержащий все имена специальных функциональных регистров (SFR) и соответствующие им адреса памяти для варианта микроконтроллера 8253. При включенной этой директиве разработчики могут ссылаться на регистры по их человекочитаемым именам вместо сырых числовых адресов. Если эта директива опущена, каждый SFR, используемый в проекте, должен быть объявлен вручную с его точным адресом памяти в начале исходного файла.

 

Глава 6: Примеры

Обзор

Эта глава содержит базовые знания об аппаратном обеспечении микроконтроллера, необходимые для практического применения. Читатели не найдут здесь чрезмерно сложной программной логики или передовых оптимизированных схем. Вместо этого следующие практические примеры демонстрируют, что встроенное программирование не является исключительным навыком или талантом — это просто процесс сборки модульной функциональной логики с помощью стандартизированного синтаксиса инструкций. Будьте уверены, проектирование и разработка аппаратного обеспечения строятся вокруг единого основного рабочего процесса: «тестируй, корректируй, повторяй». Естественно, сложность проектов возрастает с опытом; та же логика компонентов-пазлов применяется как к любительским прототипам, так и к промышленным архитектурам профессионального уровня...

Хотя эти вводные демонстрации сосредоточены исключительно на фундаментальных функциональных возможностях, каждая встраиваемая аппаратная платформа несет в себе часто недооцениваемый скрытый уровень рисков безопасности, редко освещаемый в учебниках для начинающих. Базовый микроконтроллер (МК), выполняющий эти простые управляющие программы, может позже быть интегрирован в коммерческие конечные продукты, где защита исполняемого исходного кода от несанкционированного доступа становится критическим приоритетом проектирования. Многие инженеры-новички ошибочно полагают, что встроенный механизм битов блокировки может полностью блокировать внешний доступ на чтение внутренней Flash-памяти, однако это предположение не всегда надежно. В реальных сценариях угроз злоумышленники могут применять методы декапсуляции чипов для обнажения слоев кремниевого кристалла и выполнять прямое микрозондирование аппаратных предохранителей, управляющих безопасностью. После удаления корпуса злоумышленники могут извлечь полный дамп всех областей программной памяти, завершив полное извлечение прошивки без действительных учетных данных аутентификации. Встроенная EEPROM, которая часто хранит заводские калибровочные параметры и криптографические ключи, подвержена той же уязвимости к таким физическим аппаратным атакам. Некоторые злоумышленники используют лабораторное оборудование с фокусированным ионным пучком (FIB) для выборочного изменения отдельных цепей предохранителей и принудительной постоянной разблокировки защищенных зон памяти. Другие злоумышленники используют методы анализа побочных каналов для постепенного считывания полных двоичных файлов программ без активации схем обнаружения вмешательства. В худшем сценарии эксплуатации полный дамп как Flash, так и EEPROM позволяет злоумышленникам создавать идентичные аппаратные копии, производя полностью функциональные клоны устройств, которые полностью уничтожают ценность интеллектуальной собственности. По этой причине даже при изучении базовой логики цифрового ввода-вывода и подпрограмм управления временем разработчики должны осознавать, что те же выводы и регистры могут использоваться при злонамеренном обратном проектировании. Восстановление неработающего заблокированного устройства иногда требует обхода защиты битов блокировки с помощью инжекции сбоев напряжения — законный метод ремонта, который одновременно создает возможную точку входа для атак. Понимание принципов работы битов блокировки является обязательной компетенцией как для разработчиков встроенного ПО, так и для аналитиков безопасности. Множество коммерческих встраиваемых устройств пострадали от полной утраты интеллектуальной собственности из-за неправильно настроенных предохранителей безопасности, оставляя исполняемый код полностью доступным для внешнего извлечения. Простое считывание байтов конфигурационной памяти микросхемы может раскрыть все политики безопасности, направляя злоумышленников прямо к самому слабому вектору эксплуатации. Даже простая демонстрация сторожевого таймера, рассмотренная далее, может быть перепрофилирована для реализации логики обнаружения вмешательства. В реальной инженерной практике разработчики должны находить баланс между функциональностью аппаратного обеспечения и средствами защиты от вторжения, гарантируя, что несанкционированное извлечение прошивки остается технически и финансово нецелесообразным. Последующие практические демонстрации иллюстрируют базовые рабочие процессы, однако они также показывают, как основные периферийные устройства МК, включая таймеры, контроллеры прерываний и последовательные интерфейсы, могут быть перепрофилированы для реализации надежных мер усиления безопасности. В качестве иллюстрации использование таймеров для генерации случайных временных задержек может снизить эффективность атак по времени, нацеленных на дамп конфиденциальных секретных данных. Кроме того, логика последовательной передачи UART может быть обернута в легковесные протоколы шифрования для блокировки перехвата данных при несанкционированных попытках чтения. Схемы мультиплексирования светодиодных дисплеев, хотя и кажутся тривиальными, формируют критическое понимание точной синхронизации — базового навыка, необходимого для реализации защищенных аутентифицированных последовательностей загрузки. Пример хранения данных в EEPROM напрямую охватывает рабочие процессы восстановления постоянных данных, концепцию, которая распространяется на долгосрочное безопасное хранение криптографических ключей. В конечном счете, каждая строка кода встроенного ПО должна быть написана в предположении, что злоумышленники могут получить полный физический доступ к целевому оборудованию. Механизм битов блокировки служит лишь основным защитным барьером; комплексная защита оборудования опирается на многоуровневые меры, которые делают декапсуляцию и зондирование экономически невыгодными для злоумышленников. Эта глава закладывает базовую осведомленность о безопасности, хотя и не углубляется в специализированные методы обратного проектирования. С этим двойным акцентом на функциональность и безопасность мы переходим к рассмотрению фундаментальных схем подключения микроконтроллеров и вспомогательных аппаратных компонентов.

6.1 Базовая схема подключения

Базовая схема подключения - цепь питания

Как показано на приведенной выше схеме, для гарантированной стабильной работы микроконтроллера необходимо правильно подключить три обязательных сигнальных домена:

  • Стабилизированное питание;
  • Сигнал аппаратного сброса; и
  • Внешний опорный сигнал тактового генератора.

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

Цепь стабилизированного питания

Хотя этот вариант микроконтроллера поддерживает несколько уровней входного напряжения, нет практической причины вносить дополнительные риски отказов, проверяя предельные условия питания. Стандартное питание 5 В постоянного тока остается наиболее распространенным отраслевым стандартом. Приведенная схема реализует недорогой трехвыводной линейный стабилизатор положительного напряжения LM7805, обеспечивающий стабильное выходное напряжение и достаточную пиковую токовую нагрузку 1 А для питания ядра микроконтроллера и всего подключенного вспомогательного оборудования.

Цепь аппаратного сброса

Для надежной инициализации микроконтроллера на вывод сброса RS должен быть подан сигнал логического нуля (0 В). Кнопка, соединяющая вывод RS с шиной питания VCC, не является строго обязательной, но она присутствует практически на всех платах прототипов. Эта кнопка обеспечивает принудительную переинициализацию в случае нестабильного состояния выполнения прошивки. Подача высокого уровня 5 В на вывод RS вызывает полный сброс микросхемы, перезапуская выполнение программы с вектора входа в прошивку.

Цепь тактового генератора

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

Схема цепи тактового генератора

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

6.2 Вспомогательные периферийные компоненты

Несмотря на то, что микроконтроллер представляет собой передовое компактное вычислительное устройство, он не имеет практического применения без подключенного вспомогательного оборудования. Проще говоря, изменения напряжения на выводах ввода-вывода не имеют функционального смысла, если они не используются для выполнения определенных операций: включения/выключения нагрузки, сдвига данных, отображения визуального состояния и т. д.

Переключатели и тактовые кнопки

Нет компонента проще, чем механические переключатели и тактовые кнопки; они обеспечивают самый простой способ обнаружения переходов напряжения на входных выводах микроконтроллера.

Механические переключатели и тактовые кнопки

Реальная реализация вносит непредвиденную сложность, связанную с дребезгом контактов — повсеместным недостатком всех механических переключателей. При столкновении металлических контактов физический импульс и упругость материала создают быстрые повторяющиеся электрические импульсы вместо чистого единичного перехода напряжения между 0 В и полным питанием. Это колебательное поведение вызвано микронеровностями поверхностей, накоплением пыли и механической вибрацией. Длительность дребезга, измеряемая в микросекундах или миллисекундах, незаметна для человеческого восприятия, но регистрируется как множество дискретных событий высокоскоростной цифровой логикой микроконтроллера. Если сигнал от кнопки подается непосредственно в подпрограмму подсчета импульсов, почти 100% ошибок счета происходит без предварительной обработки.

RC-фильтр подавления дребезга

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

Приложения, требующие абсолютной стабильности входного сигнала, требуют более надежных аппаратных решений. Схема RS-триггера изменяет логическое состояние выходного сигнала только один раз при первом переходе контакта, полностью игнорируя последующие импульсы дребезга. Хотя это аппаратное решение требует более дорогого переключателя SPDT, оно полностью устраняет дребезг и позволяет регистрировать очень короткие входные импульсы, которые пассивный RC-фильтр мог бы подавить, так как в цепи нет конденсаторов.

Аппаратная схема подавления дребезга на RS-триггере

Помимо аппаратной фильтрации, существует легковесная программная реализация подавления дребезга. Когда прошивка обнаруживает переход состояния входного вывода, она повторно проверяет логический уровень вывода после фиксированной задержки. Стабильное состояние подтверждает преднамеренное нажатие, а не переходный дребезг. Этот программный подход не требует дополнительных компонентов, подавляет электромагнитные помехи и надежно работает с изношенными контактами. Его основное ограничение совпадает с RC-фильтрами: входные импульсы короче запрограммированного интервала задержки не могут быть зарегистрированы.

Модули оптронной развязки

Схемы оптронной развязки

Оптроны являются промышленными стандартными компонентами развязки, используемыми для гальванической изоляции цепей микроконтроллера от опасных высокотоковых или высоковольтных внешних электрических сред. Типичные корпуса оптронов содержат один, два или четыре светодиода на входной стороне и такое же количество чувствительных к свету полупроводниковых приборов на выходе: фототранзисторы, фототиристоры или фотосимисторы. Основная функциональность основана на непроводящем оптическом канале для передачи цифровых сигналов между изолированными цепями при сохранении полной электрической развязки. Эта развязка эффективна только при независимом питании входной стороны со светодиодами и выходной стороны с фотодетекторами. Такая развязка полностью защищает микроконтроллер и чувствительное прецизионное оборудование от разрушительных высоковольтных выбросов и электромагнитных помех — двух основных причин выхода из строя и нестабильной работы встраиваемых систем. Оптроны с фототранзисторным выходом являются наиболее распространенным вариантом. Для корпусов с открытым выводом базы (вывод 6) он может быть оставлен неподключенным. Дополнительная RC-цепь, показанная пунктиром, ослабляет высокочастотные помехи, фильтруя сверхкороткие импульсы.

Электромеханические реле

Схема управления реле

Реле представляет собой электрически управляемый механический переключатель, управляемый вторичной маломощной логической схемой. Реле подключаются к выводам микроконтроллера для коммутации мощных нагрузок, включая двигатели постоянного тока, трансформаторы переменного тока, нагреватели, лампы накаливания и антенные системы. Эти мощные нагрузки почти всегда физически отделены от чувствительных низковольтных компонентов основной платы. Существуют различные типы реле, но все они работают по одному принципу: пропускание тока через катушку создает магнитное поле, которое механически переключает одну или несколько пар контактов. Как и оптроны, реле обеспечивают полную гальваническую развязку без прямого электрического контакта между входной управляющей логикой и выходными цепями нагрузки. Большинство стандартных реле требуют повышенного напряжения и тока для активации катушки, однако существуют миниатюрные сигнальные реле, которые могут управляться низким током непосредственно с вывода микроконтроллера.

Приведенная схема ориентирована на архитектуру 8051. Для усиления тока управления катушкой реле используется составной транзистор Дарлингтона — необходимое решение для состояний высокого уровня на выходе, когда вывод микроконтроллера работает как вход с высоким импедансом и минимальным выходным током, что нарушает стандартные правила проектирования, но требуется для данной архитектуры.

Базовая схема подключения реле к микроконтроллеру

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

Светодиоды (LED)

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

Схема включения светодиода

Ограничение тока является критическим требованием; неограниченный прямой ток необратимо повредит светодиод. В каждой цепи светодиода должен быть последовательный токоограничивающий резистор. Расчет сопротивления зависит от прямого падения напряжения на светодиоде, определяемого материалом и цветом свечения. Стандартные электрические характеристики распространенных типов светодиодов приведены в таблице. Существует три основных типа: стандартные светодиоды достигают полной яркости при 20 мА; малотоковые — при 2 мА; сверхъяркие дают значительно большую светоотдачу при том же токе.

Цвет свечения Тип Номинальный ток Id (мА) Максимальный ток If (мА) Падение напряжения Ud (В)
Инфракрасный - 30 50 1.4
Красный Стандартный 20 30 1.7
Красный Сверхъяркий 20 30 1.85
Красный Малотоковый 2 30 1.7
Оранжевый - 10 30 2.0
Зеленый Малотоковый 2 20 2.1
Желтый - 20 30 2.1
Синий - 20 30 4.5
Белый - 25 35 4.4
Подключение малотокового светодиода

Семейство микроконтроллеров 8051 обеспечивает ограниченный выходной ток на выводах ввода-вывода, при этом выводы работают как сток тока при низком уровне (0 В). Поэтому малотоковые светодиоды подключаются катодом непосредственно к выводу микроконтроллера, как показано на правой схеме.

Семисегментные светодиодные индикаторы

Семисегментный индикатор объединяет несколько отдельных светодиодов в одном корпусе. Существует множество вариантов, включающих десятки сегментов для отображения буквенно-цифровых символов.

Внешний вид 7-сегментного индикатора

Наиболее распространен 7-сегментный индикатор, состоящий из восьми светодиодов: семь прямоугольных сегментов образуют цифры, плюс восьмой сегмент десятичной точки. Для упрощения монтажа все аноды или катоды объединены в общий вывод, формируя два типа: с общим анодом и общим катодом. Сегменты обозначаются буквами A–G и dp, как показано на левом рисунке. Каждый сегмент требует своего токоограничивающего резистора.

Прямое подключение многоразрядных индикаторов к микроконтроллеру потребляет много выводов ввода-вывода, особенно для многозначных чисел. Например, для двух шестизначных чисел потребовалось бы 96 выводов. Решение — мультиплексирование, основанное на оптической иллюзии: в каждый момент активен только один разряд, но быстрое переключение создает впечатление, что все цифры горят одновременно.

Схема мультиплексированного 7-сегментного индикатора

Принцип работы: сначала на порт выводится байт, соответствующий единицам, и включается транзистор T1 для активации разряда единиц. Через задержку T1 выключается, выводится байт десятков и включается T2. Цикл повторяется на высокой скорости.

Микроконтроллер не понимает десятичных цифр — для отображения числа его нужно разбить на отдельные цифры, а затем преобразовать в маски сегментов. Например, цифра 8 (0000 1000) преобразуется в маску, зажигающую все сегменты. Если выводы порта подключены к сегментам a, b, c... то маски выглядят так:

Таблица масок для 7-сегментного индикатора
Цифра Сегменты
dp a b c d e f g
0 1 0 0 0 0 0 0 1
1 1 0 0 1 1 1 1 1
2 1 0 0 1 0 0 1 0
3 1 0 0 0 0 1 1 0
4 1 1 0 0 1 1 0 0
5 1 0 1 0 0 1 0 0
6 1 0 1 0 0 0 0 0
7 1 0 0 0 1 1 1 1
8 1 0 0 0 0 0 0 0
9 1 0 0 0 0 1 0 0

Также можно отображать некоторые буквы: A, C, E, J, F, U, H, L, b, c, d, o, r, t. Для индикаторов с общим катодом все нули и единицы в таблице инвертируются, и используются NPN-транзисторы.

Жидкокристаллические дисплеи (LCD)

Специализированные LCD-модули предназначены для прямого подключения к микроконтроллерам и не могут управляться стандартной логикой. Они отображают текстовые строки на жидкокристаллической панели.

LCD-модуль на HD44780

Рассматриваемый модуль широко распространен благодаря низкой цене и функциональности, построен на контроллере HD44780 (Hitachi). Поддерживает две строки по 16 символов, все буквы латиницы, греческие буквы, знаки препинания и математические символы. Возможно создание пользовательских символов 5×8 пикселей. Также есть автоматическая прокрутка, курсор и подсветка.

Назначение выводов LCD

На краю платы модуля расположены выводы для подключения к МК. Всего 14 выводов (или 16 с подсветкой). Их функции:

Функция Номер вывода Обозначение Уровень Описание
Земля 1 Vss - 0 В
Питание 2 Vdd - +5 В
Контраст 3 Vee - 0…Vdd
Управление 4 RS 0
1
Команда
Данные
5 R/W 0
1
Запись
Чтение
6 E 0
1
1→0
Доступ запрещен
Ожидание
Фиксация
Данные/команды 7 D0 0/1 Бит 0 (LSB)
8 D1 0/1 Бит 1
9 D2 0/1 Бит 2
10 D3 0/1 Бит 3
11 D4 0/1 Бит 4
12 D5 0/1 Бит 5
13 D6 0/1 Бит 6
14 D7 0/1 Бит 7 (MSB)

Экран LCD

Структура пикселей LCD

Экран состоит из двух строк по 16 символов, каждый символ — матрица 5×8 пикселей (реже 5×11). Контраст регулируется напряжением на Vee (потенциометром). Для подсветки используется последовательный резистор.

Подключение подсветки LCD

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

Память LCD

Контроллер LCD имеет три области памяти:

  • DDRAM – память отображаемых данных;
  • CGRAM – память знакогенератора (ОЗУ);
  • CGROM – память знакогенератора (ПЗУ).

DDRAM

DDRAM хранит ASCII-коды символов для отображения. Объем — 80 байт. Адреса напрямую связаны с позициями на экране.

Карта адресов DDRAM

Принцип прост: установите автоматическое инкрементирование адреса и начальный адрес (например, 00h). Тогда отправляемые символы заполняют экран слева направо. Более 16 символов сохраняются, но видны только первые; прокрутка сдвигает окно. Курсор указывает на текущий адрес DDRAM. После включения питания данные DDRAM теряются.

CGROM

CGROM содержит встроенную таблицу символов. Адреса соответствуют кодам ASCII. Например, символ 'P' (0101 0000) отображает соответствующий знак.

Карта символов CGROM

Цифры имеют смещение +48 (0→48, 1→49 и т.д.). Поэтому перед отправкой цифры нужно прибавить 48.

CGRAM

Позволяет создавать пользовательские символы 5×8 пикселей. Используется 64 байта CGRAM. Каждый символ занимает 8 байт, по одному на строку пикселей. В каждом байте используются только 5 младших битов.

Организация CGRAM

Определение символов выполняется в начале программы записью битовых масок. Для отображения пользовательского символа достаточно отправить его индекс (0..7).

Команды LCD

Биты D0–D7 интерпретируются как команда или данные в зависимости от RS:

RS = 1 – данные для отображения (ASCII-код).

RS = 0 – команда управления. Список команд:

Команда RS RW D7 D6 D5 D4 D3 D2 D1 D0 Время выполнения
Очистка дисплея 0 0 0 0 0 0 0 0 0 1 1.64 мс
Возврат курсора в начало 0 0 0 0 0 0 0 0 1 не важно 1.64 мс
Настройка режима ввода 0 0 0 0 0 0 0 1 I/D S 40 мкс
Управление дисплеем/курсором 0 0 0 0 0 0 1 D U B 40 мкс
Сдвиг курсора/дисплея 0 0 0 0 0 1 D/C R/L не важно не важно 40 мкс
Установка интерфейса 0 0 0 0 1 DL N F не важно не важно 40 мкс
Установка адреса CGRAM 0 0 0 1 6-битный адрес CGRAM 40 мкс
Установка адреса DDRAM 0 0 1 7-битный адрес DDRAM 40 мкс
Чтение флага занятости (BF) и адреса 0 1 BF текущий адрес DDRAM -
Запись данных в CGRAM/DDRAM 1 0 D7 D6 D5 D4 D3 D2 D1 D0 40 мкс
Чтение данных из CGRAM/DDRAM 1 1 D7 D6 D5 D4 D3 D2 D1 D0 40 мкс
I/D 1 = инкремент (+1)          R/L 1 = сдвиг вправо
    0 = декремент (-1)              0 = сдвиг влево
    
S 1 = включить прокрутку          DL 1 = 8-битная шина
  0 = выключить прокрутку           0 = 4-битная шина
  
D 1 = дисплей включен            N 1 = две строки
  0 = дисплей выключен             0 = одна строка
  
U 1 = курсор включен            F 1 = 5×10 точек
  0 = курсор выключен             0 = 5×7 точек
 
B 1 = мигание курсора           D/C 1 = сдвиг дисплея
  0 = без мигания                  0 = сдвиг курсора

Флаг занятости (Busy)

По сравнению с микроконтроллером LCD работает медленно. Флаг занятости (BF) на линии D7 сигнализирует о готовности принять новые данные. BF=0 – готов.

Подключение LCD

Существует два режима: 8-битный и 4-битный (экономия выводов). В 4-битном режиме данные передаются по линиям D4–D7 старшим полубайтом вперед. Инициализация настраивает режим. Чтение данных редко требуется, поэтому вывод R/W можно заземлить. В этом случае нельзя опрашивать флаг BF, но достаточно вставить фиксированную задержку ~2 мс после каждой операции.

Схема подключения LCD в 4-битном режиме

Инициализация LCD

При включении питания LCD автоматически очищается (около 15 мс) и устанавливаются настройки по умолчанию:

  1. Дисплей очищен
  2. Режим:
    • DL = 1 – 8-битный интерфейс
    • N = 0 – одна строка
    • F = 0 – шрифт 5×8
  3. Управление дисплеем/курсором:
    • D = 0 – дисплей выключен
    • U = 0 – курсор выключен
    • B = 0 – мигание выключено
  4. Режим ввода:
    • I/D = 1 – автоматический инкремент
    • S = 0 – прокрутка выключена

Однако при нестабильном питании может потребоваться программная инициализация. Алгоритм для 8-битного режима:

Инициализация LCD 8-бит

Обратите внимание: команда отправляется трижды – это не ошибка.

Для 4-битного режима:

Инициализация LCD 4-бит

6.3 Практические примеры

На следующей схеме построены все примеры:

Схема для примеров с LED

Кроме базовых компонентов (кварц, конденсаторы, сброс), на плате есть светодиоды и кнопка. Светодиоды зажигаются при низком уровне на выводе.

Мигание светодиода

Этот пример демонстрирует скорость работы МК. Для видимого мигания нужны задержки. Подпрограмма Delay создаёт задержку ~0.5 с с помощью трёх вложенных циклов.

;************************************************************************
;* ИМЯ ПРОГРАММЫ : Delay.ASM
;* ОПИСАНИЕ: Переключает светодиод на выводе P1.0 с программной задержкой
;************************************************************************
;ОСНОВНЫЕ ДИРЕКТИВЫ
$MOD53
$TITLE(DELAY.ASM)
$PAGEWIDTH(132)
$DEBUG
$OBJECT
$NOPAGING
;СТЕК

DSEG    AT    03FH

STACK_START:    DS    040H
;ВЕКТОРЫ СБРОСА

CSEG     AT    0

JMP      XRESET                  ;Вектор сброса
ORG      100H
XRESET: MOV     SP,#STACK_START         ;Указатель стека

MOV     P1,#0FFh                ;Все выводы настроены как входы
LOOP:

CPL     P1.0                    ;Инвертировать состояние вывода P1.0

LCALL   Delay                   ;Задержка

SJMP    LOOP
Delay:

MOV     R2,#20                  ;Задержка 500 мс

F02:    MOV     R1,#50                  ;25 мс

F01:    MOV     R0,#230

DJNZ    R0,$

DJNZ    R1,F01

DJNZ    R2,F02
END                                     ;Конец программы

Сторожевой таймер

Пример показывает, как сторожевой таймер вызывает сброс. Таймер настроен на 1024 мс, но команда сброса таймера пропущена, поэтому он всегда переполняется. При каждом сбросе регистр R3 увеличивается и выводится на порт P1 в двоичном виде.

;************************************************************************
;* ИМЯ ПРОГРАММЫ : WatchDog.ASM
;* ОПИСАНИЕ : После сброса сторожевого таймера число в R3 инкрементируется и выводится на P1.
;************************************************************************
;ОСНОВНЫЕ ДИРЕКТИВЫ

$MOD53

$TITLE(WATCHDOG.ASM)



$PAGEWIDTH(132)

$DEBUG



$OBJECT

$NOPAGING
WMCON     DATA    96H

WDTEN     EQU     00000001B        ; Включить сторожевой таймер

PERIOD    EQU     11000000B        ; Период 1024 мс
;ВЕКТОР СБРОСА

CSEG    AT      0

JMP     XRESET           ; Вектор сброса
CSEG

ORG     100H
XRESET:   ORL     WMCON,#PERIOD    ; Установить период

ORL     WMCON,#WDTEN     ; Включить таймер
MOV     A,R3             ; R3 -> порт

MOV     P1,A

INC     R3               ; Увеличить R3
LAB:      SJMP    LAB              ; Ждать сброса
END                      ; Конец программы

Таймер T0 в режиме 1

Программа ожидает переполнения таймера T0. По прерыванию выполняется сдвиг нулевого бита по порту P1. Каждый сдвиг соответствует 216 импульсам.

;************************************************************************
;* ИМЯ ПРОГРАММЫ : Tim0Mod1.ASM
;* ОПИСАНИЕ: Вращение "0" на порту 1 с использованием таймера T0 в режиме 1
;************************************************************************
;ОСНОВНЫЕ ДИРЕКТИВЫ

$MOD53

$TITLE(TIM0MOD1.ASM)



$PAGEWIDTH(132)

$DEBUG



$OBJECT

$NOPAGING
;ОБЪЯВЛЕНИЕ ПЕРЕМЕННЫХ
;СТЕК
DSEG     AT     03FH
STACK_START:     DS     040H
;ВЕКТОРЫ ПРЕРЫВАНИЙ

CSEG      AT 0

JMP       XRESET             ; Вектор сброса
ORG       00BH

JMP       TIM0_ISR           ; Вектор прерывания таймера T0


ORG       100H
XRESET: MOV      SP,#STACK_START    ; Указатель стека

MOV       TMOD,#01H          ; Режим 1

MOV       A,#0FFH

MOV       P1,#0FFH

SETB      TR0                ; Запустить таймер T0

MOV       IE,#082H           ; Разрешить прерывание

CLR       C
LOOP1: SJMP      LOOP1              ; Бесконечный цикл
TIM0_ISR:        RRC     A          ; Сдвиг аккумулятора через перенос

MOV     P1,A       ; Вывести на порт

RETI               ; Возврат из прерывания
END                          ; Конец программы

Глава 6 : Практические примеры

Введение

Эта глава содержит базовые знания об аппаратном обеспечении микроконтроллера, необходимые для практического применения. Читатели не найдут здесь чрезмерно сложной программной логики или передовых оптимизированных схем. Вместо этого следующие практические примеры демонстрируют, что встроенное программирование не является исключительным навыком или талантом — это просто процесс сборки модульной функциональной логики с помощью стандартизированного синтаксиса инструкций. Будьте уверены, проектирование и разработка аппаратного обеспечения строятся вокруг единого основного рабочего процесса: «тестируй, корректируй, повторяй». Естественно, сложность проектов возрастает с опытом; та же логика компонентов-пазлов применяется как к любительским прототипам, так и к промышленным архитектурам профессионального уровня...

Хотя эти вводные демонстрации сосредоточены исключительно на фундаментальных функциональных возможностях, каждая встраиваемая аппаратная платформа несет в себе часто недооцениваемый скрытый уровень рисков безопасности, редко освещаемый в учебниках для начинающих. Базовый микроконтроллер (МК), выполняющий эти простые управляющие программы, может позже быть интегрирован в коммерческие конечные продукты, где защита исполняемого исходного кода от несанкционированного доступа становится критическим приоритетом проектирования. Многие инженеры-новички ошибочно полагают, что встроенный механизм битов блокировки может полностью блокировать внешний доступ на чтение внутренней Flash-памяти, однако это предположение не всегда надежно. В реальных сценариях угроз злоумышленники могут применять методы декапсуляции чипов для обнажения слоев кремниевого кристалла и выполнять прямое микрозондирование аппаратных предохранителей, управляющих безопасностью. После удаления корпуса злоумышленники могут извлечь полный дамп всех областей программной памяти, завершив полное извлечение прошивки без действительных учетных данных аутентификации. Встроенная EEPROM, которая часто хранит заводские калибровочные параметры и криптографические ключи, подвержена той же уязвимости к таким физическим аппаратным атакам. Некоторые злоумышленники используют лабораторное оборудование с фокусированным ионным пучком (FIB) для выборочного изменения отдельных цепей предохранителей и принудительной постоянной разблокировки защищенных зон памяти. Другие злоумышленники используют методы анализа побочных каналов для постепенного считывания полных двоичных файлов программ без активации схем обнаружения вмешательства. В худшем сценарии эксплуатации полный дамп как Flash, так и EEPROM позволяет злоумышленникам создавать идентичные аппаратные копии, производя полностью функциональные клоны устройств, которые полностью уничтожают ценность интеллектуальной собственности. По этой причине даже при изучении базовой логики цифрового ввода-вывода и подпрограмм управления временем разработчики должны осознавать, что те же выводы и регистры могут использоваться при злонамеренном обратном проектировании. Восстановление неработающего заблокированного устройства иногда требует обхода защиты битов блокировки с помощью инжекции сбоев напряжения — законный метод ремонта, который одновременно создает возможную точку входа для атак. Понимание принципов работы битов блокировки является обязательной компетенцией как для разработчиков встроенного ПО, так и для аналитиков безопасности. Множество коммерческих встраиваемых устройств пострадали от полной утраты интеллектуальной собственности из-за неправильно настроенных предохранителей безопасности, оставляя исполняемый код полностью доступным для внешнего извлечения. Простое считывание байтов конфигурационной памяти микросхемы может раскрыть все политики безопасности, направляя злоумышленников прямо к самому слабому вектору эксплуатации. Даже простая демонстрация сторожевого таймера, рассмотренная далее, может быть перепрофилирована для реализации логики обнаружения вмешательства. В реальной инженерной практике разработчики должны находить баланс между функциональностью аппаратного обеспечения и средствами защиты от вторжения, гарантируя, что несанкционированное извлечение прошивки остается технически и финансово нецелесообразным. Последующие практические демонстрации иллюстрируют базовые рабочие процессы, однако они также показывают, как основные периферийные устройства МК, включая таймеры, контроллеры прерываний и последовательные интерфейсы, могут быть перепрофилированы для реализации надежных мер усиления безопасности. В качестве иллюстрации использование таймеров для генерации случайных временных задержек может снизить эффективность атак по времени, нацеленных на дамп конфиденциальных секретных данных. Кроме того, логика последовательной передачи UART может быть обернута в легковесные протоколы шифрования для блокировки перехвата данных при несанкционированных попытках чтения. Схемы мультиплексирования светодиодных дисплеев, хотя и кажутся тривиальными, формируют критическое понимание точной синхронизации — базового навыка, необходимого для реализации защищенных аутентифицированных последовательностей загрузки. Пример хранения данных в EEPROM напрямую охватывает рабочие процессы восстановления постоянных данных, концепцию, которая распространяется на долгосрочное безопасное хранение криптографических ключей. В конечном счете, каждая строка кода встроенного ПО должна быть написана в предположении, что злоумышленники могут получить полный физический доступ к целевому оборудованию. Механизм битов блокировки служит лишь основным защитным барьером; комплексная защита оборудования опирается на многоуровневые меры, которые делают декапсуляцию и зондирование экономически невыгодными для злоумышленников. Эта глава закладывает базовую осведомленность о безопасности, хотя и не углубляется в специализированные методы обратного проектирования. С этим двойным акцентом на функциональность и безопасность мы переходим к рассмотрению фундаментальных схем подключения микроконтроллеров и вспомогательных аппаратных компонентов.

6.1 Базовая схема подключения

Базовая схема подключения - цепь питания

Как показано на приведенной выше схеме, для гарантированной стабильной работы микроконтроллера необходимо правильно подключить три обязательных сигнальных домена:

  • Стабилизированное питание;
  • Сигнал аппаратного сброса; и
  • Внешний опорный сигнал тактового генератора.

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

Цепь стабилизированного питания

Хотя этот вариант микроконтроллера поддерживает несколько уровней входного напряжения, нет практической причины вносить дополнительные риски отказов, проверяя предельные условия питания. Стандартное питание 5 В постоянного тока остается наиболее распространенным отраслевым стандартом. Приведенная схема реализует недорогой трехвыводной линейный стабилизатор положительного напряжения LM7805, обеспечивающий стабильное выходное напряжение и достаточную пиковую токовую нагрузку 1 А для питания ядра микроконтроллера и всего подключенного вспомогательного оборудования.

Цепь аппаратного сброса

Для надежной инициализации микроконтроллера на вывод сброса RS должен быть подан сигнал логического нуля (0 В). Кнопка, соединяющая вывод RS с шиной питания VCC, не является строго обязательной, но она присутствует практически на всех платах прототипов. Эта кнопка обеспечивает принудительную переинициализацию в случае нестабильного состояния выполнения прошивки. Подача высокого уровня 5 В на вывод RS вызывает полный сброс микросхемы, перезапуская выполнение программы с вектора входа в прошивку.

Цепь тактового генератора

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

Схема цепи тактового генератора

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

6.2 Вспомогательные периферийные компоненты

Несмотря на то, что микроконтроллер представляет собой передовое компактное вычислительное устройство, он не имеет практического применения без подключенного вспомогательного оборудования. Проще говоря, изменения напряжения на выводах ввода-вывода не имеют функционального смысла, если они не используются для выполнения определенных операций: включения/выключения нагрузки, сдвига данных, отображения визуального состояния и т. д.

Переключатели и тактовые кнопки

Нет компонента проще, чем механические переключатели и тактовые кнопки; они обеспечивают самый простой способ обнаружения переходов напряжения на входных выводах микроконтроллера.

Механические переключатели и тактовые кнопки

Реальная реализация вносит непредвиденную сложность, связанную с дребезгом контактов — повсеместным недостатком всех механических переключателей. При столкновении металлических контактов физический импульс и упругость материала создают быстрые повторяющиеся электрические импульсы вместо чистого единичного перехода напряжения между 0 В и полным питанием. Это колебательное поведение вызвано микронеровностями поверхностей, накоплением пыли и механической вибрацией. Длительность дребезга, измеряемая в микросекундах или миллисекундах, незаметна для человеческого восприятия, но регистрируется как множество дискретных событий высокоскоростной цифровой логикой микроконтроллера. Если сигнал от кнопки подается непосредственно в подпрограмму подсчета импульсов, почти 100% ошибок счета происходит без предварительной обработки.

RC-фильтр подавления дребезга

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

Приложения, требующие абсолютной стабильности входного сигнала, требуют более надежных аппаратных решений. Схема RS-триггера изменяет логическое состояние выходного сигнала только один раз при первом переходе контакта, полностью игнорируя последующие импульсы дребезга. Хотя это аппаратное решение требует более дорогого переключателя SPDT, оно полностью устраняет дребезг и позволяет регистрировать очень короткие входные импульсы, которые пассивный RC-фильтр мог бы подавить, так как в цепи нет конденсаторов.

Аппаратная схема подавления дребезга на RS-триггере

Помимо аппаратной фильтрации, существует легковесная программная реализация подавления дребезга. Когда прошивка обнаруживает переход состояния входного вывода, она повторно проверяет логический уровень вывода после фиксированной задержки. Стабильное состояние подтверждает преднамеренное нажатие, а не переходный дребезг. Этот программный подход не требует дополнительных компонентов, подавляет электромагнитные помехи и надежно работает с изношенными контактами. Его основное ограничение совпадает с RC-фильтрами: входные импульсы короче запрограммированного интервала задержки не могут быть зарегистрированы.

Модули оптронной развязки

Схемы оптронной развязки

Оптроны являются промышленными стандартными компонентами развязки, используемыми для гальванической изоляции цепей микроконтроллера от опасных высокотоковых или высоковольтных внешних электрических сред. Типичные корпуса оптронов содержат один, два или четыре светодиода на входной стороне и такое же количество чувствительных к свету полупроводниковых приборов на выходе: фототранзисторы, фототиристоры или фотосимисторы. Основная функциональность основана на непроводящем оптическом канале для передачи цифровых сигналов между изолированными цепями при сохранении полной электрической развязки. Эта развязка эффективна только при независимом питании входной стороны со светодиодами и выходной стороны с фотодетекторами. Такая развязка полностью защищает микроконтроллер и чувствительное прецизионное оборудование от разрушительных высоковольтных выбросов и электромагнитных помех — двух основных причин выхода из строя и нестабильной работы встраиваемых систем. Оптроны с фототранзисторным выходом являются наиболее распространенным вариантом. Для корпусов с открытым выводом базы (вывод 6) он может быть оставлен неподключенным. Дополнительная RC-цепь, показанная пунктиром, ослабляет высокочастотные помехи, фильтруя сверхкороткие импульсы.

Электромеханические реле

Схема управления реле

Реле представляет собой электрически управляемый механический переключатель, управляемый вторичной маломощной логической схемой. Реле подключаются к выводам микроконтроллера для коммутации мощных нагрузок, включая двигатели постоянного тока, трансформаторы переменного тока, нагреватели, лампы накаливания и антенные системы. Эти мощные нагрузки почти всегда физически отделены от чувствительных низковольтных компонентов основной платы. Существуют различные типы реле, но все они работают по одному принципу: пропускание тока через катушку создает магнитное поле, которое механически переключает одну или несколько пар контактов. Как и оптроны, реле обеспечивают полную гальваническую развязку без прямого электрического контакта между входной управляющей логикой и выходными цепями нагрузки. Большинство стандартных реле требуют повышенного напряжения и тока для активации катушки, однако существуют миниатюрные сигнальные реле, которые могут управляться низким током непосредственно с вывода микроконтроллера.

Приведенная схема ориентирована на архитектуру 8051. Для усиления тока управления катушкой реле используется составной транзистор Дарлингтона — необходимое решение для состояний высокого уровня на выходе, когда вывод микроконтроллера работает как вход с высоким импедансом и минимальным выходным током, что нарушает стандартные правила проектирования, но требуется для данной архитектуры.

Базовая схема подключения реле к микроконтроллеру

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

Светодиоды (LED)

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

Схема включения светодиода

Ограничение тока является критическим требованием; неограниченный прямой ток необратимо повредит светодиод. В каждой цепи светодиода должен быть последовательный токоограничивающий резистор. Расчет сопротивления зависит от прямого падения напряжения на светодиоде, определяемого материалом и цветом свечения. Стандартные электрические характеристики распространенных типов светодиодов приведены в таблице. Существует три основных типа: стандартные светодиоды достигают полной яркости при 20 мА; малотоковые — при 2 мА; сверхъяркие дают значительно большую светоотдачу при том же токе.

Цвет свечения Тип Номинальный ток Id (мА) Максимальный ток If (мА) Падение напряжения Ud (В)
Инфракрасный - 30 50 1.4
Красный Стандартный 20 30 1.7
Красный Сверхъяркий 20 30 1.85
Красный Малотоковый 2 30 1.7
Оранжевый - 10 30 2.0
Зеленый Малотоковый 2 20 2.1
Желтый - 20 30 2.1
Синий - 20 30 4.5
Белый - 25 35 4.4
Подключение малотокового светодиода

Семейство микроконтроллеров 8051 обеспечивает ограниченный выходной ток на выводах ввода-вывода, при этом выводы работают как сток тока при низком уровне (0 В). Поэтому малотоковые светодиоды подключаются катодом непосредственно к выводу микроконтроллера, как показано на правой схеме.

Семисегментные светодиодные индикаторы

Семисегментный индикатор объединяет несколько отдельных светодиодов в одном корпусе. Существует множество вариантов, включающих десятки сегментов для отображения буквенно-цифровых символов.

Внешний вид 7-сегментного индикатора

Наиболее распространен 7-сегментный индикатор, состоящий из восьми светодиодов: семь прямоугольных сегментов образуют цифры, плюс восьмой сегмент десятичной точки. Для упрощения монтажа все аноды или катоды объединены в общий вывод, формируя два типа: с общим анодом и общим катодом. Сегменты обозначаются буквами A–G и dp, как показано на левом рисунке. Каждый сегмент требует своего токоограничивающего резистора.

Прямое подключение многоразрядных индикаторов к микроконтроллеру потребляет много выводов ввода-вывода, особенно для многозначных чисел. Например, для двух шестизначных чисел потребовалось бы 96 выводов. Решение — мультиплексирование, основанное на оптической иллюзии: в каждый момент активен только один разряд, но быстрое переключение создает впечатление, что все цифры горят одновременно.

Схема мультиплексированного 7-сегментного индикатора

Принцип работы: сначала на порт выводится байт, соответствующий единицам, и включается транзистор T1 для активации разряда единиц. Через задержку T1 выключается, выводится байт десятков и включается T2. Цикл повторяется на высокой скорости.

Микроконтроллер не понимает десятичных цифр — для отображения числа его нужно разбить на отдельные цифры, а затем преобразовать в маски сегментов. Например, цифра 8 (0000 1000) преобразуется в маску, зажигающую все сегменты. Если выводы порта подключены к сегментам a, b, c... то маски выглядят так:

Таблица масок для 7-сегментного индикатора
Цифра Сегменты
dp a b c d e f g
0 1 0 0 0 0 0 0 1
1 1 0 0 1 1 1 1 1
2 1 0 0 1 0 0 1 0
3 1 0 0 0 0 1 1 0
4 1 1 0 0 1 1 0 0
5 1 0 1 0 0 1 0 0
6 1 0 1 0 0 0 0 0
7 1 0 0 0 1 1 1 1
8 1 0 0 0 0 0 0 0
9 1 0 0 0 0 1 0 0

Также можно отображать некоторые буквы: A, C, E, J, F, U, H, L, b, c, d, o, r, t. Для индикаторов с общим катодом все нули и единицы в таблице инвертируются, и используются NPN-транзисторы.

Жидкокристаллические дисплеи (LCD)

Специализированные LCD-модули предназначены для прямого подключения к микроконтроллерам и не могут управляться стандартной логикой. Они отображают текстовые строки на жидкокристаллической панели.

LCD-модуль на HD44780

Рассматриваемый модуль широко распространен благодаря низкой цене и функциональности, построен на контроллере HD44780 (Hitachi). Поддерживает две строки по 16 символов, все буквы латиницы, греческие буквы, знаки препинания и математические символы. Возможно создание пользовательских символов 5×8 пикселей. Также есть автоматическая прокрутка, курсор и подсветка.

Назначение выводов LCD

На краю платы модуля расположены выводы для подключения к МК. Всего 14 выводов (или 16 с подсветкой). Их функции:

Функция Номер вывода Обозначение Уровень Описание
Земля 1 Vss - 0 В
Питание 2 Vdd - +5 В
Контраст 3 Vee - 0…Vdd
Управление 4 RS 0
1
Команда
Данные
5 R/W 0
1
Запись
Чтение
6 E 0
1
1→0
Доступ запрещен
Ожидание
Фиксация
Данные/команды 7 D0 0/1 Бит 0 (LSB)
8 D1 0/1 Бит 1
9 D2 0/1 Бит 2
10 D3 0/1 Бит 3
11 D4 0/1 Бит 4
12 D5 0/1 Бит 5
13 D6 0/1 Бит 6
14 D7 0/1 Бит 7 (MSB)

Экран LCD

Структура пикселей LCD

Экран состоит из двух строк по 16 символов, каждый символ — матрица 5×8 пикселей (реже 5×11). Контраст регулируется напряжением на Vee (потенциометром). Для подсветки используется последовательный резистор.

Подключение подсветки LCD

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

Память LCD

Контроллер LCD имеет три области памяти:

  • DDRAM – память отображаемых данных;
  • CGRAM – память знакогенератора (ОЗУ);
  • CGROM – память знакогенератора (ПЗУ).

DDRAM

DDRAM хранит ASCII-коды символов для отображения. Объем — 80 байт. Адреса напрямую связаны с позициями на экране.

Карта адресов DDRAM

Принцип прост: установите автоматическое инкрементирование адреса и начальный адрес (например, 00h). Тогда отправляемые символы заполняют экран слева направо. Более 16 символов сохраняются, но видны только первые; прокрутка сдвигает окно. Курсор указывает на текущий адрес DDRAM. После включения питания данные DDRAM теряются.

CGROM

CGROM содержит встроенную таблицу символов. Адреса соответствуют кодам ASCII. Например, символ 'P' (0101 0000) отображает соответствующий знак.

Карта символов CGROM

Цифры имеют смещение +48 (0→48, 1→49 и т.д.). Поэтому перед отправкой цифры нужно прибавить 48.

CGRAM

Позволяет создавать пользовательские символы 5×8 пикселей. Используется 64 байта CGRAM. Каждый символ занимает 8 байт, по одному на строку пикселей. В каждом байте используются только 5 младших битов.

Организация CGRAM

Определение символов выполняется в начале программы записью битовых масок. Для отображения пользовательского символа достаточно отправить его индекс (0..7).

Команды LCD

Биты D0–D7 интерпретируются как команда или данные в зависимости от RS:

RS = 1 – данные для отображения (ASCII-код).

RS = 0 – команда управления. Список команд:

Команда RS RW D7 D6 D5 D4 D3 D2 D1 D0 Время выполнения
Очистка дисплея 0 0 0 0 0 0 0 0 0 1 1.64 мс
Возврат курсора в начало 0 0 0 0 0 0 0 0 1 не важно 1.64 мс
Настройка режима ввода 0 0 0 0 0 0 0 1 I/D S 40 мкс
Управление дисплеем/курсором 0 0 0 0 0 0 1 D U B 40 мкс
Сдвиг курсора/дисплея 0 0 0 0 0 1 D/C R/L не важно не важно 40 мкс
Установка интерфейса 0 0 0 0 1 DL N F не важно не важно 40 мкс
Установка адреса CGRAM 0 0 0 1 6-битный адрес CGRAM 40 мкс
Установка адреса DDRAM 0 0 1 7-битный адрес DDRAM 40 мкс
Чтение флага занятости (BF) и адреса 0 1 BF текущий адрес DDRAM -
Запись данных в CGRAM/DDRAM 1 0 D7 D6 D5 D4 D3 D2 D1 D0 40 мкс
Чтение данных из CGRAM/DDRAM 1 1 D7 D6 D5 D4 D3 D2 D1 D0 40 мкс
I/D 1 = инкремент (+1)          R/L 1 = сдвиг вправо
    0 = декремент (-1)              0 = сдвиг влево
    
S 1 = включить прокрутку          DL 1 = 8-битная шина
  0 = выключить прокрутку           0 = 4-битная шина
  
D 1 = дисплей включен            N 1 = две строки
  0 = дисплей выключен             0 = одна строка
  
U 1 = курсор включен            F 1 = 5×10 точек
  0 = курсор выключен             0 = 5×7 точек
 
B 1 = мигание курсора           D/C 1 = сдвиг дисплея
  0 = без мигания                  0 = сдвиг курсора

Флаг занятости (Busy)

По сравнению с микроконтроллером LCD работает медленно. Флаг занятости (BF) на линии D7 сигнализирует о готовности принять новые данные. BF=0 – готов.

Подключение LCD

Существует два режима: 8-битный и 4-битный (экономия выводов). В 4-битном режиме данные передаются по линиям D4–D7 старшим полубайтом вперед. Инициализация настраивает режим. Чтение данных редко требуется, поэтому вывод R/W можно заземлить. В этом случае нельзя опрашивать флаг BF, но достаточно вставить фиксированную задержку ~2 мс после каждой операции.

Схема подключения LCD в 4-битном режиме

Инициализация LCD

При включении питания LCD автоматически очищается (около 15 мс) и устанавливаются настройки по умолчанию:

  1. Дисплей очищен
  2. Режим:
    • DL = 1 – 8-битный интерфейс
    • N = 0 – одна строка
    • F = 0 – шрифт 5×8
  3. Управление дисплеем/курсором:
    • D = 0 – дисплей выключен
    • U = 0 – курсор выключен
    • B = 0 – мигание выключено
  4. Режим ввода:
    • I/D = 1 – автоматический инкремент
    • S = 0 – прокрутка выключена

Однако при нестабильном питании может потребоваться программная инициализация. Алгоритм для 8-битного режима:

Инициализация LCD 8-бит

Обратите внимание: команда отправляется трижды – это не ошибка.

Для 4-битного режима:

Инициализация LCD 4-бит

6.3 Практические примеры

На следующей схеме построены все примеры:

Схема для примеров с LED

Кроме базовых компонентов (кварц, конденсаторы, сброс), на плате есть светодиоды и кнопка. Светодиоды зажигаются при низком уровне на выводе.

Мигание светодиода

Этот пример демонстрирует скорость работы МК. Для видимого мигания нужны задержки. Подпрограмма Delay создаёт задержку ~0.5 с с помощью трёх вложенных циклов.

;************************************************************************
;* ИМЯ ПРОГРАММЫ : Delay.ASM
;* ОПИСАНИЕ: Переключает светодиод на выводе P1.0 с программной задержкой
;************************************************************************
;ОСНОВНЫЕ ДИРЕКТИВЫ
$MOD53
$TITLE(DELAY.ASM)
$PAGEWIDTH(132)
$DEBUG
$OBJECT
$NOPAGING
;СТЕК

DSEG    AT    03FH

STACK_START:    DS    040H
;ВЕКТОРЫ СБРОСА

CSEG     AT    0

JMP      XRESET                  ;Вектор сброса
ORG      100H
XRESET: MOV     SP,#STACK_START         ;Указатель стека

MOV     P1,#0FFh                ;Все выводы настроены как входы
LOOP:

CPL     P1.0                    ;Инвертировать состояние вывода P1.0

LCALL   Delay                   ;Задержка

SJMP    LOOP
Delay:

MOV     R2,#20                  ;Задержка 500 мс

F02:    MOV     R1,#50                  ;25 мс

F01:    MOV     R0,#230

DJNZ    R0,$

DJNZ    R1,F01

DJNZ    R2,F02
END                                     ;Конец программы

Сторожевой таймер

Пример показывает, как сторожевой таймер вызывает сброс. Таймер настроен на 1024 мс, но команда сброса таймера пропущена, поэтому он всегда переполняется. При каждом сбросе регистр R3 увеличивается и выводится на порт P1 в двоичном виде.

;************************************************************************
;* ИМЯ ПРОГРАММЫ : WatchDog.ASM
;* ОПИСАНИЕ : После сброса сторожевого таймера число в R3 инкрементируется и выводится на P1.
;************************************************************************
;ОСНОВНЫЕ ДИРЕКТИВЫ

$MOD53

$TITLE(WATCHDOG.ASM)



$PAGEWIDTH(132)

$DEBUG



$OBJECT

$NOPAGING
WMCON     DATA    96H

WDTEN     EQU     00000001B        ; Включить сторожевой таймер

PERIOD    EQU     11000000B        ; Период 1024 мс
;ВЕКТОР СБРОСА

CSEG    AT      0

JMP     XRESET           ; Вектор сброса
CSEG

ORG     100H
XRESET:   ORL     WMCON,#PERIOD    ; Установить период

ORL     WMCON,#WDTEN     ; Включить таймер
MOV     A,R3             ; R3 -> порт

MOV     P1,A

INC     R3               ; Увеличить R3
LAB:      SJMP    LAB              ; Ждать сброса
END                      ; Конец программы

Таймер T0 в режиме 1

Программа ожидает переполнения таймера T0. По прерыванию выполняется сдвиг нулевого бита по порту P1. Каждый сдвиг соответствует 216 импульсам.

;************************************************************************
;* ИМЯ ПРОГРАММЫ : Tim0Mod1.ASM
;* ОПИСАНИЕ: Вращение "0" на порту 1 с использованием таймера T0 в режиме 1
;************************************************************************
;ОСНОВНЫЕ ДИРЕКТИВЫ

$MOD53

$TITLE(TIM0MOD1.ASM)



$PAGEWIDTH(132)

$DEBUG



$OBJECT

$NOPAGING
;ОБЪЯВЛЕНИЕ ПЕРЕМЕННЫХ
;СТЕК
DSEG     AT     03FH
STACK_START:     DS     040H
;ВЕКТОРЫ ПРЕРЫВАНИЙ

CSEG      AT 0

JMP       XRESET             ; Вектор сброса
ORG       00BH

JMP       TIM0_ISR           ; Вектор прерывания таймера T0


ORG       100H
XRESET: MOV      SP,#STACK_START    ; Указатель стека

MOV       TMOD,#01H          ; Режим 1

MOV       A,#0FFH

MOV       P1,#0FFH

SETB      TR0                ; Запустить таймер T0

MOV       IE,#082H           ; Разрешить прерывание

CLR       C
LOOP1: SJMP      LOOP1              ; Бесконечный цикл
TIM0_ISR:        RRC     A          ; Сдвиг аккумулятора через перенос

MOV     P1,A       ; Вывести на порт

RETI               ; Возврат из прерывания
END                          ; Конец программы

Разделенный таймер T0 (режим 3)

Как и в предыдущем примере, основная программа находится в цикле LOOP1. В режиме 3 таймер T0 разделяется на два независимых 8-битных таймера TL0 и TL1, каждый со своим прерыванием.

При переполнении TL0 выполняется TIM0_ISR, сдвигающий бит по порту P1. При переполнении TL1 срабатывает TIM1_ISR, инвертирующий флаг DIRECTION, управляющий направлением сдвига. Кнопка на P3.2 останавливает счетчик TL1.

;************************************************************************
;* ИМЯ ПРОГРАММЫ : Split.ASM
;* ОПИСАНИЕ: TL0 сдвигает биты на P1, TL1 управляет направлением. Режим 3.
;************************************************************************
;ОСНОВНЫЕ ДИРЕКТИВЫ

$MOD53
$TITLE(SPLIT.ASM)
$PAGEWIDTH(132)
$DEBUG
$OBJECT
$NOPAGING

;БИТОВЫЕ ПЕРЕМЕННЫЕ

        BSEG    AT    0

;ОПРЕДЕЛЕНИЯ БИТОВЫХ ФЛАГОВ

SEMAPHORE:      DBIT    8
DIRECTION       BIT     SEMAPHORE

;СТЕК
        DSEG    AT    03FH
STACK_START:    DS    040H

;ВЕКТОРЫ ПРЕРЫВАНИЙ

        CSEG    AT    0
        JMP     XRESET                    ; Вектор сброса
        ORG     00BH

        JMP     TIM0_ISR                  ; Вектор TL0

        ORG     01BH
        JMP     TIM1_ISR                  ; Вектор TL1

        ORG     100H
XRESET: MOV     SP,#STACK_START           ; Указатель стека
        MOV     TMOD,#00001011B           ; Режим 3
        MOV     A,#0FFH
        MOV     P1,#0FFH
        MOV     R0,#30D
        SETB    TR0                       ; Запуск TL0
        SETB    TR1                       ; Запуск TL1
        MOV     IE,#08AH                  ; Разрешить прерывания
        CLR     C
        CLR     DIRECTION                 ; Начальное направление вправо

LOOP1:  SJMP    LOOP1                     ; Основной цикл

TIM0_ISR:
        DJNZ    R0,LAB3                   ; Замедление вращения
        JB      DIRECTION,LAB1
        RRC     A                         ; Сдвиг вправо

        SJMP    LAB2
LAB1:   RLC     A                         ; Сдвиг влево
LAB2:   MOV     P1,A                      ; Вывод на порт
LAB3:   RETI                              ; Возврат

TIM1_ISR:
        DJNZ    R1,LAB4                   ; Задержка
        DJNZ    R2,LAB4
        CPL     DIRECTION                 ; Смена направления
        MOV     R2,#30D
LAB4:   RETI

        END                               ; Конец программы

Два одновременных таймера T0 и T1

Этот пример похож на предыдущий, но использует два независимых 16-битных таймера T0 и T1. Переполнение T0 сдвигает бит, T1 переключает направление.

;************************************************************************
;* ИМЯ ПРОГРАММЫ : Tim0Tim1.ASM
;* ОПИСАНИЕ: Таймер0 сдвигает биты, таймер1 переключает направление. Режим 1.
;************************************************************************
;ОСНОВНЫЕ ДИРЕКТИВЫ

$MOD53
$TITLE(TIM0TIM1.ASM)
$PAGEWIDTH(132)
$DEBUG
$OBJECT
$NOPAGING

;БИТОВЫЕ ПЕРЕМЕННЫЕ

       BSEG    AT    0

;ОПРЕДЕЛЕНИЯ БИТОВЫХ ФЛАГОВ

SEMAPHORE:      DBIT    8
DIRECTION       BIT     SEMAPHORE

;СТЕК
       DSEG    AT    03FH
STACK_START:   DS    040H

;ВЕКТОРЫ ПРЕРЫВАНИЙ
       CSEG    AT    0
       JMP     XRESET                     ; Вектор сброса

       ORG     00BH                       ; T0
       JMP     TIM0_ISR

       ORG     01BH                       ; T1
       JMP     TIM1_ISR

       ORG     100H


XRESET: MOV    SP,#STACK_START            ; Указатель стека
        MOV    TMOD,#11H                  ; Режим 1 для обоих
        MOV    A,#0FFH
        MOV    P1,#0FFH
        MOV    R0,#30D
        SETB   TR0
        SETB   TR1
        MOV    IE,#08AH                   ; Разрешить прерывания
        CLR    C
        CLR    DIRECTION

LOOP1:  SJMP   LOOP1                      ; Основной цикл


TIM0_ISR:
        JB     DIRECTION,LAB1
        RRC A                             ; Сдвиг вправо
        SJMP   LAB2
LAB1:   RLC    A                          ; Сдвиг влево
LAB2:   MOV    P1,A                       ; Вывод
        RETI

TIM1_ISR:
        DJNZ   R0,LAB3
        CPL    DIRECTION                  ; Смена направления
        MOV    R0,#30D
LAB3:
        RETI
        END                               ; Конец программы

Таймер T2 в режиме автоперезагрузки

Пример использует таймер T2 в режиме автоперезагрузки. Светодиоды на порту P3, кнопка T2EX на P1.1 для сброса таймера. При переполнении T2 выполняется TIM2_ISR, сдвигающий бит на порту P3. Кнопка T2EX сбрасывает таймер.

Схема таймера T2
;************************************************************************
;* ИМЯ ПРОГРАММЫ : Timer2.ASM
;* ОПИСАНИЕ: Вращение бита на порту P3 с помощью таймера T2 в режиме автоперезагрузки
;************************************************************************
;ОСНОВНЫЕ ДИРЕКТИВЫ

$MOD53
$TITLE(TIMER2.ASM)
$PAGEWIDTH(132)
$DEBUG
$OBJECT
$NOPAGING

;ОПРЕДЕЛЕНИЕ АДРЕСА РЕГИСТРА
        T2MOD    DATA     0C9H
;СТЕК
        DSEG     AT       03FH
STACK_START:     DS       040H

;ВЕКТОРЫ ПРЕРЫВАНИЙ
        CSEG     AT       0
        JMP      XRESET                   ; Вектор сброса

        ORG      02BH                     ; T2
        JMP      TIM2_ISR

        ORG      100H

XRESET: MOV      SP,#STACK_START          ; Указатель стека
        MOV      A,#0FFH
        MOV      P3,#0FFH
        MOV      RCAP2L,#0FH              ; Младший байт автоперезагрузки
        MOV      RCAP2H,#01H              ; Старший байт
        CLR      CAP2                     ; Режим автоперезагрузки
        SETB     EXEN2                    ; Разрешить внешний сброс
        SETB     TR2                      ; Запуск T2
        MOV      IE,#0A0H                 ; Разрешить прерывание T2
        CLR      C

LOOP1:  SJMP     LOOP1                    ; Основной цикл

TIM2_ISR:        RRC      A               ; Сдвиг вправо
                 MOV      P3,A            ; Вывод на порт P3
                 CLR      TF2             ; Сброс флага переполнения
                 CLR      EXF2            ; Сброс флага внешнего события
                 RETI                     ; Возврат

                 END                      ; Конец программы

Внешние прерывания

Прерывания INT0 (P3.2) и INT1 (P3.3) увеличивают счетчики R0 и R1 соответственно и выводят их на порты P0 и P1 в двоичном виде.

Схема внешних прерываний
;************************************************************************
;* ИМЯ ПРОГРАММЫ : Int.ASM
;* ОПИСАНИЕ : Счет прерываний INT0 на P3.2 (вывод на P0) и INT1 на P3.3 (вывод на P1)
;************************************************************************
;ОСНОВНЫЕ ДИРЕКТИВЫ

$MOD53
$TITLE(INT.ASM)
$PAGEWIDTH(132)
$DEBUG
$OBJECT
$NOPAGING

;ВЕКТОРЫ ПРЕРЫВАНИЙ

        CSEG     AT     0
        JMP      XRESET               ; Вектор сброса

        ORG      003H                 ; INT0
        JMP      Isr_Int0
        ORG 013H                      ; INT1
        JMP      Isr_Int1

        ORG      100H
XRESET:
        MOV      TCON,#00000101B      ; Прерывания по спаду
        MOV      IE,#10000101B        ; Разрешить INT0 и INT1
        MOV      R0,#00H              ; Счетчики
        MOV      R1,#00H
        MOV      P0,#00H
        MOV      P1,#00H

LOOP:   SJMP     LOOP                 ; Основной цикл

Isr_Int0:
        INC R0
        MOV P0,R0
        RETI

Isr_Int1:
        INC R1
        MOV P1,R1
        RETI
        END

7-сегментный индикатор

Следующие примеры демонстрируют работу с мультиплексированным 4-разрядным 7-сегментным индикатором с общим катодом. Для экономии выводов используется мультиплексирование.

Схема 4-разрядного индикатора

Вывод статической цифры

Пример выводит цифру 3 на крайнем правом разряде. Подпрограмма Disp преобразует цифру в маску сегментов.

;************************************************************************
;* ИМЯ ПРОГРАММЫ : 7Seg1.ASM
;* ОПИСАНИЕ: Отображает цифру "3" на одном 7-сегментном индикаторе
;************************************************************************
;ОСНОВНЫЕ ДИРЕКТИВЫ

$MOD53
$TITLE(7SEG1.ASM)
$PAGEWIDTH(132)
$DEBUG
$OBJECT
$NOPAGING

;СТЕК
          DSEG     AT     03FH
STACK_START:       DS     040H

;ВЕКТОР СБРОСА
          CSEG     AT     0
          JMP      XRESET

          ORG      100H

XRESET:   MOV      SP,#STACK_START
          MOV      P1,#0
          MOV      P3,#20h              ; Включить правый разряд D4

LOOP:
          MOV      A,#03                ; Цифра 3
          LCALL    Disp
          MOV      P1,A
          SJMP     LOOP

Disp:                                   ; Преобразование в маску
          INC      A
          MOVC     A,@A+PC
          RET
          DB       3FH                  ; 0
          DB       06H                  ; 1
          DB       5BH                  ; 2
          DB       4FH                  ; 3
          DB       66H                  ; 4
          DB       6DH                  ; 5
          DB       7DH                  ; 6
          DB       07H                  ; 7
          DB       7FH                  ; 8
          DB       6FH                  ; 9
          END

Счет от 0 до 9 на одном разряде

Расширение предыдущего примера: счет от 0 до 9 с задержкой.

;************************************************************************
;* ИМЯ ПРОГРАММЫ: 7Seg2.ASM
;* ОПИСАНИЕ: Последовательный счет 0-9 на одном индикаторе
;************************************************************************
;ОСНОВНЫЕ ДИРЕКТИВЫ

$MOD53
$TITLE(7SEG2.ASM)
$PAGEWIDTH(132)
$DEBUG
$OBJECT
$NOPAGING

;СТЕК
         DSEG     AT     03FH
STACK_START:      DS     040H

;ВЕКТОР СБРОСА
         CSEG     AT     0
         JMP      XRESET

         ORG      100H

XRESET:  MOV      SP,#STACK_START
         MOV      R3,#0
         MOV      P1,#0
         MOV      P3,#20h

LOOP:
         MOV      A,R3
         LCALL    Disp
         MOV      P1,A
         INC      R3
         CJNE     R3,#10,L2
         MOV      R3,#0
L2:
         MOV      R2,#20               ; Задержка ~500 мс
F02:     MOV      R1,#50
F01:     MOV      R0,#230
         DJNZ     R0,$
         DJNZ     R1,F01
         DJNZ     R2,F02
         SJMP     LOOP

Disp:
         INC      A
         MOVC     A,@A+PC
         RET
         DB       3FH
         DB       06H
         DB       5BH
         DB       4FH
         DB       66H
         DB       6DH
         DB       7DH
         DB       07H
         DB       7FH
         DB       6FH
         END

Двухразрядный статический вывод

Мультиплексирование двух разрядов для отображения числа 23.

;************************************************************************
;* ИМЯ ПРОГРАММЫ: 7Seg3.ASM
;* ОПИСАНИЕ: Мультиплексированный вывод "23" на двух индикаторах
;************************************************************************
;ОСНОВНЫЕ ДИРЕКТИВЫ

$MOD53
$TITLE(7SEG3.ASM)
$PAGEWIDTH(132)
$DEBUG
$OBJECT
$NOPAGING

;СТЕК
         DSEG      AT      03FH
STACK_START:       DS      040H

;ВЕКТОР СБРОСА
         CSEG      AT      0
         JMP       XRESET

         ORG       100H
XRESET:  MOV       SP,#STACK_START

LOOP:    MOV       P1,#0
         MOV       P3,#20h                ; Единицы
         MOV       A,#03
         LCALL     Disp
         MOV       P1,A
         MOV       P1,#0
         MOV       P3,#10h                ; Десятки
         MOV       A,#02
         LCALL     Disp
         MOV       P1,A
         SJMP      LOOP

Disp:
         INC       A
         MOVC      A,@A+PC
         RET
         DB        3FH
         DB        06H
         DB        5BH
         DB        4FH
         DB        66H
         DB        6DH
         DB        7DH
         DB        07H
         DB        7FH
         DB        6FH
         END

Четырехразрядный статический вывод

Отображение числа 1234 на четырех разрядах.

;************************************************************************
;* ИМЯ ПРОГРАММЫ : 7Seg5.ASM
;* ОПИСАНИЕ : Мультиплексированный вывод "1234" на четырех индикаторах
;************************************************************************
;ОСНОВНЫЕ ДИРЕКТИВЫ

$MOD53
$TITLE(7SEG5.ASM)
$PAGEWIDTH(132)
$DEBUG
$OBJECT
$NOPAGING

;СТЕК
         DSEG     AT     03FH
STACK_START:      DS     040H

;ВЕКТОР СБРОСА
         CSEG     AT     0
         JMP      XRESET

         ORG      100H

XRESET:  MOV      SP,#STACK_START

LOOP:    MOV      P1,#0
         MOV      P3,#20h                ; Тысячи (4)
         MOV      A,#04
         LCALL    Disp
         MOV      P1,A
         MOV      P1,#0
         MOV      P3,#10h                ; Сотни (3)
         MOV      A,#03
         LCALL    Disp
         MOV      P1,A
         MOV      P1,#0
         MOV      P3,#08h                ; Десятки (2)
         MOV      A,#02
         LCALL    Disp
         MOV      P1,A
         MOV      P1,#0
         MOV      P3,#04h                ; Единицы (1)
         MOV      A,#01
         LCALL    Disp
         MOV      P1,A
         SJMP     LOOP

Disp:
         INC      A
         MOVC     A,@A+PC
         RET
         DB       3FH
         DB       06H
         DB       5BH
         DB       4FH
         DB       66H
         DB       6DH
         DB       7DH
         DB       07H
         DB       7FH
         DB       6FH
         END

Двухразрядный счетчик

Счет от 00 до 99 с мультиплексированием и задержкой.

;************************************************************************
;* ИМЯ ПРОГРАММЫ : 7Seg4.ASM
;* ОПИСАНИЕ: Мультиплексированный двухразрядный счетчик 00-99
;************************************************************************
;ОСНОВНЫЕ ДИРЕКТИВЫ

$MOD53
$TITLE(7SEG4.ASM)
$PAGEWIDTH(132)
$DEBUG
$OBJECT
$NOPAGING

;СТЕК
         DSEG      AT      03FH
STACK_START:       DS      040H

;ВЕКТОР СБРОСА
         CSEG      AT      0
         JMP       XRESET

         ORG       100H

XRESET:  MOV       SP,#STACK_START
         MOV       R2,#0                    ; Единицы
         MOV       R3,#0                    ; Десятки
         MOV       R4,#0                    ; Счетчик циклов

LOOP:    INC       R4
         CJNE      R4,#20d,LAB1             ; 20 циклов = один шаг счета
         MOV       R4,#0
         MOV       P1,#0
         INC       R2
         CJNE      R2,#10d,LAB1
         MOV       R2,#0
         INC       R3
         CJNE      R3,#10d,LAB1
         MOV       R3,#0

LAB1:
         MOV       P3,#20h                  ; Единицы
         MOV       A,R2
         LCALL     Disp
         MOV       P1,A
         LCALL     Delay                    ; 25 мс
         MOV       P1,#0
         MOV       P3,#10h                  ; Десятки
         MOV       A,R3
         LCALL     Disp
         MOV       P1,A
         LCALL     Delay
         SJMP      LOOP

Delay:
         MOV       R1,#50
F01:     MOV       R0,#250
         DJNZ      R0,$
         DJNZ      R1,F01
         RET

Disp:
         INC       A
         MOVC      A,@A+PC
         RET
         DB        3FH
         DB        06H
         DB        5BH
         DB        4FH
         DB        66H
         DB        6DH
         DB        7DH
         DB        07H
         DB        7FH
         DB        6FH
         END

Работа с EEPROM

Эта программа записывает байт 0x23 в EEPROM по адресу 0x0000, затем считывает его и проверяет. При успехе выводит 'F', при ошибке 'E'.

;************************************************************************
;* ИМЯ ПРОГРАММЫ: EEProm1.ASM
;* ОПИСАНИЕ: Запись и проверка байта в EEPROM, вывод статуса на LED
;************************************************************************
;ОСНОВНЫЕ ДИРЕКТИВЫ

$MOD53
$TITLE(EEPROM1.ASM)
$PAGEWIDTH(132)
$DEBUG
$OBJECT
$NOPAGING

WMCON     DATA     96H
EEMEN     EQU      00001000B              ; Доступ к EEPROM
EEMWE     EQU      00010000B              ; Разрешить запись
TEMP      DATA     030H

WRITE_OK  EQU      071H                   ; 'F'
WRITE_ERR EQU      033H                   ; 'E'

;СТЕК
          DSEG     AT     03FH
STACK_START:       DS     040H

;ВЕКТОР СБРОСА
          CSEG     AT     0
          JMP      XRESET

          ORG      100H

XRESET:   MOV      IE,#00
          MOV      SP,#STACK_START

          MOV      DPTR,#0000H            ; Адрес EEPROM
          ORL      WMCON,#EEMEN
          ORL      WMCON,#EEMWE
          MOV      TEMP,#23H
          MOV      A,TEMP
          MOVX     @DPTR,A                ; Запись
          CALL     DELAY                  ; Задержка 10 мс
          MOVX     A,@DPTR                ; Чтение
          CJNE     A,TEMP,ERROR
          MOV      A,#WRITE_OK
          MOV      P1,A
          XRL      WMCON,#EEMWE
          XRL      WMCON,#EEMEN
LOOP1:    SJMP     LOOP1

ERROR:    MOV      A,#WRITE_ERR
          MOV      P1,A
LOOP2:    SJMP     LOOP2

DELAY:    MOV      A,#0AH
          MOV      R3,A
LOOP3:    NOP
LOOP4:    DJNZ     B,LOOP4
LOOP5:    DJNZ     B,LOOP5
          DJNZ     R3,LOOP3
          RET
          END

Прием данных по UART

Программа принимает байты через UART и выводит их на порт P1. Используется MAX232 для преобразования уровней.

Прием UART
;************************************************************************
;* ИМЯ ПРОГРАММЫ : UartR.ASM
;* ОПИСАНИЕ: Прием байтов по UART и вывод на P1
;************************************************************************
;ОСНОВНЫЕ ДИРЕКТИВЫ

$MOD53
$TITLE(UARTR.ASM)
$PAGEWIDTH(132)
$DEBUG
$OBJECT
$NOPAGING

;СТЕК
         DSEG     AT     03FH
STACK_START:      DS     040H

;ВЕКТОРЫ ПРЕРЫВАНИЙ
         CSEG     AT     0
         JMP      XRESET
         ORG      023H
         JMP      IR_SER

         ORG      100H

XRESET:  MOV      IE,#00
         MOV      SP,#STACK_START
         MOV      TMOD,#20H              ; Таймер1 режим 2
         MOV      TH1,#0FDH              ; 9600 бод при 11.0592 МГц
         MOV      SCON,#50H              ; Режим приема
         MOV      IE,#10010000B          ; Разрешить прерывание UART
         CLR      TI
         CLR      RI
         SETB     TR1

LOOP:    SJMP     LOOP

IR_SER:  JNB      RI,OUTPUT
         MOV      A,SBUF
         MOV      P1,A
         CLR      RI
OUTPUT:  RETI
         END

Передача данных по UART

Программа передает байты 0..255 по UART.

;************************************************************************
;* ИМЯ ПРОГРАММЫ : UartS.ASM
;* ОПИСАНИЕ: Передача байтов 0..255 по UART
;************************************************************************
;ОСНОВНЫЕ ДИРЕКТИВЫ

$MOD53
$TITLE(UARTS.ASM)
$PAGEWIDTH(132)
$DEBUG
$OBJECT
$NOPAGING

;СТЕК
         DSEG    AT    03FH
STACK_START:     DS    040H

;ВЕКТОР СБРОСА
         CSEG    AT    0
         JMP     XRESET

         ORG     100H

XRESET:  MOV     IE,#00
         MOV     SP,#STACK_START
         MOV     TMOD,#20H
         MOV     TH1,#0FDH
         MOV     SCON,#40H              ; Режим передачи
         CLR     TI
         CLR     RI
         MOV     R3,#00H
         SETB    TR1

START:   MOV     SBUF,R3
LOOP1:   JNB     TI,LOOP1
         CLR     TI
         INC     R3
         CJNE    R3,#00H,START
LOOP:    SJMP    LOOP
         END

Вывод текста на LCD

Программа инициализирует LCD в 4-битном режиме и выводит сообщение на две строки.

Вывод на LCD
;************************************************************************
;* ИМЯ ПРОГРАММЫ : Lcd.ASM
;* ОПИСАНИЕ: Вывод текста на LCD 16x2 в 4-битном режиме
;************************************************************************
;ОСНОВНЫЕ ДИРЕКТИВЫ

$MOD53
$TITLE(LCD.ASM)
$PAGEWIDTH(132)
$DEBUG
$OBJECT
$NOPAGING

;СТЕК
          DSEG     AT     0E0h
Stack_Start:       DS     020h

Start_address      EQU    0000h

;ВЕКТОР СБРОСА
          CSEG     AT     0
          ORG      Start_address
          JMP      Inic

          ORG      Start_address+100h

          MOV      IE,#00
          MOV      SP,#Stack_Start

Inic:     CALL     LCD_inic

;*************************************************
;* ОСНОВНАЯ ПРОГРАММА
;*************************************************

START:    MOV      A,#80h
          CALL     LCD_status
          MOV      A,#'M'
          CALL     LCD_putc
          MOV      A,#'i'
          CALL     LCD_putc
          MOV      A,#'k'
          CALL     LCD_putc
          MOV      A,#'r'
          CALL     LCD_putc
          MOV      A,#'o'
          CALL     LCD_putc
          MOV      A,#'e'
          CALL     LCD_putc
          MOV      A,#'l'
          CALL     LCD_putc
          MOV      A,#'e'
          CALL     LCD_putc
          MOV      A,#'k'
          CALL     LCD_putc
          MOV      A,#'t'
          CALL     LCD_putc
          MOV      A,#'r'
          CALL     LCD_putc
          MOV      A,#'o'
          CALL     LCD_putc
          MOV      A,#'n'
          CALL     LCD_putc
          MOV      A,#'i'
          CALL     LCD_putc
          MOV      A,#'k'
          CALL     LCD_putc
          MOV      A,#'a'
          CALL     LCD_putc

          MOV      A,#0c0h                ; Вторая строка
          CALL     LCD_status
          MOV      A,#'R'
          CALL     LCD_putc
          MOV      A,#'a'
          CALL     LCD_putc
          MOV      A,#'z'
          CALL     LCD_putc
          MOV      A,#'v'
          CALL     LCD_putc
          MOV      A,#'o'
          CALL     LCD_putc
          MOV      A,#'j'
          CALL     LCD_putc
          MOV      A,#'n'
          CALL     LCD_putc
          MOV      A,#'i'
          CALL     LCD_putc
          MOV      A,#' '
          CALL     LCD_putc
          MOV      A,#'s'
          CALL     LCD_putc
          MOV      A,#'i'
          CALL     LCD_putc
          MOV      A,#'s'
          CALL     LCD_putc
          MOV      A,#'t'
          CALL     LCD_putc
          MOV      A,#'e'
          CALL     LCD_putc
          MOV      A,#'m'
          CALL     LCD_putc
          MOV      A,#'i'
          CALL     LCD_putc

          MOV      R0,#20d
          CALL     Delay_10ms
          MOV      DPTR,#LCD_DB
          MOV      A,#6d
          CALL     LCD_inic_status
          MOV      R0,#10d
          CALL     Delay_10ms
          JMP      START

;*********************************************
;* ПОДПРОГРАММА: Delay_10ms
;* ЗАДЕРЖКА R0 * 10 мс
;*********************************************

Delay_10ms:  MOV   R5,00h
             MOV   R6,#100d
             MOV   R7,#100d
             DJNZ  R7,$
             DJNZ  R6,$-4
             DJNZ  R5,$-6
             RET

;**************************************************************************************
;* ПОДПРОГРАММА: LCD_inic
;* ИНИЦИАЛИЗАЦИЯ LCD В 4-БИТНОМ РЕЖИМЕ
;**************************************************************************************

LCD_enable     BIT    P1.3
LCD_read_write BIT    P1.1
LCD_reg_select BIT    P1.2
LCD_port       EQU    P1
Busy           BIT    P1.7

LCD_Start_Line1  EQU   00h
LCD_Start_Line2  EQU   40h

LCD_DB:        DB     00111100b              ; Команда 0
               DB     00101100b              ; Команда 1
               DB     00011000b              ; Команда 2
               DB     00001100b              ; Команда 3
               DB     00000110b              ; Команда 4
               DB     00000010b              ; Команда 5
               DB     00000001b              ; Команда 6
               DB     00001000b              ; Команда 7

LCD_inic:
               MOV    DPTR,#LCD_DB

               MOV    A,#00d                 ; Тройная инициализация
               CALL  LCD_inic_status_8
               MOV   A,#00d
               CALL  LCD_inic_status_8
               MOV   A,#00d
               LCALL LCD_inic_status_8

               MOV   A,#1d                   ; Переключение в 4-битный режим
               CALL  LCD_inic_status_8
               MOV   A,#1d
               CALL  LCD_inic_status

               MOV   A,#3d
               CALL  LCD_inic_status
               MOV   A,#6d
               CALL  LCD_inic_status
               MOV   A,#4d
               CALL  LCD_inic_status

               RET

LCD_inic_status_8:
               PUSH  B

               MOVC  A,@A+DPTR
               CLR   LCD_reg_select
               CLR   LCD_read_write

               MOV   B,LCD_port
               ORL   B,#11110000b
               ORL   A,#00001111b
               ANL   A,B

               MOV   LCD_port,A
               SETB  LCD_enable
               CLR   LCD_enable               

               MOV   B,#255d
               DJNZ  B,$
               DJNZ B,$
               DJNZ B,$

               POP B
               RET

LCD_inic_status:
               MOVC  A,@A+DPTR
               CALL  LCD_status
               RET

;****************************************************************************
;* ПОДПРОГРАММА: LCD_status
;* ОТПРАВКА КОМАНДЫ В 4-БИТНОМ РЕЖИМЕ
;****************************************************************************

LCD_status:    PUSH  B
               MOV   B,#255d
               DJNZ  B,$
               DJNZ  B,$
               DJNZ  B,$
               CLR   LCD_reg_select
               CALL  LCD_port_out

               SWAP  A
               DJNZ  B,$
               DJNZ  B,$
               DJNZ  B,$
               CLR   LCD_reg_select
               CALL  LCD_port_out

               POP   B
               RET

;****************************************************************************
;* ПОДПРОГРАММА: LCD_putc
;* ОТПРАВКА СИМВОЛА
;****************************************************************************

LCD_putc:      PUSH  B
               MOV   B,#255d
               DJNZ  B,$
               SETB  LCD_reg_select
               CALL  LCD_port_out

               SWAP  A
               DJNZ  B,$
               SETB  LCD_reg_select
               CALL  LCD_port_out
               POP   B
               RET

;****************************************************************************
;* ПОДПРОГРАММА: LCD_port_out
;* ВЫВОД ПОЛУБАЙТА И СТРОБИРОВАНИЕ
;****************************************************************************

LCD_port_out:  PUSH  ACC
               PUSH  B
               MOV   B,LCD_port
               ORL   B,#11110000b
               ORL   A,#00001111b
               ANL   A,B

               MOV   LCD_port,A
               SETB  LCD_enable
               CLR   LCD_enable               

               POP   B
               POP   ACC
               RET

               END

Преобразование двоичного числа в десятичные цифры

Подпрограмма преобразует байт в сотни, десятки и единицы.

;************************************************************************
;* ИМЯ ПОДПРОГРАММЫ : BinDec.ASM
;* ОПИСАНИЕ : Преобразование 8-битного значения в десятичные цифры
;************************************************************************

BINDEC:            MOV     B,#10d
                   DIV     AB             ; A / 10
                   MOV     R3,B           ; Единицы
                   MOV     B,#10d
                   DIV     AB
                   MOV     R2,B           ; Десятки
                   MOV     B,#10d
                   DIV     AB
                   MOV     A,B            ; Сотни
                   RET

Эта глава охватила все фундаментальные примитивы управления аппаратным обеспечением для разработки микроконтроллеров, однако эти же базовые подпрограммы являются частыми целями злонамеренной эксплуатации встраиваемых систем. Например, простые программные циклы задержки, реализованные для мигания светодиодом, могут быть использованы для измерения точных временных вариаций между ветвями выполнения, что позволяет злоумышленникам через анализ побочных каналов выявить скрытые пути выполнения секретного кода. Демонстрация сторожевого таймера, хотя и предназначена как механизм восстановления, также демонстрирует функциональность полного сброса — поведение, которое может быть использовано для принудительного восстановления устройства или обхода защиты, если логика таймаута настроена неадекватно. Примеры с таймерами и внешними прерываниями учат точному управлению синхронизацией на уровне циклов — критическому навыку как для проектирования защищенных протоколов связи, так и для полного обратного проектирования проприетарных встраиваемых систем. Интерфейсы UART представляют собой заметные риски, так как незашифрованный трафик позволяет пассивно перехватывать передаваемые данные; без криптографической обертки злоумышленники могут захватывать полные дампы последовательного трафика и восстанавливать логику прошивки. Проверка записи/чтения EEPROM напрямую взаимодействует с энергонезависимой памятью, что является основной целью для злоумышленников, стремящихся получить полный дамп Flash или изменить калибровочные параметры для разблокировки функций. Даже мультиплексированные LED-дисплеи демонстрируют технику коммутации сигналов, которую злоумышленники могут использовать для запутывания физического зондирования при декапсуляции. Как показано, каждый вывод и регистр могут стать вектором атаки для полного извлечения прошивки, если предохранители безопасности не настроены. Бит блокировки часто является единственным барьером, защищающим код, но многие продукты поставляются с отключенной или неправильно настроенной защитой. Это требует от инженеров подхода, рассматривающего извлечение прошивки как реальную бизнес-угрозу, и инвестирования в защиту от вскрытия, экранирование и многоуровневую безопасность. Процедура записи и проверки EEPROM служит шаблоном для безопасного хранения данных, но без шифрования она не предотвращает клонирование. Современные злоумышленники используют лазерную декапсуляцию и микрозондирование для чтения Flash без аутентификации. Хотя такие атаки дороги, они экономически оправданы для ценных устройств. Поэтому все примеры в этой главе следует рассматривать как напоминание о постоянных угрозах. Сам микроконтроллер — это гибкая платформа, но его встроенные механизмы безопасности требуют тщательной настройки. Восстановление пароля через бэкдор может быть использовано для дампа кода. Таким образом, каждая простая программа несет скрытый риск, становясь критическим при проектировании серийных продуктов. Обратное проектирование этих элементарных подпрограмм часто является началом более крупной атаки, поэтому разработчики должны применять подход «безопасность прежде всего» с первых прототипов. Знание методов разблокировки через сбои так же важно, как и знание контрмер. В итоге, эта глава закладывает фундамент для создания устойчивых к взлому систем — при условии, что разработчики усвоят уроки о предохранителях, битах блокировки и защите EEPROM. Овладев этими принципами, инженеры смогут создавать продукты, устойчивые к клонированию, и сохранять конфиденциальность интеллектуальной собственности. Путь от мигающего светодиода до защищенной промышленной системы начинается с освоения этих примитивов и полного осознания всех связанных уязвимостей.

  • Список обратного проектирования МК SST 8051 от Mikatech:
  • Серия SST89Cxx – снятие защиты копирования МК: SST89C54 SST89C58 SST89C583 SST89C5833 SST89C58RC SST89C59 ...

    Серия SST89Exx – взлом защиты копирования МК: SST89E516RD SST89E516RD2 SST89E554 SST89E52RC SST89E52RD SST89E52RD2 SST89E54RC SST89E54RD SST89E54RD2 SST89E554RC SST89E564RD SST89E58RD SST89E58RD2 ...

    Серия SST89Vxx – чтение защиты битов блокировки МК: SST89V516RD SST89V516RD2 SST89V52RD SST89V52RD2 SST89V54RD2 SST89V554RC SST89V564RD SST89V58RD2...

    Серия SST89VFxx – взлом защиты битов блокировки копирования МК: SST39VF1682 SST39VF1681 SST39VF6402B SST39VF6401B SST39VF6402 SST39VF6401 SST39VF3202 SST39VF3201 SST39VF1602 SST39VF1601 ...

Общие вопросы об извлечении прошивок микроконтроллеров


  • Безопасно ли отправлять оплату в MikaTech ?

    Если бы MikaTech была плохой компанией, в интернете можно было бы найти тонны негативных отзывов за 28 лет истории

    Итак, ответ: ДА! Мы хорошие люди.

    Почему выбирают Mikatech, пожалуйста нажмите здесь, чтобы узнать


  • Может ли Mikatech взломать микросхемы, не указанные на сайте?

    У разных производителей разные номера деталей, но внутреннее ядро микросхемы может быть изготовлено по одной технологии. Невозможно перечислить все номера деталей, к которым может применяться наша технология, например MYSON, STK, FEELING, ANALOG, FUJITSU, NOVATEK, LG/HYNDAI.

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

  • Будет ли защищена моя конфиденциальность?

    Mikatech Innovative Limited понимает важность конфиденциальности своих клиентов. В момент обращения в Mikatech ваша личная информация будет защищена нашими управленческими регламентами, разработанными за годы практики. Mikatech использует эту информацию для настройки своих услуг под вас и никогда не раскрывает ее третьим лицам по любой причине.
    По каждому проекту мы удаляем все данные, материалы и коды через 60 дней после передачи файлов, что защищает нас и вашу конфиденциальность.

  • Законно ли пользоваться услугами Mikatech ?

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


  • Я отправил вам письмо, почему нет ответа ?

    • A. Наш почтовый сервер временно вышел из строя, ваше сообщение не было доставлено, даже если отображается сообщение об успешной отправке, свяжитесь с нами снова.
    • B. Наш email распознается вашим почтовым сервером как спам, поэтому наш ответ был отклонен или помещен в спам-папку. Пожалуйста, удалите наш аккаунт из списка спама, проверьте спам-папку или используйте другой email (например, gmail).
    • C. Ваш email распознается нашим сервером как спам и был помещен в спам-папку, пожалуйста, используйте другой email для связи.



    Услуги по взлому МК


    время взлома МК

    Лет

    28 +
    страны взлома МК

    Стран

    110 +
    клиенты атак на МК

    Клиентов

    5000 +
    разблокированные проекты МК

    Проектов

    60000 +