Электромеханические системы автоматизации

Характеристика, устройство, конфигурация и назначение микроконтроллеров I8051, PIC16F877, организация их памяти. Основные методы и приемы системного программирования микроконтроллеров и интерфейса на языках семейства ассемблер MCS-51 и PICmicro.

Рубрика Коммуникации, связь, цифровые приборы и радиоэлектроника
Вид методичка
Язык русский
Дата добавления 18.04.2010
Размер файла 3,0 M

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

- Цифры.

Символы интервала определяют один или несколько пробелов в предложении исходного модуля. К этим символам относятся «пробел» и «табуляция».

В качестве букв воспринимаются латинские буквы верхнего и нижнего регистра

Наименования знаков и их обозначение приведено в таблице 1:

Таблица 1 - Допустимые знаки

Наименование

Обозначение

Номер

#

Знак денежной единицы

$

Апостроф

'

круглая скобка левая

(

круглая скобка правая

)

Звездочка

*

Плюс

+

Запятая

,

Минус

-

Точка

.

дробная черта

/

Двоеточие

:

Точка с запятой

;

Меньше

<

Равно

=

больше

>

вопросительный знак

?

коммерческое эт

@

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

Из символов формируются идентификаторы и числа.

Идентификатор - это символическое обозначение объекта программы. В качестве идентификатора может быть использована любая последовательность букв и цифр. При этом в качестве буквы может быть использована любая буква латинского алфавита, а также вопросительный знак (?) и знак «нижнее подчеркивание» (_). Идентификатор может начинаться только с буквы. Это позволяет отличать его от числа. В идентификаторах, язык программирования ASM-51 различает буквы верхнего и нижнего регистров.

Количество символов в идентификаторе ограничено длиной строки (255 символов). Транслятор различает идентификаторы по первым 31 символам.

Примеры идентификаторов:

ADD5, FFFFH, ALFA_1.

В языке программирования ASM-51 имеются три категории идентификаторов: ключевые слова, встроенные имена и определяемые имена.

Ключевое слово является определяющей частью оператора языка ассемблера. Значения ключевых слов языка ассемблера АSМ-51 не могут быть изменены или переопределены в программном модуле каким-либо образом. Ключевому слову не может быть назначено имя-синоним. Ключевые слова могут быть написаны буквами как верхнего, так и нижнего регистров.

В языке АSМ-51 имеются следующие категории ключевых слов:

- Инструкции.

- Директивы.

- Встроенные имена.

- Операции.

Инструкции по форме записи совпадают с мнемоническими обозначениями команд микроконтроллеров семейства MCS-51 и совместно с операндами, составляют команды микроконтроллера.

Директивы совместно с вспомогательными словами определяют действия в программе, которые должны быть выполнены ассемблером в процессе преобразования исходного текста программы в объектный код.

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

Встроенные имена присвоены адресам регистров специальных функций, адресам флагов специальных функций, рабочим регистрам R0-R7 текущего банка регистров, а также аккумулятору A и флагу переноса C.

Определяемые имена объявляются пользователем. В языке программирования ASM-51 имеются следующие категории определяемых идентификаторов:

- Метки.

- Внутренние и внешние переменные адресного типа.

- Внутренние и внешние переменные числового типа.

- Имена сегментов.

- Названия программных модулей.

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

B -двоичное число;

Q или O - восьмеричное число;

[D] - десятичное число (суффикс допускается пропускать);

H - шестнадцатеричное.

Для десятичного числа суффикс может отсутствовать. Количество символов в числе ограничено размером строки, однако значение числа определяется по модулю 2.

Примеры записи чисел:

011101b, 1011100B, 735Q, 456o, 256 , 0fah, 0CBH

Число всегда начинается с цифры. Это необходимо для того, чтобы отличать шестнадцатеричное число от идентификатора: ADCH - идентификатор; 0ADCH - число.

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

- «+» суммирование.

- «-» вычитание.

- «*» умножение.

- «/» деление.

- «mod» вычисление остатка от целочисленного деления

В языке программирования ASМ-51 также определена одноместная операция «-». Для нее требуется один операнд, которому она предшествует. Для изменения порядка выполнения операций можно воспользоваться скобками. Кроме арифметических операций в выражениях допустимо использование логических операций:

- «not» побитовая инверсия операнда.

- «and» логическое «и».

- «or» логическое «или».

- «xor» «исключающее или» (суммирование по модулю два).

- Функций выделения старшего HIGH и младшего LOW байта шестнадцатиразрядного числа.

Пример использования выражений для определения числовой константы:

Рисунок 14 - Использование выражений числовой константы на языке ASM-51

Часто число используется для представления символов. В этом случае для определения числа можно воспользоваться литеральной константой «'». Литеральная константа заключается в апострофы:

MOV SBUF,#`A'

Для записи фраз в памяти программ можно воспользоваться литеральными строками:

ERROR: DB`Ошибка при передаче'

В этом случае каждый символ заменяется отдельным байтом и запоминается в ПЗУ памяти программ.

2.4 Директивы языка ASM-51

2.4.1 Общие сведения

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

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

Ассемблер поддерживает ряд директив, которые позволяют дать символическое определение переменным, резервируют и инициализируют пространство памяти, определяют расположение сгенерированного объектного кода в памяти. За исключением DB и DW директивы не производят объектный код. Директивы используются, чтобы изменить состояние ассемблера, определить объекты и добавить информацию к объектному файлу.

Директивы ассемблера могут быть разделены на ряд категорий:

- Символические определения.

- Резервирование пространства памяти.

- Инициализация данных.

- Управление состоянием ассемблера.

- Выбор сегментов.

- Определение макрокоманд.

2.4.2 Директивы символических определений

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

BIT - Определяет символическое имя, ссылающееся на адрес бита.

CODE - Определяет символическое имя, ссылающееся на адрес кода (для объектного кода).

DATA - Определяет символическое имя, ссылающееся на адрес резидентной памяти данных.

EQU - Назначает символическому имени числовое значение или имя регистра.

IDATA - Определяет символическое имя, ссылающееся на косвенно-адресуемый адрес резидентной памяти данных (для объектного кода).

SEGMENT - Объявляет имя перемещаемого сегмента, его тип и расположение (для объектного кода).

SET - Назначает символическое имя числовому значению или регистру. Имя может быть впоследствии изменено с помощью директивы SET.

XDATA - Определяет символическое имя, ссылающееся на адрес внешней памяти данных (для объектного кода).

2.4.3 Директивы резервирования и инициализации памяти

Эти директивы используются для резервирования и инициализации слов, байтов или битов. В абсолютном сегменте зарезервированное пространство начинается с текущего адреса. В перемещаемом сегменте зарезервированное пространство начинается с текущего смещения. Указатель расположения поддерживается отдельно для каждого сегмента, к нему можно обращаться, используя символ ($):

DB - Заносит в память программ байтовую константу.

DBIT - Резервирует пространство в битовом сегменте (для объектного кода).

DS - Резервирует пространство памяти в текущем сегменте (для объектного кода).

DW - Инициализирует память значением слова.

2.4.4 Директивы компоновки программы

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

EXTRN - Определяет символические имена, которые объявлены в других объектных модулях.

NAME - Определяет имя объектного модуля.

PUBLIC - Определяет символические имена, которые могут использоваться в других объектных модулях.

2.4.5 Директивы управления состоянием ассемблера

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

END - Сообщает о конце транслируемого модуля.

ORG - Изменяет значение ассемблерного счетчика адреса текущего сегмента программы.

USING - Выбирает номер банка регистров общего назначения.

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

Следующие директивы определяют сегменты данных и кода (для объектного кода):

BSEG - Выбирает абсолютный битовый сегмент.

CSEG - Выбирает сегмент программы в машинном коде.

DSEG - Выбирает абсолютный сегмент резидентной памяти данных.

ISEG - Выбирает абсолютный косвенно адресуемый сегмент резидентной памяти данных.

RSEG - Выбирает предварительно определенный перемещаемый сегмент.

XSEG - Выбирает абсолютный сегмент внешней памяти данных.

2.4.7 Директивы макроопределений

Следующие директивы используются для определения макрокоманд (для макроассемблера):

ENDM - Заканчивает макроопределение.

EXITM - Заставляет макрорасширение немедленно завершиться.

IRP - Определяет список аргументов.

IRPC - Определяет аргумент.

LOCAL - Определяет до 16 локальных символов, используемых внутри макрокоманды.

MACRO - Начало макроопределения, определяет имя макрокоманды и параметров, которые могут быть переданы макрокоманде.

REPT - Определяет количество повторений последующих строк.

2.5 Примеры использования директив

Директива equ позволяет назначать имена переменных и констант. Теперь можно назначить переменной адрес в одном месте и пользоваться идентификатором переменной во всей программе. Правда за использование идентификатора именно в качестве переменной отвечает программист. Тем не менее, если в процессе написания программы потребуется изменить адрес переменной, это можно сделать в одном месте программы, а не просматривать всю программу, разбираясь, является ли в данной конкретной команде число 10 константой, адресом ячейки ли количеством повторов в цикле. Все необходимые изменения сделает сам транслятор. Пример назначения переменных приведен на примере описания интерфейса подключения жидкокристаллического (ЖКИ) к микроконтроллеру. Достоинство такого описания заключается в простом переносе программы на другую, сходную систему, имеющую другое подключение индикатора:

DispDat

EQU

P0

; Шина данных ЖКИ на порте P0.

;

RDS

EQU

P1.2

; Сигнал чтение команды ЖКИ подключен к

; линии P1.2.

RW

EQU

P1.1

; Сигнал выбора записи/чтения ЖКИ подключен к

; линии P1.1

E

EQU

P1.0

; Сигнал строб синхронизации ЖКИ подключен к

; линии P1.0

BUSY

EQU

P0.7

; Сигнал занятости ЖКИ подключен к линии P0.7

;

SetDD_Adr

EQU

80h

; Адрес регистра данных/адреса внутри ЖКИ

FuncSet

EQU

20h

; Команда ЖКИ установки функций

_8bit

EQU

10h

; Режим 8 бит интерфейс ЖКИ

_2line

EQU

8

; Режим 2 строчного ЖКИ

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

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

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

Константы, назначаемые директивой equ, могут быть использованы только в одной команде. Достаточно часто требуется работа с таблицей констант, такой как таблица перекодировки, таблицы элементарных функций или синдромы помехоустойчивых кодов. Такие константы используются не на этапе трансляции, а хранятся в памяти программ микроконтроллера. Для занесения констант в память программ микроконтроллера используются директивы db и dw.

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

Рисунок 15 - Пример подключения индикатора к МПС

При установке соответствующего бита разряда выходного буфера в логическую «1», зажигается соответствующий сегмент. Например, для отображения числа 1 необходимо установить биты D1 и D2, соответствующие сегментам «b» и «c». Тогда, для вывода чисел на такой индикатор, необходимо выполнить программный дешифратор из числа в код семисегментного индикатора. Можно выполнить табличный перевод, напоминающий поиск значения функции по таблицам Брадиса. Непосредственно данные для свечения на индикаторе задаются директивой db:

;Подпрограмма перевода числа в код семисегментного индикатора

;Вход: А - ДД число формата 0Х

;Выход: А - семисегментный код числа

;----------------------------------------------------------------------

Decode:

MOV

DPTR, #Table

; Загрузка адреса таблицы.

MOVC

A,@A+DPTR

; Чтение записи со смещением в А.

RET

;

Table:

;

hgfedcba

DB

00111111b

; Символ `0'

DB

00000110b

; Символ `1'

DB

01011011b

; Символ `2'

DB

01001111b

; Символ `3'

DB

01100110b

; Символ `4'

DB

01101101b

; Символ `5'

DB

01111101b

; Символ `6'

DB

00000111b

; Символ `7'

DB

01111111b

; Символ `8'

DB

01101111b

; Символ `9'

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

Decode:

MOV

R7,#EndNadp-NadpSvjazUst

;В R7 заносим число символов.

MOV

DPTR,#NadpSvjazUst

;Подготовить к передаче первый символ

PutNextChar:

CLR

A

MOVC

A,@A+DPTR

;Читаем очередной символ

INC

DPTR

CALL

PutChar

;Отправляем символ на передачу

DJNZ

R7,PutNextChar

;Последний символ?

RET

;Да, возврат из подпрограммы

NadpSvjazUst: DB `Связь установлена',10,13

EndNadp:

Директива dw позволяет заносить в память программ двухбайтные числа. В этой директиве, как и в директиве db числа можно заносить через запятую. Пример листинга фрагмента:

0023 0001

294

dw 1,2,0abh,'a','QW'

0025 0002

0027 00AB

0029 0061

002B 5157

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

Директива org предназначена для записи в счетчик адреса сегмента значения своего операнда. То есть при помощи этой директивы можно поместить команду (или данные) в памяти микроконтроллера по любому адресу. Пример использования директивы ORG для размещения подпрограмм обработки прерываний на векторах прерываний показан ниже:

Reset:

LJMP Main ; Переход на начало основной программы.

; Прерывание переполнения таймера 0. ------------------------------------

ORG 0bh ; Вектор прерывания таймера 0.

LJMP IntT0 ; Переход на обработчик прерывания Т/С0.

; Прерывание последовательного порта. -----------------------------------

ORG 23h ; Вектор прерывания последовательного порта.

LJMP IntSerPort

;Для частоты кварцевого резонатора 12МГц.

IntT0:

