Косвенная адресация

Косвенная адресация очень удобная штука, когда необходимо оперировать с большим количеством регистров, о ней я упоминал еще в первой статье, здесь же покажу, как можно применить данный вид адресации.
Для работы с косвенной адресацией используется регистр специального назначения FSR и физически не реализованный регистр INDF. Принцип работы простой, в регистр FSR записываем адрес какого-либо регистра, пусть это будет регистр с названием temp (то есть адресу этого регистра присвоено название temp с помощью директивы equ), после чего содержимое регистра temp “условно” оказывается в регистре INDF. Теперь все операции, проделанные над регистром INDF, будут выполнены и для регистра temp, на самом же деле обращение к регистру INDF вызовет действие непосредственно с регистром temp, поэтому я и употребил термин “условно”.

Рассмотрим следующую задачу: необходимо получить 10 байт данных от какого-либо устройства по интерфейсу SPI (тут возможен не только SPI, например I2C, UART и т.д.) и разместить их в памяти данных (ОЗУ). В “шапке” программы необходимо присвоить название одному регистру, начиная с которого будут располагаться остальные регистры, в них будет происходить запись принятых байтов, пусть это будет регистр с названием data. Понадобиться еще один регистр (назовем его shet), который будет выступать в качестве счетчика принятых байтов. Код программы представлен ниже:

Первым делом записываем число 10 в регистр shet, чтобы вести отчет принятых байтов, далее записываем адрес первого регистра (регистр data по адресу 0х21, который будет использоваться для хранения принятых данных) в регистр FSR. Вызываем подпрограмму spi для получения одного байта данных, при этом байт записывается в аккумулятор при выходе из подпрограммы. По возвращении из подпрограммы записываем принятый байт в регистр INDF, на самом деле этот байт записывается в регистр data, расположенный по адресу 0х21 в памяти данных. Теперь производим инкремент регистра FSR, тем самым подготавливая следующий регистр памяти данных для записи очередного принятого байта. После инкремента в регистре FSR будет лежать число 0х22, то есть это адрес следующего регистра в памяти данных после регистра data. Далее декрементируем регистр shet, если он не равен нулю, переходим на метку s1, получаем новый байт и записываем в регистр INDF, только теперь этот байт запишется в регистр с адресом 0х22. Тем самым после выполнения кода (когда регистр shet обнулится), все 10 принятых байт запишутся в регистры расположенные последовательно по адресам 0х21 – 0х2A.

Конечно, можно поступить просто и прямолинейно, присвоить названия всем 10-ти регистрам, и написать линейный код: вызов подпрограммы spi, далее запись полученного байта в первый регистр, очередной вызов подпрограммы с записью в следующий регистр, и так 10 раз подряд. В итоге получим код размером в 20 строчек (слов памяти программ). Но это будет неоптимизированный код, занимающий много места в памяти программ, а если нам надо принять 20, 40, 60 байт?

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

При использовании косвенной адресации следует помнить о банках памяти.
Но тут все проще, нежели при непосредственной адресации. Банк указывается одним битом IRP регистра STATUS, если этот бит сброшен, можно обращаться к регистрам расположенным сразу в двух банках, в 0-ом и 1-ом, если бит установлен, обращение идет к регистрам 2-го и 3-го банка.

Оцените статью
Добавить комментарий

  1. Роман

    А не подскажете какую нибудь программу для Pic 12f675 с использованием косвенной адресации,или же где уже имеются написанные программы составленные в MPLAB IDE! А то дали курсовой проект, а данную тему даже не рассматривали

    Ответить
    1. admin автор

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

      Ответить
  2. Sergo15

    подскажите пожалуйста как использовать косвеггую адресацию на этом примере)
    Использовать косвенную адресацию. В регистры h’20’ – h’2 F’ занести константу h’0 F’. [h’2 F’] отобразить в Portb.

    Ответить
    1. admin автор

      Ответить
  3. RMAU

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

    Ответить
  4. Сергей

    Подсажите, как напримере продолжить эту операциюРис.2 Прямая/косвенная адресация в PIC16F877
    Пример 1 Косвенная адресация
    BCF STATUS, IRP ; Установить банк 0,1
    MOVLW 0x20 ; Указать первый регистр в ОЗУ
    MOVWF FSR
    NEXT:
    CLRF INDF ; Очистить регистр
    INCF FSR,F ; Увеличить адрес
    BTFSS FSR,4 ; Завершить?
    GOTO NEXT ; Нет, продолжить очистку
    CONTINUE:
    ; Да

    Ответить
    1. admin автор

      Не понял, что именно вы хотите узнать? в вашем примере выполняется очистка 16 регистров ОЗУ, начиная с адреса 0x20 (32).

      Ответить
  5. Сергей

    Про косвенную, что уходит и приходит )))) в цифрах

    Ответить