Перейти к содержанию
С Днём Победы! ×

Разбираем Pic Код


bolt_2.0

Рекомендуемые сообщения

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

Вопрос по следующему коду:

;***********************************************************************************************

; Multi.asm

; Автоколебательный мультивибратор.

; PIC16F84A Кварц 4 мГц.

;===============================================================================================

LIST p=16F84A ; Установка типа микроконтроллера.

__CONFIG 03FF1H ; Бит защиты выключен, WDT выключен,

; стандартный XT - генератор.

;===============================================================================================

; Определение положения регистров специального назначения.

;===============================================================================================

Status equ 03h ; Регистр выбора банка.

TrisB equ 06h ; Регистр выбора направления работы выводов порта В.

PortB equ 06h ; Регистр управления защелками порта В.

;===============================================================================================

; Определение названия и положения регистров общего назначения.

;===============================================================================================

Sec equ 0Ch ; Счетчик времени полупериода.

;===============================================================================================

; Определение места размещения результатов операций.

;===============================================================================================

F equ 1 ; Результат направить в регистр.

;===============================================================================================

org 0 ; Начать выполнение программы с адреса 0 PC.

goto Start ; Переход в ПП Start.

;***********************************************************************************************

; Текст рабочей части программы.

;***********************************************************************************************

; Установка направления работы RB0 - на выход.

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

Start bsf Status,5 ; Перейти в 1-й банк (установить в 1 5-й бит

; регистра Status).

movlw .0 ; Записать константу 0 в аккумулятор (W).

movwf TrisB ; Скопировать 0 из W в регистр TrisB.

bcf Status,5 ; Перейти в 0-й банк (установить в 0 5-й бит

; регистра Status).

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

; Определение времени полупериода (закладка константы в регистр Sec).

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

movlw .32 ; Записать в регистр W константу .32

movwf Sec ; Скопировать .32 из W в регистр Sec.

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

; Формирование на выводе RB0 нулевого уровня.

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

bcf PortB,0 ; Установить на выходе защелки RB0 ноль.

nop ; Калибровочный машинный цикл.

nop ; -------------"--------------

Pause_1 decfsz Sec,F ; Декремент содержимого регистра Sec с помещением резуль-

goto Pause_1 ; тата декремента в этот же регистр.

; Если этот результат не=0, то осуществляется переход

; в ПП Pause_1 ("закольцовка" в этой ПП).

; Если =0, то программа исполняется далее.

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

; Определение времени полупериода (закладка константы в регистр Sec).

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

movlw .30 ; Записать в регистр W константу .30

movwf Sec ; Скопировать .30 из W в регистр Sec.

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

; Формирование на выводе RB0 единичного уровня.

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

bsf PortB,0 ; Установить на выходе защелки RB0 единицу.

nop ; То же самое, что и для нулевого уровня,

nop ; только "закольцовка" происходит в ПП Pause_2.

Pause_2 decfsz Sec,F ; ------------------"-------------------

goto Pause_2 ; ------------------"-------------------

goto Start ; Переход на новый полный цикл программы.

;***********************************************************************************************

end ; Директива конца программы (всегда последняя снизу).

В тексте я выделил красным цветом команды инициализации регистров специального назначения. Только вот насколько я знаю PORTB имеет адрес 06h а TRISB адрес 86h. Как так получается, что разным регистрам назначается ячейка памяти с одним и тем же адресом ?? :blink:

Изменено пользователем bolt_2.0
Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

  • Ответов 88
  • Создана
  • Последний ответ

Топ авторов темы

Топ авторов темы

Изображения в теме

Очепятка :rolleyes:

И вообще если пользуетесь MPLAB, то применяйте директиву INCLUDE, подключая дополнительно нужный файл. Например, вставив после строчки LIST, следующей

#include P16F84A.inc

Регистры назначенные вами можно определить списком

CBLOCK 0Ch

;здесь

;регистры

ENDC

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

Для интереса загляните в папку

c:\Program Files\Microchip\MPASM Suite\

и откройте P16F84A.inc всё будет понятно.

Изменено пользователем wws63

Опыт - это то, что получаешь, не получив того, что хотел

Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

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

Не цитируите полностью предыдущее сообщение!!!

Ссылка на комментарий
Поделиться на другие сайты

Особенности хранения литиевых аккумуляторов и батареек

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

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

.... Как так получается, что разным регистрам назначается ячейка памяти с одним и тем же адресом ?? :blink:

Получается так.

Разрядность команды у этого семейства МК - 14. Этого не хватает для полной адресации ОЗУ и спецрегистров в частности, как части ОЗУ. Всего остается для прямой адресации 7 разрядов. В этой ситуации введено разделение всего поля адресов ОЗУ на банки. Их может быть от 2-х до 4-х.

Переключение банков осуществляется через два разряда регистра статуса. У 84-го контроллера два банка и они переключаются одним разрядом RP0 спецрегистра STATUS.

Таким образом, старший разряд адреса регистра оказывается не в поле команды, а этом разряде статуса.

Когда вы пишите адреса 0x86 или 0x06, то на самом деле в результирующем коде генерируется одно и тоже.

Отсюда следует необходимость следующей записи:

bsf STATUS, RP0 - переход в первый банк

movlw b'00011100'

movwf TRISB

bcf STATUS, RP0 - возврат в нулевой банк

clrf PORTB

Изменено пользователем my504

戦う前に相手のベルトの色に注目

Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

А почему компилятор не ругается, что два регистра специального назначения прописанны под одним адрессом? Такого ведь в принципе по здравому смыслу быть не может...

И вообще, зачем указывать регистрам спец назначения адреса, если они являются постоянными (константами) ??? :blink:

Таким образом, старший разряд адреса регистра оказывается не в поле команды, а этом разряде статуса.

Когда вы пишите адреса 0x86 или 0x06, то на самом деле в результирующем коде генерируется одно и тоже.

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

Изменено пользователем bolt_2.0
Ссылка на комментарий
Поделиться на другие сайты

1. Давайте придерживаться принятой терминологии. Иначе это будет разговор глухого со слепым. (это про "маршрутизаторы"... :D ). Если Вам не известно значение слов, то их лучше не употреблять....

2. Компилятор не знает ничего о Ваших намерениях. Вы написали мета команду присвоения в тексте именам регистра TRISB значения 0х86.

Почему компилятор должен видеть в этом ошибку?

3. Не нужно запутывать. Мыслите проще. Нужно адресовать поле памяти от 0x00 до 0xFF. Как это сделать с помощью 7 битного адресного поля в коде операции?

Ответ. Иметь отдельный аппаратный бит, который устанавливается ДО исполнения этой команды и является восьмым разрядом адреса операнда (регистра).

Это и есть разбиение на банки.

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

Но компилятор все таки выдаст ПРЕДУПРЕЖДЕНИЕ 302, если в старшем бите операнда в ассемблере будет обнаружена единица. Это помогает забывчивым программистам. Но это не ошибка.

Изменено пользователем my504

戦う前に相手のベルトの色に注目

Ссылка на комментарий
Поделиться на другие сайты

Нет, я не то имел в виду - TrisB стандартно имеет адрес 86h, а если ему задать адрес 06h то получается, что МК будет общаться с ним как с PortB, и выходит что мы просто изменили имена регистров специального назначения. Но так как имена регистров специального назначения менять нельзя по идее компиллятор должен выругаться на всё это дело...

Ссылка на комментарий
Поделиться на другие сайты

Вы вообще не понимаете алгоритма работы компилятора.

Давайте разберем.

Для начала примем, что Вы корректно написали проект и к нему присоединен хедер-файл с именем выбранного контролера и расширением .inc

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

При обращении к ТРИЗе и к ПОРТу их младшие 7 разрядов адреса совпадают. Если Вы посмотрите на скопилированный код, то обнаружите, что, например, команда

movwf TRISB

movwf PORTB

АБСОЛЮТНО ИДЕНТИЧНЫ. И дизассемблер МПЛАБа вообще покажет Вам только вариант с ПОРТом.

Разные записи важны ДЛЯ ЧИТАБЕЛЬНОСТИ КОДА, а не для копилятора. Иначе Вы просто запутаетесь.

Но перед обращением именно к ТРИЗе потребуется выставить единицу в RP0 регистра СТАТУСа. Иначе будет обращение к ПОРТу. Несмотря на заптсь в исходном тексте.

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

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

Это надуманая проблема, поскольку при ОЗУ объемом более, чем 256 ячеек все равно приходится прибегать к разбиению на страницы, даже и при 8 разрядах адреса операнда в команде.

Кроме того есть не только абсолютная адресация. При обращении к регистрам памяти через косвенную адресацию (регистры FSR-INDF) адрес в FSR вписывается ПОЛНОСТЬЮ. Т.е. восьмиразрядный.

Изменено пользователем my504

戦う前に相手のベルトの色に注目

Ссылка на комментарий
Поделиться на другие сайты

При обращении к ТРИЗе и к ПОРТу их младшие 7 разрядов адреса совпадают. Если Вы посмотрите на скопилированный код, то обнаружите, что, например, команда

movwf TRISB

movwf PORTB

АБСОЛЮТНО ИДЕНТИЧНЫ. И дизассемблер МПЛАБа вообще покажет Вам только вариант с ПОРТом.

Но ведь эти регистры выполняют разные функции:

PORTB - Двунаправленный вывод порта В

TRISB - Выбор направления работы выводов порта В

Как разные команды могуд компиллироваться в одинаковую !?

Изменено пользователем bolt_2.0
Ссылка на комментарий
Поделиться на другие сайты

Как поступает компилятор, когда доходит до имени регистра?

Он начинает искать в проекте (во всех включенных в него файлах) описание этого имени. Т.е. ЧИСЛО. Восьмиразрядное. Которое он подставит в код вместо этого имени. Так вот восьмой разряд при подстановке будет выброшен.

Если Вы попытаетесь присвоить одному имени два разных значения, то получите сообщение об ошибке, а хекса не получите.

Если присвоить разным именам одинаковые значения, то это нормально и никакой ошибки тут нет. Например для локальных переменных в АСМе присваивать одинаковые указатели адреса абсолютно нормально, поскольку они используют одни ячейки но в разное время. Экономится память...

Отвечаю на последнее сообщение.

Вы невнимательно читаете ответы.

Настоящий адрес будет образован с учетом бита RP0/

Компилятор НЕ ИМЕЕТ никакой информации об именах регистров. Вся эта информация только в проекте.

Когда программа будет ИСПОЛНЯТЬСЯ, а не компилироваться, тогда и будет сформирован реальный адрес по состоянию бита RP0 в этот момент.

Изменено пользователем my504

戦う前に相手のベルトの色に注目

Ссылка на комментарий
Поделиться на другие сайты

Спасибо, кажется начинает доходить :)

Идём далее:

;===============================================================================================

; Определение места размещения результатов операций.

;===============================================================================================

F equ 1 ; Результат направить в регистр.

Регмстру F присваивается значение 1, но в шапке программы про регистр F небыло нислова. Как МК узнает, в какой ячейки памяти хранить это значение?

Ссылка на комментарий
Поделиться на другие сайты

Эта строка не является командой и она не транслируется.

Это псевдокоманда ассемблера. Она есть инструкция самому компилятору о замене ПРИ ТРАНСЛЯЦИИ символа F в тексте программы на значение 1.

И только.

Изменено пользователем my504

戦う前に相手のベルトの色に注目

Ссылка на комментарий
Поделиться на другие сайты

org 0 ; Начать выполнение программы с адреса 0 PC

Теперь вопрос о PC. Это строка указывает выполнять программу со строки "LIST p=16F84A " т.к. она и является нулевой в счетчике PC или же всётаки с нижеидущей строки "goto Start" как с первой команды программы?

Ссылка на комментарий
Поделиться на другие сайты

Эта строка говорит о том, что после неё следующая команда будет по адресу 0х00.

Учитывая, что товарисч с трудом въезжает в тему, чуть уточню Алекса.

Эта строка говорит о том, что после неё следующая команда будет размещена в памяти по адресу 0х00.

戦う前に相手のベルトの色に注目

Ссылка на комментарий
Поделиться на другие сайты

movlw .0 ; Записать константу 0 в аккумулятор (W).

movwf TrisB ; Скопировать 0 из W в регистр TrisB.