Mov TL0, #LOW(-(Fosc/12)*10-2) ;Настройка таймера

Mov TH0, #HIGH(-(Fosc/12)*10-2) ;на 10мкс.

Reti

;Начало основной программы микроконтроллера.

Main: Mov SP,#VershSteka ; Настройка указателя стека.

Call Init ; Выполнить п/п инициализации микроконтроллера.

;------------------------------------------------------------------------

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

Директива using. При использовании прерываний критичным является время, занимаемое программой, обработчиком прерываний. Это время можно значительно сократить, выделив для обработки прерываний отдельный банк регистров. Выделить отдельный банк регистров можно при помощи директивы USING. Номер банка используемых регистров указывается в директиве в качестве операнда. Пример использования директивы USING для подпрограммы обслуживания прерываний от таймера 0 приведен ниже:

_code segment code

CSEG AT 0bh ; Вектор прерывания от Т/С0.

Jmp TntT0

rseg _code

USING 2

IntT0:

Push PSW ; Сохраняем регистры в стек.

Push ACC

Mov PSW,#00010000b ;Включаем банк 2 РОН.

Mov TL0, #LOW(-(Fosc/12)*10-2) ;Настройка таймера

Mov TH0, #HIGH(-(Fosc/12)*10-2) ;на 10мкс.

Pop ACC

Pop PSW

Reti

Директива CALL. В системе команд микроконтроллера MCS-51 используется три команды безусловного перехода. Выбор конкретной команды зависит от расположения ее в памяти программ, однако программист обычно этого не знает. В результате во избежание ошибок приходится использовать самую длинную команду LJMP. Это приводит к более длинным программам и к дополнительной нагрузке на редактор связей. Транслятор сам может подобрать наилучший вариант команды безусловного перехода. Для этого вместо команды микроконтроллера следует использовать директиву call.

2.6 Реализация подпрограмм

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

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

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

Рисунок 16 - Вызов подпрограммы и возврат к выполнению основной программы

Для обращения к подпрограмме и возврата из нее в систему команд микропроцессоров вводят специальные команды. В микроконтроллерах семейства MCS-51 это команды LCALL, ACALL для вызова подпрограммы и команда RET для возврата из подпрограммы. Эти команды не только осуществляют передачу управления на указанный адрес, но и запоминают адрес команды, следующей за командой вызова подпрограммы в стековой памяти. Команда возврата из подпрограммы RET передает управление команде, адрес которой был запомнен командой вызова подпрограммы. Пример использования подпрограммы на языке программирования ASM-51 приведен ниже:

...

Mov G_Per,#56 ; Передать 56 через последовательный порт.

Call PeredatByte

...

Mov G_Per,#49 ; Передать 49 через последовательный порт.

Call PeredatByte

...

;-----------------------------------------------------------------------*

; Подпрограмма передачи байта по последовательному порту

;-----------------------------------------------------------------------*

PeredatByte:

Jb TI,$ ; Ожидание конца передачи предыдущего байта.

Mov SBUF,G_Per ; Передача байта

Ret

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

Очень часто требуется из одной подпрограммы обращаться к другой подпрограмме. Такое обращение к подпрограмме называется вложенным. Количество вложенных подпрограмм называется уровнем вложенности подпрограмм. Максимально допустимый уровень вложенности подпрограмм определяется количеством ячеек стековой памяти. Логически эти ячейки памяти организованы так, чтобы считывание последнего записанного адреса производилось первым, а первого записанного адреса производилось последним (буфер LIFO). Такая логическая организация формируется специальным счетчиком. Этот счетчик, как было указано выше, называется указателем стека SP. Ячейка памяти, в которую в данный момент может быть записан адрес возврата из подпрограммы, называется вершиной стека. Количество ячеек памяти, предназначенных для организации стека, называется глубиной стека. Последняя ячейка памяти, в которую можно производить запись называется дном стека. Логическая организация стека приведена на рис. 17.

В микроконтроллерах семейства MCS-51 при занесении информации в стек содержимое указателя стека увеличивается (стек растет вверх), поэтому стек размещается в самой верхней части памяти данных. Для того, чтобы установить глубину стека 28 байт, необходимо вычесть из адреса максимальной ячейки внутренней памяти микроконтроллера глубину стека и записать полученное значение в указатель стека SP:

DnoSteka EQU 127; Объем внутреннего ОЗУ I8051 - 128 байт.

Mov SP,#DnoSteka-28; Установим глубину стека 28 байт.

Рисунок 17 - Организация стека в памяти данных микропроцессора

