В каком банке памяти микроконтроллера pic16f84 находится регистр trisb

Обновлено: 02.07.2024

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

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

Ниже показана типичная структура программы на ассемблере.

;--- Шапка программы --- list p=16f628a __config b'11111100110001' CBLOCK 0x20 variable1 ; первая запись variable2 ; вторая запись variable3 ; третья запись variable4 ; четвёртая запись ENDC Const1 equ .1 Const2 equ .5 TRISB equ 06h (1-й банк) PORTB equ 06h (0-й банк) Status equ 03h Z equ 02h

;--- Тело программы --- org 0h ; можно выполнить 3 команды ; основной программы goto  start org 4h ; подпрограмма обработки ; прерываний start ; продолж. основной программы ; инициализация ; решение задачи end

1. Шапка программы.

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

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

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

Пользовательские регистры контроллера PIC16F628A начинаются по адресу 20h. В нашем примере, поименовав константы, начиная со значения 20h, мы фактически назначили регистру по адресу 20h имя variable1, регистру по адресу 21h имя variable2 и т.д. Допустим, мы используем регистр по адресу 20h в качестве счётчика. Для того, чтобы увеличить значение счётчика нам нужно прибавить 1 к значению, записанному в этом регистре. На ассемблере это можно записать так: incf 20h. Но, у нас константе 20h соответствует имя variable1. То есть, мы можем записать incf variable1 и компилятор сам заменит variable1 на 20h. Согласитесь, вторая запись гораздо более наглядна.

То есть, с помощью директивы CBLOCK можно фактически определить блоки регистров (присвоить имена регистрам, расположенным по определённым адресам), которые будут использоваться в программе как переменные.

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

Допустим в программе мы несколько раз в разных местах оперируем константой, значение которой равно 1 (например загружаем её в аккумулятор командой movlw .1). Если нам понадобится перекомпилировать программу с другим значением этой константы, то надо будет искать все куски кода, где мы её используем и в каждом случае отдельно менять код. Если же мы директивой equ указали, что записи Const1 соответствует константа 1, то теперь мы везде можем писать movlw Const1 и для изменения константы нам нужно всего лишь изменить её значение в шапке программы.

2. Тело программы.

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

При возникновении прерывания счётчик так же всегда устанавливается по какому-то определённому адресу, например для PIC16F628A это будет адрес 0004h. Следовательно, если мы используем в программе прерывания, то перед подпрограммой обработки прерываний нужно написать ORG 04h, чтобы первая инструкция этой подпрограммы располагалась по адресу 0004h. Кроме того, в этом случае, необходимо обеспечить, чтобы основная программа не пересекалась с подпрограммой обработки прерывания.