Зачем ставить точку перед нулём?

Изменено пользователем dimas5552
Ссылка на комментарий
Поделиться на другие сайты

А если эту команду посреди программы написать то тогда получается все вышеидущие команды будут просто выкинуты, верно?

Странные вопросы, как у ребенка. А если сделать глупо, что будет?

Компилятор выдаст ошибку.

Про точку перед нулем.

Это признак десятичного формата числа.

0х00 или 00h - шестнадцатиричный формат

.0 или d0 - десятичный формат

b'00000000' - бинарный (двоичный) формат

Изменено пользователем my504

戦う前に相手のベルトの色に注目

Ссылка на комментарий
Поделиться на другие сайты

А если эту команду посреди программы написать то тогда получается все вышеидущие команды будут просто выкинуты, верно?
Перед вышеидущими командами Вы так-же должны указать адрес в памяти с которого они должны начатся. Иначе компиль выдаст ошибку.
Зачем ставить точку перед нулём?
Точка обозначает что число после неё представляется в десятичной системе.

PS:Вы почитали доку которую я Вам прикреплял ??? Там про всё это подробно описано !!!

Ссылка на комментарий
Поделиться на другие сайты

Pause_1 decfsz Sec,F ; Декремент содержимого регистра Sec с помещением резуль-

goto Pause_1 ; тата декремента в этот же регистр.

; Если этот результат не=0, то осуществляется переход

; в ПП Pause_1 ("закольцовка" в этой ПП).

; Если =0, то программа исполняется далее.

1. Команда DECF вычитает 1 из указанного регистра и обычно записывается так: decfsz. Что если записать её так: decffl, ведь f - признак регистра, l - признак константы (l=1) и тогда получется, что из регистра f мы вычитаем один с записью в тот же регистр f. Так можно зделать?:

decffl Sec, 1

2. Непонятно, почему если переменная Sec больше нуля, то выполняется нижеидушая строка, а если =0, то ниже через одну? У команды decf такое свойство?

ПыСы: В прикреплённой доке ни слова про decf...

Изменено пользователем dimas5552
Ссылка на комментарий
Поделиться на другие сайты

Про decf.. Вы найдёте в ДАТАШИТЕ!!! Там есть описания всех команд поддерживающих данным МК.

Не ленитесь читать.

Что если записать её так: decffl
Откуда Вы взяли такое "символосочетание" (decffl) ? :blink: Что за отсебятина ?
Ссылка на комментарий
Поделиться на другие сайты

Было бы неплохо, если бы Вы вначале открыли ЛЮБОЙ даташит на 12 или 16 ПИК и посмотрели систему команд.

В данном случае имеет место быть гадание на кофейной гуще.

decfsz - decrement f skip if zero - декремент регистра и пропуск следующей команды, если после декремента результат нулевой

decf - decrement f - декремент регистра

Все методы адресации применимы для обеих команд.

В первом случае никакие флаги статуса не устанавливаются.

Во втором устанавливается флаг Z при нулевом результате.

ЭТО РАЗНЫЕ КОМАНДЫ.

Изменено пользователем my504

戦う前に相手のベルトの色に注目

Ссылка на комментарий
Поделиться на другие сайты

Было бы неплохо, если бы Вы вначале открыли ЛЮБОЙ даташит на 12 или 16 ПИК и посмотрели систему команд.

А не могли бы Вы скинуть датащит, из которого Вы написали эти комментарии...

Ссылка на комментарий
Поделиться на другие сайты

Даташит на 676-ой/630-ый:

http://ww1.microchip...eDoc/40039F.pdf

Референс мануал (раздел Система команд):

http://ww1.microchip...eDoc/31029a.pdf

Тоже самое, но перевод на русский:

http://www.microchip...us/PIC16_29.pdf

PS Комментарии я писал из головы...

Изменено пользователем my504

戦う前に相手のベルトの色に注目

Ссылка на комментарий
Поделиться на другие сайты

Спасибо за ссылки :) последняя наиболее интересная ибо на русском языке :rolleyes:

Хотелось бы теперь узнать на простом языке в чем разница между регистрами специального назначения PORTB и TRISB?

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу

×
×
  • Создать...