Кроме содержимого программного счетчика часто требуется запоминать содержимое внутренних регистров и флагов процессора, локальных переменных подпрограммы. Стек оказался удобным средством и для этой задачи. Сохранение локальных переменных в стеке позволило осуществлять вызов подпрограммы самой из себя (реализовывать рекурсивные алгоритмы). Это привело к введению в систему команд специальных команд работы со стеком. В микроконтроллерах семейства MCS-51 это команды PUSH и POP. Использование этих команд показывается на следующем примере:

Podprogramma:

PUSH PSW ; Сохраняем используемые в подпрограмме

PUSH ACC ; регистры в стеке

PUSH R0

... ; Код самой подпрограммы.

POP R0 ; Извлекаем сохраненные регистры из стека

POP ACC ; в обратном порядке.

POP PSW

RET ; Выход из подпрограммы.

В приведенном выше примере передачи байта через последовательный порт, сам байт передается в подпрограмму через глобальную переменную G_Per. Однако программа будет эффективнее при использовании подпрограммы с параметрами. Мы знаем, что параметр подпрограммы - это локальная переменная. В этом случае могут значительно снизиться требования к памяти данных. Для размещения локальных переменных лучше всего использовать внутренние регистры процессора. На языке ASM51 для передачи параметра размерностью один байт обычно используется аккумулятор.

Если в подпрограмму нужно передать двухбайтовое значение, то в качестве параметра подпрограммы используется пара регистров (обычно регистры R6-старший байт и R7-младший байт). Пример программы, передающей в подпрограмму двухбайтовое число, написанной на языке программирования ASM-51 приведен ниже:

...

;Пример передачи в подпрограмму двухбайтового числа.

Mov R7, #56 ; Передача младшего байта.

Mov R6, #0 ; Передача старшего байта.

Call Podprog ; Вызвать подпрограмму.

...

Если в подпрограмму нужно передать четырехбайтовое значение (это требуется для переменной, соответствующей типу long или float), то используются регистры R4...R7 (регистр R4 - старший байт):

...

;Пример передачи в подпрограмму четырехбайтового числа.

Mov R7, #56 ; Передача младшего байта.

Mov R6, #0

Mov R5, #0

Mov R4, #0 ; Передача старшего байта.

Call Podprog ; Вызвать подпрограмму.

...

Регистры R0 и R1 обычно используются в качестве указателей обрабатываемых переменных, таких как строки или массивы. Если требуется, чтобы подпрограмма обработала значительный объем данных, то эти данные можно передать через параметр - указатель. В качестве указателя при обращении к внешней памяти данных или к памяти программ обычно используется регистр-указатель данных DPTR. Пример передачи в качестве параметра строки, написанный на языке программирования ASM-51 приведен ниже:

...

;Пример передачи в подпрограмму указателя данных.

Mov DPTR, #Stroka ; Передача указателя на строку.

Call Podprog ; Вызвать подпрограмму.

...