bcf PORTB, 0 ; устанавливаем начальное состояние ; (уровень, который установится на RB0 ; после переключения направления работы ; на выход, 0 - низкий уровень, 1 - высокий bsf Status, RP0 ; переходим в первый банк (нужный ; нам регистр TRISB находится там), для чего ; устанавливаем в 1 бит RP0 регистра Status bcf TRISB, 0 ; устанавливаем в 0 нулевой бит регистра TRISB ; (устанавливаем направление работы RB0 - на выход) bcf Status, RP0 ; возвращаемся в нулевой банк

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

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

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

Память программ. В PIC16F84A команды имеют 14 разрядов и хранятся во флэш-памяти. Ячейки памяти также имеют 14 разрядов и образуют слово. Объем памяти составляет 1 К (1024) слов.

При сбросе МК сигналом низкого уровня на выводе MCLR (Master Clear) происходит сброс в нуль счетчика команд PC, и после окончания сигнала MCLR дальнейшее выполнение команд программы производится с адреса 000h. Так как программа находится в энергонезависимой памяти, при отключении питания ее стирание не происходит.

В PIC16F84A все регистры распределены по двум банкам, которые имеют нумерацию 0 и 1. В каждый момент времени программе доступен только один регистровый банк. Переключение между банками осуществляется при помощи 5-го бита с именем RP0 из регистра состояния STATUS. При сбросе этого бита в 0 доступен банк 0, при установке бита в 1 – банк 1. Наиболее часто используемые РСФ находятся в банке 0. Некоторые из РСФ присутствуют в обоих банках. Регистры РОН, а их всего 68, продублированы в обоих банках. После сброса МК автоматически выбирается регистровый банк 0.

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

· регистр статуса STATUS содержит флаги АЛУ, состояния контроллера при сбросе и биты выбора банков ПД;

· регистр конфигурации OPTION_REG содержит управляющие биты для конфигурации предварительного делителя (предделителя), внешних прерываний, таймера, а также подтягивающих резисторов (pull-up) на выводах порта В;

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

Порты ввода/вывода. МК PIC16F84A имеет 13 выводов (линий), каждый из которых может быть сконфигурирован (программно настроен) на ввод или вывод данных. На рисунке 1 приведена упрощенная функциональная схема одной линии порта. В каждой линии имеется триггер данных, входящий в регистр данных порта PORT; триггер направления передачи данных, входящий в регистр направления TRIS; выходной буфер OBF; буфер чтения вывода порта IBF. Буферы OBF и IBF имеют выходы с тремя состояниями. Управление состоянием выходов выполняется с помощью сигналов на входах EN. При EN = 1 выходы буферов находятся в активном режиме и передают логические “1” или “0” со входов. При EN = 0 выходы находятся в отключенном Z-состоянии. Управление буфером OBF выполняется от триггера TRIS. Когда в триггере записан “0”, высокий уровень с инверсного выхода триггера поступает на управляющий вывод EN буфера OBF и переводит его выход в активный режим. Информация, записанная в триггере данных PORT (“0” или “1”), поступает на выход линии порта. Когда в триггере TRIS записана “1”, на выводе EN будет “0”, и выход буфера OBF переходит в Z-состояние, т.е. отключается от вывода порта. Логическое состояние на выводе порта в этом случае может быть прочитано с помощью буфера IBF, который открывается командой чтения выводов порта. Буфер IBF открывается кратковременно только на момент чтения выводов порта. В остальное время выход IBF находится в Z-состоянии и не влияет на шину данных МК. Таким образом, для настройки линии порта на вывод в соответствующий разряд регистра TRIS надо записать 0, а для настройки линии на ввод – записать 1.

Выводы распределены между двумя портами МК: пять выводов порта А (RA0-RA4) и восемь выводов порта В (RB0-RB7). Выбор состояния вывода (вход или выход) определяется регистрами TRISA и TRISB. После сброса МК автоматически все линии портов настроены на ввод. Для изменения настройки необходимо в регистры направления загрузить соответствующую информацию. Пример настройки линий порта В: линии RB0-RB3 – на вывод, линии RB4-RB7 – на ввод:

movlw b’11110000’ ; загрузить в регистр W двоичное число 11110000

movwf TRISB ; переслать содержимое W в регистр TRISB

Некоторые выводы портов обладают специальными функциями. Так, будучи настроенными на ввод линии RB0 и RB4-RB7 могут активизировать прерывания. Вывод RA4 порта А может служить входом подключения внешнего генератора для подсчета числа импульсов с помощью TMR0. Особенностью линий порта В является возможность программного подключения к его выводам, настроенным на ввод, внутренних “подтягивающих” резисторов сопротивлением приблизительно 50 кОм. Возможность такого подключения упрощает взаимодействие с клавиатурой и исключает необходимость в использовании внешнего резистора.

Программный счетчик в PIC16C84 имеет ширину 13 бит и способен адресовать 8Кх14бит объема программной памяти. Однако, физически на кристалле имеется только 1Кх14 памяти (адреса 0000h-03FFh). Обращение к адресам выше 3FFh фактически есть адресация в тот же первый килобайт. В памяти программ есть выделенные адреса. Вектор сброса находится по адресу 0000h, вектор прерывания – по адресу 0004h. Обычно по адресу 0004h располагается подпрограмма идентификации и обработки прерываний, а по адресу 0000h – команда перехода на метку START, указывающую начало основной программы.

ПЗУ(EEPROM) PIC16C84 рассчитано на ограниченное число циклов стирания/записи. Чтобы записать в программную память, кристалл должен быть переведен в специальный режим при котором на ножку /MCLR подается напряжение программирования Vprg, а питание Vdd должно находиться в пределах 4.5 В . 5.5В. PIC16C84 непригоден для применений, в которых часто модифицируется программа. Запись в программную память осуществляется побитно, последовательно с использованием только двух ножек.

Организация памяти программ и стека приведена на рис. 8.3.

Программный счетчикШирина программного счетчика - 13 бит. Младший байт программного счетчика (PCL) доступен для чтения и записи и находится в регистре 02h. Старший байт программного счетчика (PCH) не может быть прямым образом прочитан или записан. Старший байт программного счетчика может быть записан через PCLATH регистр, адрес которого 0Ah. В зависимости от того, загружается ли в программный счетчик новое значение во время выполнения команд CALL, GOTO, или в младший байт программного счетчика (PCL) производится запись, - старшие биты программного счетчика загружаются из PCLATH разными способами так, как показано на рис. 8.4. Команды CALL и GOTO оперируют 11-разрядным адресным диапазоном, достаточным для смещения в пределах страницы программной памяти объемом 2К слов. PIC16F8X игнорируют значения бит PCLATH<4:3>, которые используются для обращения к страницам 1, 2 и 3 программной памяти.

Стек и возвраты из подпрограмм. Кристалл PIC16C84 имеет восьмиуровневый аппаратный стек шириной 13 бит. Область стека не принадлежит ни к программной области, ни к области данных, а указатель стека пользователю недоступен. Текущее значение программного счетчика посылается в стек, когда выполняется команда CALL или производится обработка прерывания. При выполнении процедуры возврата из подпрограммы (команды RETLW , RETFIE или RETURN), в программный счетчик выгружается содержимое стека. Регистр PCLATH (0Ah) не изменяется при операциях со стеком. Стек работает как циклический буфер. Следовательно, после того как стек был загружен 8 раз, девятая загрузка перепишет значение первой. Признаков положения стека в контроллере не предусмотрено, поэтому пользователь должен самостоятельно следить за уровнем вложения подпрограмм.

Рис. 8.3. Организация памяти программ и стека.


Рис. 8.4. Организация программного счетчика.

PIC16 - микроконтроллеры, изучение, и всё что с ними связано

Viktor2312 Пт Фев 19 2016, 21:57

PIC16 - микроконтроллеры. Изучение, и всё что с ними связано.

PIC16 - микроконтроллеры, изучение, и всё что с ними связано Pic16f14

Продолжение в следующем посте.
.

Последний раз редактировалось: Viktor2312 (Пн Сен 17 2018, 10:07), всего редактировалось 9 раз(а)

Viktor2312 Пт Фев 19 2016, 21:57

Организация памяти микроконтроллера PIC16F84A.

____ В микроконтроллере PIC16F84 существует два блока памяти - память программ и память данных. Каждый блок имеет собственную шину, таким образом, доступ к блокам может происходить одновременно.
____ Память данных, в свою очередь, разделена на специальные регистры и регистры общего применения (ОЗУ пользователя). Специальные регистры применяются для хранения битов состояния, определяющих работу портов ввода-вывода, таймеров и других периферийных модулей микроконтроллера.
____ Кроме специальных регистров и ОЗУ, пространство памяти данных содержит ячейки EEPROM. Эта область памяти не может быть адресована непосредственно, и доступ к ней получают через специальный регистр косвенной адресации EEADR, в который записывают порядковый номер ячейки. 64 байта EEPROM имеют номера с 00h по 3Fh. Обычно EEPROM используют для хранения констант, значения которых не должны пропадать при отключении питания.
____ Несмотря на то, что EEPROM гарантированно допускает 10,000,000 циклов стирания-записи, изготовитель не рекомендует использовать её ячейки для хранения часто изменяемых значений, поскольку при этом может быстро исчерпаться её ресурс. Для хранения программных переменных следует использовать ОЗУ (регистры общего применения).

____ Микроконтроллер PIC16F84A имеет 13-битный программный счётчик, позволяющий адресовать до 8К х 14 памяти программ. В микроконтроллере PIC16F84A физически адресуются только первые 1024 (0000h - 03FFh) ячеек памяти. Обращение к старшим адресам, лежащими за пределами указанного диапазона физически равносильно обращению к соответствующим адресам внутри диапазона.

____ Старт по сбросу происходит с адреса 0000h, вектор прерывания один и расположен по адресу 0004h. Обычно по адресу 0004h располагают подпрограмму распознавания и обработки прерываний, а по адресу 0000h команду перехода на метку, расположенную сразу за подпрограммой обработки прерывания.

____ В микроконтроллере PIC16F84A память данных разбита на две части - специальные регистры и регистры общего применения (ОЗУ пользователя). Кроме того, память данных разделена на два банка. Что иллюстрирует рисунок ниже:

____ Переключение банков происходит при помощи изменения 5-го бита в регистре STATUS. Если бит установлен в 0, адресуется нулевой банк, если в 1, соответственно, первый. Некоторые специальные регистры адресуются независимо от включённого банка. Например, обращение по адресу 03h при включённом банке 0 или по адресу 83h при включённом банке 1 равнозначно даёт доступ к специальному регистру STATUS. Регистры общего применения представляют собой статическое ОЗУ и могут быть адресованы непосредственно или косвенно, с применением регистра косвенной адресации FSR (04h). Так, например, адреса 0Eh и 8Eh адресуют одну и ту же ячейку ОЗУ.

____ Специальные регистры представляют собой статическое ОЗУ, в котором некоторые биты устанавливаются по умолчанию при сбросе. Ниже представлена таблица с специальными регистрами:


Специальные регистры и их назначение.

____ Регистр STATUS хранит арифметические флаги АЛУ, информацию о сбросе и бит выбора банка памяти данных. Как и любой другой регистр, регистр STATUS может являться регистром назначения для любой операции. Но если над регистром STATUS выполняют операцию, которая может изменить состояние битов Z, DC и C, то запись в эти три бита блокируется. Их состояние изменяется только аппаратно, в зависимости от состояния АЛУ. Более того, биты /TO и /PD также недоступны для записи. Следовательно, результат операции с регистром STATUS в качестве приёмника может оказаться совсем не таким, как ожидалось. Например, команда CLRF STATUS (очистит полностью регистр STATUS) на самом деле очистит только три старших бита и установит в 1 бит Z. Поэтому к регистру STATUS следует применять только команды BCF, BSF, SWAPF и MOVWF, потому что они не изменяют другие биты состояния.
____ Рассмотрим подробно назначение битов регистра STATUS:

bit 7. IRP - бит выбора банка памяти, применяемый при косвенной адресации. Этот бит не применяется в PIC16F84A и должен всегда оставаться сброшенным. Чтобы обеспечить совместимость программы с более новыми микроконтроллерами, этот бит никогда нельзя использовать в программе при использовании микроконтроллера PIC16F84A.
0 = bank 0,1 (00h - FFh)
1 = bank 2,3 (100h - 1FFh)

bit 6 - 5. RP1, RP0 - биты выбора банка памяти, применяемый при прямой адресации.
00 = bank 0 (00h - 7Fh)
01 = bank 1 (80h - FFh)
10 = bank 2 (100h - 17Fh)
11 = bank 3 (180h - 1FFh)
Каждый банк содержит 128 байт. Поскольку в PIC16F84A используется только два банка, 0 и 1, то бит RP1 должен быть всегда сброшен, а для выбора банка используется бит RP0.

bit 4. /TO - флаг срабатывания сторожевого таймера. Устанавливается в 1 при включении питания и командами CLRWDT и SLEEP. Сбрасывается в 0 по завершении выдержки сторожевого таймера.

bit 3. /PD - режим хранения данных. Устанавливается в 1 при включении питания или выполнении команды CLRWDT. Сбрасывается в 0 командой SLEEP.

bit 2. Z - флаг нулевого результата. Устанавливается в 1, если результат арифметической или логической операции равен нулю. Сохраняет своё значение до следующей операции.

bit 1. DC - флаг десятичного переноса. Используется для команд ADDWF, ADDLW, SUBWF и SUBLW. Отслеживает перенос из четвёртого разряда результата.
1 = Произошёл перенос при сложении.
0 = Не произошёл перенос при сложении.
Вычитание в АЛУ выполняется сложением кода первого операнда с дополнительным кодом второго операнда. Значение бита контекстно зависит от того, какая операция выполнялась. Для операции вычитания значение бита инвертировано.

bit 0. C - флаг переноса. Используется для команд ADDWF, ADDLW, SUBWF и SUBLW. Отслеживает перенос из старшего разряда в бит переноса при сложении.
1 = Произошёл перенос при сложении.
0 = Не произошёл перенос при сложении.

____ Вычитание в АЛУ выполняется сложением кода первого операнда с дополнительным кодом второго операнда. Значение бита контекстно зависит от того, какая операция выполнялась. Для операции вычитания значение бита инвертировано. Так, например, выполнив операцию вычитания 00h - 01h получаем FFh и бит С, установленный в 1. Следовательно результат операции отрицательный (бит С здесь выступает как знаковый разряд и число FFh с установленным знаковым разрядом по законам двоичной алгебры является минус единицей). При вычитании 01h - 00h получаем 01h и бит С = 0. Результат положительный. При сложении FFh + 02h получаем 01h и бит С = 1. Произошёл перенос, значит реальный результат 101h.
____ При выполнении команд сдвига RRF и RLF в этот бит загружается соответственно младший или старший бит регистра-источника.
____ Используя флаги /TO и /PD можно определить, чем был вызван сброс.

PIC16 - микроконтроллеры, изучение, и всё что с ними связано Pic16f10

х - состояние битов не изменилось. Сброс по входу /MCLR в обычном режиме не меняет текущие значения битов /TO и /PD.

____ Специальный регистр OPTION_REG представляет собой полностью доступный для записи и чтения регистр, в котором находятся биты, управляющие работой предварительного делителя, источниками внешних прерываний, встроенным таймером TMR0 и подтягивающими резисторами для порта B.

____ Назначение битов регистра OPTION_REG:

bit 7. /RBPU - включение встроенной нагрузки порта B.
1 = Нагрузка отключена.
0 = Нагрузка включена.

bit 6. INTEDG - выбор фронта прерывающего сигнала.
1 = Прерывание по нарастанию сигнала на выводе RB0/INT.
0 = Прерывание по спаду сигнала на выводе RB0/INT.

bit 5. T0CS - выбор источника тактирования для таймера TMR0.
1 = Импульсы с входа RA4/T0CKI.
0 = Внутренняя тактовая частота (CLKOUT).

bit 4. T0SE - выбор фронта сигнала для таймера TMR0, если в качестве источника выбран вход RA4/T0SKI (T0CS = 1).
1 = Инкремент по спаду на выводе RA4/T0SKI.
0 = Инкремент па нарастанию на выводе RA4/T0SKI.

bit 3. PSA - бит, управляющий подключением предварительного делителя.
1 = Предварительный делитель подключён к WDT.
0 = Предварительный делитель подключён к TMR0.

bit 2 - 0. PS2 - PS0 - управление коэффициентом деления предварительного делителя в зависимости от подключения.

PIC16 - микроконтроллеры, изучение, и всё что с ними связано Pic16f12

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

PIC16 - микроконтроллеры, изучение, и всё что с ними связано Pic16f13

____ Назначение битов регистра INTCON:

bit 7. GIE - бит глобального запрета прерываний.
1 = Разрешены все немаскируемые прерывания.
0 = Запрещены все прерывания.

bit 6. EEIE - разрешение прерывания по окончанию записи в EEPROM.
1 = Прерывание по окончанию записи разрешено.
0 = Прерывание по окончанию записи запрещено.

bit 5. T0IE - разрешение прерывания по переполнению таймера TMR0.
1 = Прерывание разрешено.
0 = Прерывание запрещено.

bit 4. INTE - разрешение прерывания по входу RB0/INT.
1 = Прерывание разрешено.
0 = Прерывание запрещено.

bit 3. RBIE - разрешение прерывания по изменению состояния на входах порта B, линии RB7 - RB4.
1 = Прерывание разрешено.
0 = Прерывание запрещено.

bit 2. T0IF - флаг прерывания по переполнению таймера/счётчика TMR0.
1 = TMR0 был переполнен (следует сбросить программно!).
0 = TMR0 не был переполнен.

bit 1. INTF - флаг прерывания по входу RB0/INT.
1 = Произошло прерывание по входу RB0/INT (следует сбросить программно!).
0 = Не происходило прерывание по входу RB0/INT.
Флаг используется для определения источника прерывания.

bit 0. RBIF - флаг прерывания по изменению состояния на входах RB7 - RB4.
1 = На одном из входов RB7 - RB4 произошло изменение уровня (следует сбросить программно!).
0 = Не происходило прерывание по изменению уровня.
Флаг используется для определения источника прерывания.


Продолжение в следующем посте.
.

Последний раз редактировалось: Viktor2312 (Пн Сен 17 2018, 10:42), всего редактировалось 34 раз(а)

Читайте также: