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

Косвенная адресация очень удобная штука, когда необходимо оперировать с большим количеством регистров, о ней я упоминал еще в первой статье, здесь же покажу, как можно применить данный вид адресации.
Для работы с косвенной адресацией используется регистр специального назначения 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-го банка.

У этой записи 8 комментариев

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

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

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

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

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

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

Имя (обязательно)Email (обязательно)Веб-сайт

Добавить комментарий