Stroka: DB `Наша строка символов.'

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

...

;Пример передачи в подпрограмму указателя данных внутренней памяти.

Mov R0, #Array ; Передача указателя на данные.

Call Obrabotka ; Вызвать подпрограмму.

...

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

Mov A,X ; Передать в подпрограмму значение Х.

Call Sin ; Вызов функции Y=sin(X)

Mov Y,A ; Сохранение функции в переменной Y.

При этом переменные X и Y должны быть заранее определены директивой EQU.

2.7 Реализация многомодульных программ

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

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

- При назначении переменных их количество ограничено программой-транслятором и может быть исчерпано при написании программы.

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

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

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

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

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

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

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

Для того, чтобы транслятор вместо формирования сообщения об ошибке записал в объектный модуль информацию, необходимую для редактора связей, нужно использовать специальные директивы ссылок на внешние переменные или метки. Обычно эти директивы называются PUBLIC (общие) и EXTRN (внешние). Для ссылки на переменную или метку используется директива EXTRN. В этой директиве перечисляются через запятую метки и переменные, точное значение которых редактор связей должен получить из другого модуля и модифицировать все команды, в которых эти метки или переменные используются. Пример использования директивы EXTRN на языке программирования ASM-51:

EXTRN DATA (BufInd, ERR)

EXTRN CODE (Podprog)

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

PUBLIC BufInd, Parametr

PUBLIC Podprogr, ?Podprog?Byte

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

Для объединения нескольких модулей в исполняемую программу имена всех модулей передаются в редактор связей rl51.exe в качестве параметров при запуске этой программы. Пример вызова редактора связей из командной строки DOS для объединения трех модулей:

rl51.exe progr.obj, modul1.obj, modul2.obj

В результате работы редактора связей в этом примере будет создан исполняемый модуль с именем progr. Формат записи информации в этом файле остается прежним - объектный. Это позволяет объединять модули по частям, то есть при желании можно из нескольких мелких модулей получить один более крупный.

Для получения из объектного файла HEX-файл необходимо объектный файл обработать программой oh.exe.

2.8 Использование сегментов в языке программирования ассемблер

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

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

- Программы.

- Стека.

- Переменных.

- Констант.

Пример размещения сегментов в адресном пространстве памяти программ и внутренней памяти данных приведен на рис. 18:

Рисунок 18 - Разбиение памяти программ и данных на сегменты

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

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

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

Директива BSEG позволяет определить абсолютный сегмент во внутренней памяти данных с битовой адресацией по определенному адресу. Эта директива не назначает имени сегменту, то есть объединение сегментов из различных программных модулей невозможно. Для определения конкретного начального адреса сегмента применяется атрибут AT. Если атрибут AT не используется, то начальный адрес сегмента предполагается равным нулю. Использование битовых переменных позволяет значительно экономить внутреннюю память программ микроконтроллера. Пример использования директивы BSEG для объявления битовых переменных:

BSEG AT 8 ; Сегмент начинается с 8 бита.

RejInd: DBIT 1 ; Флаг режима индикации.

RejPriem: DBIT 1 ; Флаг режима приема.

Flag: DBIT 1 ; Флаг общего назначения.

Директива CSEG позволяет определить абсолютный сегмент в памяти программ по определенному адресу. Эта директива не назначает имени сегменту, то есть объединение сегментов из различных программных модулей невозможно. Для определения конкретного начального адреса сегмента применяется атрибут AT. Если атрибут AT не используется, то начальный адрес сегмента предполагается равным нулю. Пример использования директивы CSEG для размещения подпрограммы обслуживания прерывания от таймера 0:

CSEG AT 0bh ; Вектор прерывания от Т/С0.

IntT0:

Mov TL0, #LOW(-(Fosc/12)*10-2) ;Настройка таймера

Mov TH0, #HIGH(-(Fosc/12)*10-2) ;на 10мкс.

Reti

Директива DSEG позволяет определить абсолютный сегмент во внутренней памяти данных по определенному адресу. Предполагается, что к этому сегменту будут обращаться команды с прямой адресацией. Эта директива не назначает имени сегменту, то есть объединение сегментов из различных программных модулей невозможно. Для определения конкретного начального адреса сегмента применяется атрибут AT. Если атрибут AT не используется, то начальный адрес сегмента предполагается равным нулю. Пример использования директивы DSEG для объявления байтовых переменных:

DSEG AT 20h ; Разместить сегмент с адреса, где возможна

; битовая адресация (Для возможности одновремен-

; ной битовой и байтовой адресации).

RejInd: DS 1 ; Переменная, отображающая состояние программ

; обслуживания аппаратуры.

Rejim: DS 1 ; Переменная режима работы.

Massiv: DS 10 ; Десятибайтовый массив.

В приведенном примере предполагается, что он связан с примером, приведенном выше. Т. е. команды, изменяющие битовые переменные RejInd, RejPriem или Flag одновременно будут изменять содержимое переменной Rejim, и наоборот команды, работающие с переменной Rejim, одновременно изменяют содержимое флагов RejInd, RejPriem или Flag. Такое объявление переменных позволяет написать наиболее эффективную программу управления контроллером и подключенными к нему устройствами.

Директива ISEG позволяет определить абсолютный сегмент во внутренней памяти данных по определенному адресу. Эта директива не назначает имени сегменту, то есть объединение сегментов из различных программных модулей невозможно. Для определения конкретного начального адреса сегмента применяется атрибут AT. Если атрибут AT не используется, то начальный адрес сегмента предполагается равным нулю. Пример использования директивы ISEG для объявления байтовых переменных:

ISEG AT 40h ; Расположить сегмент в адресах от 40h.

Buffer: DS 10 ; Переменная Buffer объемом 10 байт.

Stack: DS 245 ; Глубина стека 245 байт.

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

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

Data - размещает сегмент во внутренней памяти данных с прямой адресацией;

Idata - размещает сегмент во внутренней памяти данных с косвенной адресацией;

Bit - размещает сегмент во внутренней памяти данных с битовой адресацией;

Xdata - размещает сегмент во внешней памяти данных;

Code - размещает сегмент в памяти программ;

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

_data segment idata

PUBLIC VershSteka, BufferKlav

; Определение переменных

rseg _data

BufferKlav DS 8 ; Объем буфера клавиатуры 8 байт.

VershSteka: ; Стек начинается здесь.

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

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

Еще один пример использования директив segment и rseg:

_bits segment bit

PUBLIC KnIzm, strVv

; Определение битовых переменных

rseg _bits

KnIzm: DBIT 1 ; Флаг нажатия кнопки.

strVv: DBIT 1 ; Флаг введенной строки.

В этом примере директива segment используется для объявления сегмента битовых переменных.

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

Пример использования перемещаемых сегментов в исходном тексте программы:

_code segment code

CSEG AT 0 ; Начало программы.

Reset:

Jmp Main

; Начало основной программы микроконтроллера-----------------------------

rseg _code

Main:

Movx @DPTR,A

Mov SP,#VershSteka ; Настроить указатель стека на вершину

Call Init ; Выполнить п/п инициализации процессора.

;------------------------------------------------------------------------

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

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

3 Создание программ для микроконтроллеров

3.1 Структурное программирование

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

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

Алгоритм программы-монитора приведен на рис. 19.

Рисунок 19 - Алгоритм программы-монитора

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

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

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

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

Call ReadPort ; Прочитать порт

Call IndOFF ; Прочитать порт

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

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

Алгоритмически такая цепочка операторов изображена на рис. 20.

Рисунок 20 - Алгоритмическое изображение линейной цепочки операторов

Второй структурный оператор называется условный оператор (оператор ветвления). Достаточно часто одна или другая задачи должны исполняться в зависимости от определенного условия, которое зависит от результатов выполнения предыдущей программы или от внешних устройств. Каждая из таких задач называется плечом условного оператора и изображена на рис. 21:

Рисунок 21 - Алгоритмическое изображение условного оператора

Условный оператор может использоваться в неполном виде, когда отсутствует одно из плеч оператора.

Третий структурный оператор - это оператор цикла с проверкой условия после тела цикла. Такой оператор легко реализуется на языке программирования ассемблер при помощи команды условного или безусловного перехода. Отличие от условного оператора заключается в том, что передача управления осуществляется не вперед, а назад. На языках программирования высокого уровня такой оператор входит в состав языка (оператор do..while в языке программирования C++, или оператор repeat..until в языке программирования PASCAL). В языке ассемблер MCS-51 - это команда DJNZ, перед которой пишется тело цикла.

Алгоритмически такой оператор изображен на рис. 22.

Рисунок 22 - Алгоритмическое изображение оператора цикла с проверкой условия после тела цикла

Четвертый структурный оператор - это оператор цикла с проверкой условия до тела цикла. В отличие от предыдущего оператора тело цикла в этом операторе может ни разу не выполниться, если условие цикла сразу же выполнено. Этот оператор, как и условный оператор, невозможно реализовать на одной машинной команде:

Рисунок 23 - Алгоритмическое изображение оператора цикла с проверкой условия до тела цикла

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

E (equal) - Равно;

NE (Not Equal) - Не равно;

GE (Great or Equal) - Больше или равно;

LE (Less or Equal) - Меньше или равно;

GT (Great Than) - Больше;

LT (Less Than) - Меньше.

У некоторых микропроцессоров операции данных условных переходов присутствуют. Для микропроцессоров, у которых нет таких операций (в том числе и I8051), данные условия строятся на анализе результатов регистра PSW после выполнения сравнения чисел.

Рассмотрим пример сравнения двух байтовых величин на микроконтроллере I8051. Т. к. данный контроллер имеет команду сравнения и перехода, если не равно (CJNE), то данный вариант мы рассматривать не будем. Пусть имеется 2 байта, один в аккумуляторе, другой - в регистре R1. Нужно их сравнить и выполнить плечо условия №1, если они равны. Иначе - плечо №2:

Clr C ; Отчистим признак переноса перед сравнением.

Subb A,R1 ; Сравнение вычитанием

Jnz NeRavno ; Переход на плечо №2.

... ; Здесь выполняется плечо №1 равенства.

Jmp Dalee

NeRavno:

... ; Здесь выполняется плечо №2 не равно.

Dalee: ; Продолжение программы.

При выполнении мягких условий (GE и LE) задача усложняется из-за контроля двух признаков. Пусть нам необходимо проверить условие (A)(R1). Если оно соблюдается, то выполняем плечо №1, иначе - №2:

Clr C ; Отчистим признак переноса перед сравнением.

Subb A,R1 ; Сравнение вычитанием.

Jb ACC.7,Menwe ; Переход на плечо №1.по условию меньше (А<0).

Jz Menwe ; Переход на плечо №1 по условию равенства (A=0).

... ; Здесь выполняется плечо №2.

Jmp Dalee

Menwe:

... ; Здесь выполняется плечо №1.

Dalee: ; Продолжение программы.

По такому принципу можно построить конструкции и с помощью команды сложения. Пример контроля признаков результата сравнения в зависимости от разных условий при выполнении вычитания приведен в таблице 2. В процессе построения программы следует помнить, что условные переходы в языке ассемблер для микроконтроллера I8051 могут выполнить только относительный переход по адресному пространству в пределах -128…+127 адресов относительно самой команды. Поэтому желательно располагать плечи условий, которые выполняются по переходу, как можно ближе к участку программы, где выполняется сравнение. Если такой возможности нет и в процессе компиляции программы, компилятор выдал ошибку о невозможности выполнить переход, то приведенные выше конструкции условных операторов нужно дополнить «длинными прыжками» LJMP к плечу оператора.

Таблица 2 - Ветвления и их команды после операции вычитания

Условие

Название условия

Выполнение ветвлений

A=R1

E

JZ

AR1

NE

JNZ

A<R1

LT

JC или JB ACC.7

A>R1

GT

JNC или JNB ACC.7

A?R1

LE

(JC+JZ)

A?R1

GE

(JNC+JZ)

3.2 Создание программы микропроцессорного устройства

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


Подобные документы

  • Семейство 16-разрядных микроконтроллеров Motorola 68HC12, их структура и функционирование. Модуль формирования ШИМ-сигналов. Средства отладки и программирования микроконтроллеров 68НС12. Особенности микроконтроллеров семейства MCS-196 фирмы INTEL.

    курсовая работа [239,6 K], добавлен 04.01.2015

  • Рассмотрение структуры и принципов работы таймеров/счетчиков (общего назначения, сторожевого, типов А, В, С, D, Е) микроконтроллеров и аналого-цифрового преобразователя семейства AVR с целью разработки обучающего компьютерного электронного пособия.

    курсовая работа [1,0 M], добавлен 06.03.2010

  • Использование микроконтроллеров AVR фирмы Atmel в проектируемой аппаратуре. Архитектура и общие характеристики прибора, предназначение арифметики логического устройства и понятие флэш-памяти. Формат пакета данных, алгоритм их передачи и система команд.

    контрольная работа [427,3 K], добавлен 12.11.2010

  • Структурная схема микроконтроллеров семейства MCS-51: отличительные особенности, назначение выводов, блок регистров специальных функций. Карта прямоадресуемых бит. Методы адресации, граф команд пересылки, обмена и загрузки. Ввод и отображение информации.

    курсовая работа [135,5 K], добавлен 22.08.2011

  • Адресное пространство микроконтроллеров MSP430F1xx. Байтовая и словная формы инструкций. Система команд MSP микроконтроллеров. Периферийные устройства микроконтроллеров MSP430F1xx. Аналого-цифровой преобразователь ADC12, его технические характеристики.

    курсовая работа [278,1 K], добавлен 04.05.2014

  • Микроконтроллер (MCU) — микросхема, предназначенная для управления электронными устройствами. Их можно встретить во многих современных приборах, в том числе и бытовых. Рассмотрение архитектуры различных микроконтроллеров, ядра, памяти, питания, периферии.

    реферат [216,5 K], добавлен 24.12.2010

  • Понятие и виды микроконтроллеров. Особенности программирования микропроцессорных систем, построение систем управления химико-технологическим процессом. Изучение архитектуры микроконтроллера ATmega132 фирмы AVR и построение на его основе платформы Arduino.

    курсовая работа [1,9 M], добавлен 13.01.2011

  • Проектирование специализированных радиоэлектронных устройств с применением микропроцессорных комплектов и цифровых микросхем среднего и малого уровней интеграции. Архитектура микроконтроллеров семейства INTEL8051. Программа устройства на Ассемблере.

    курсовая работа [42,3 K], добавлен 29.07.2009

  • Общая характеристика операций, выполняемых по командам базовой системы. Описание и мнемокоды команд, используемых при разработке программы на языке AVR Ассемблера. Основные принципы работы команд с обращением по адресу SRAM и к регистрам ввода–вывода.

    реферат [148,4 K], добавлен 21.08.2010

  • Классификация, структура, архитектура и модульная организация микроконтроллеров. Средства разработки программного обеспечения AVR-контроллеров. Директивы транслятора ассемблера, рабочая частота и циклы. Исследование арифметических и логических команд.

    методичка [3,0 M], добавлен 19.09.2019

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.