Авторизация


...

Кто на сайте?

Сейчас 116 гостей и ни одного зарегистрированного пользователя на сайте

Статистика

-Посетители : 23007
-Материалы : 209

Пользователь сайта продает...

  Универсальный цифровой спидометр

Пользователь сайта покупает...

Запись в память программ PIC18XXXX.

Автор: Николай Викторов Просмотров: 2295

 

 

  • TBLWT*+ - происходит запись в промежуточный регистр  , указанного по адресу регистра  (TBLPTRL, трех последних бит),после чтения таблицы адрес увеличивается на 1 (инкремент).
  •  TBLWT*- - происходит запись в промежуточный регистр  , указанного по адресу регистра  (TBLPTRL, трех последних бит), после чтения таблицы адрес уменьшается на 1 (декремент).

  • TBLWT+* - происходит запись в промежуточный регистр  , указанного по адресу регистра  (TBLPTRL, трех последних бит), адрес увеличивается на 1 (преинкремент) перед выполнением команды.

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

    В операции стирания и записи необходимо задействовать два регистра специального назначения:

    • EECON1 - регистр управления для доступа к памяти.
    • EECON2 - не физический регистр.

    Рекомендованная последовательность действий для записи блока Flash памяти программ:

    1.  Прочитать 64 байта блока в память данных.
    2. Обновить необходимые регистры с информацией из памяти программ.
    3.  Загрузить в указатель адрес стираемого блока Flash памяти программ.
    4. Выполнить процедуру стирания.
    5. Загрузить в указатель адрес первого байта.
    6. Записать первые 8 байт с автоинкрементом указателя в промежуточные регистры.
    7. Установить  бит EEPGD для  выбора Flash памяти  программ;  установить  бит WREN для      разрешения записи.
    8. Выключить прерывания.
    9. Записать 55h в регистр EECON2.
    10. Записать AAh в регистр EECON2.
    11. Установить бит WR для инициализации цикла записи блока.
    12. CPU остановит выполнение программы до завершения цикла записи (ориентировочно 2мс).
    13. Выполнить команду NOP.
    14. Разрешить прерывания.
    15. Повторить шаги 6-14 семь раз для записи 64 байт.
    16. Выполнить контрольное чтение.

     

    Из практики  можно сказать: " То что рекомендовано разработчиком лучше соблюдать".  Так или иначе, рекомендации возникают не на пустом месте...  По этому,  мы не будем отступать от "правил"? , но есть уточнения ...

    Очень многие допускают ошибку, предполагая что раз написано 64 байта значит ни больше не меньше записывать нельзя. На самом деле это не так. Записывать можно разное количество блоков по 8 байт (хоть один). А вот процедура стирания действительно блоками по 64 байта.  Опять же не стоит путать табличную процедуру стирания  с процедурой стирания памяти программ. В табличной процедуре стираются только по 8 байт. Единственное "неудобство"  при табличной записи, необходимо следить за расположением таблицы, которая должна начинаться по адресу кратным  "8", т.е. 0,8,16,32 и т.д. до 248. 

     В примере, после записи необходимых данных,  выполним ПП проверки   записанных данных в память программ.

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

    Очень важно не "наехать" и не стереть программный код (саму программу). На стадии разработки и отладки MBLAB выдаст вам ошибку, а вот в процессе эксплуатации" программы такое возможно. Для исключения такой ситуации желательно работать с метками,  особенно для новичков,  метки (названия) таблиц , необходимо располагать в конце программного кода, с учетом сказанного выше (кратность 0,8...) тем самым исключается возможность "наезда". Конечно,  это относится к изменению таблиц с данными и если есть необходимость в изменении программного кода, то здесь сам программист должен предусмотреть все возможные ситуации.

    Приступим  к реализации :

    В качестве примера рассмотрим ситуацию, когда необходимо переписать 15 байт в таблице данных "TEST". Естественно можно применить другое название таблицы и другое количество данных.

    • Первое действие чтение таблицы.(к примеру 64 байта.) (рассматривали в первой части статьи)
    • Для упрощения примера сбросим 15 байт начиная с адреса  0107h (14) и 013Сh  (1 байт).

     

    ;-------------------------------------
    ; ПП предварительной записи в ОЗУ необходимых
    ; данных, с последующей записью в таблицу
    ; в примере изменяются значения 15 байтов.
    ;-------------------------------------
     ZAP_data  lfsr        FSR0,0x0107 ; Адрес первого регистра для изменения.
               movlw               .14 ; Всего 14 байт
               movwf              Temp ;
               clrf              INDF0 ; Очистить регистр
               movf           POSTINC0 ; Увеличиваем адрес FSR0L на 1
               decfsz             Temp ; Все очищены?
               bra                $-.6 ; нет,следующий
               lfsr        FSR0,0x013C ; Адрес  регистра для изменения.
               clrf              INDF0 ; Очистить регистр
               return                  ; Да, возврат из ПП
    

    В результате в ОЗУ у нас будут  вот такие данные:

     

    alt

     

    Т.е. мы изменили значения 15 регистров (сбросили в "0") и теперь  перезапишем в таблицу "TEST" блоками по 8 байт. Сначала "короткая" запись в промежуточные регистры (8 байт)..

    ;-----------------------------------
    ; Короткая запись  8 байт
    ;-----------------------------------
    Counter_8  movlw                 8 ; Задание количества
               movwf           Counter ; байтов в одном блоке.
               nop
               movf         POSTINC0,0 ; =Копируем в W значение регистра.    
               movwf            TABLAT ;  в регистр TABLAT=
               tblwt*+                 ; Запись в защелку
               decfsz          Counter ; Все байты блока записаны?
               bra                $-.8 ; нет,следующий.

     

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

     

    ;-----------------------------------
    ; Длинная запись
    ;-----------------------------------
               bsf        EECON1,EEPGD ; Работа с Flash-памятью программ.
               bcf         EECON1,CFGS ; Обращение к Flash памяти программ
               bsf         EECON1,WREN ; Разрешение записи.
               bcf          INTCON,GIE ; Запрет прерывания
               movlw              055h ; =
               movwf            EECON2 ; Обязательная
               movlw              0AAh ; процедура.
               movwf            EECON2 ; =
               bsf           EECON1,WR ; Инициализация цикла записи.
               nop                     ; 
               bsf          INTCON,GIE ; Разрешение прерывания.
               decfsz       Count_Blok ; Кол-во блоков по 8 байт
               call          Counter_8 ;  
               bcf         EECON1,WREN ; Запрет записи.
               return                  ; Возврат из прерывания

     

    Для записи более одного блока (8 байт) повторяем процедуру записи столько раз, сколько необходимо записать блоков. В данном примере 8 блоков или 64 байта. После завершения записи проверяем значение соответствующего регистра памяти программ со значением в ОЗУ, тем самым проверяем на ошибку.  Если хоть один записанный в памяти программ  байт не совпадет с содержимым соответствующих регистров в ОЗУ,  установится  флаг ошибки (Flag,0).

     

               list          p=18F252 ; Используется микроконтроллер PIC18F252.
                #include   p18F252.inc ; Подключение INC-файла PIC18F252.
    ;***************************************************************************
    ; Конфигурирование.
    ;***************************************************************************
                CONFIG      OSC=XT     ; кварц.резонатор
                CONFIG      BOR=OFF    ; Сброс по снижению питания выключен
                CONFIG      WDT=OFF    ; WDT выключен.
                CONFIG      LVP=OFF    ; Режим низковольтного програм. выкл.
    ;-----------------------------------
    ; Регистры общ. назначения
    ;-----------------------------------
                cblock             00h ;
                Flag                   ; Флаг ошибки
                R_Bute_L               ; младший байт кол-ва данных таблицы.  
                R_Bute_H               ; старший байт кол-ва данных таблицы.
                ProvEE_L               ; младший байт
                ProvEE_H               ; младший байт
                Temp                   ;
                Counter                ; количество байт (всегда 8)
                Count_Blok             ; количество блоков по 8 байт
                endc                   ;
                org                  0 ;
                goto             START ;
    ;-----------------------------------
    
    START       call            W_DATA ; Вызов ПП
                clrf              Flag ; Сброс флага ошибки
                goto             START ; зацикливаем.
       
    ;-----------------------------------
    ; ПП записи в память программ.           
    ;-----------------------------------
    W_DATA      movlw               .8 ;
                movwf       Count_Blok ; количество байт (всегда 8)
                call            Ukaz_1 ; TBLPTR на начало таблицы
                movlw               .8 ; количество блоков по 8 байт
                MULWF       Count_Blok ; высчитаваем общее количество байт
                movff   PRODH,R_Bute_H ; Кол-во байт (старший, для коп. в ОЗУ
                movff   PRODL,R_Bute_L ; Кол-во байт (младший),для коп. в ОЗУ
                movff   PRODH,ProvEE_H ; Кол-во байт (старший) для проверки записи
                movff   PRODL,ProvEE_L ; Кол-во байт (младший) для проверки записи
                incf          R_Bute_H ; Коррекция.
                incf          ProvEE_H ; Коррекция.
                call            Ukaz_1 ; TBLPTR на начало таблицы
                call            R_DATA ; Вызов ПП чтения.
                call          ZAP_data ; Тестовая - для демонстрации (удалить)
                call            Ukaz_1 ; TBLPTR на начало таблицы
                movlw               .8 ; =Коррекция
                subwf        TBLPTRL,F ; =
                movlw                0 ; =
                subwfb       TBLPTRH,F ; =
                call         Counter_8 ; Запись новых данных
                call            Ukaz_1 ; TBLPTR на начало таблицы
                call           PROV_EE ; Проверка записи
                return
    
    ;-----------------------------------
    ; проверка записи
    ;-----------------------------------
    PROV_EE    TBLRD*+                 ; Чтение байта +1 адрес
               movf         POSTINC0,0 ;
               CPFSEQ           TABLAT ;
               bsf              Flag,0 ; Флаг ошибки.
               decfsz         ProvEE_L ; Все прочитаны?
               bra             PROV_EE ; нет,следующий
               decfsz         ProvEE_H ; Все прочитаны?
               bra             PROV_EE ; нет,следующий   
               return                  ; Да, возврат из ПП  
    
    ;-----------------------------------
    ; Короткая запись  8 байт
    ;-----------------------------------
    Counter_8  movlw                 8 ; Задание количества
               movwf           Counter ; байтов в одном блоке.
               nop
               movf         POSTINC0,0 ; =Копируем в W значение регистра.    
               movwf            TABLAT ;  в регистр TABLAT=
               tblwt*+                 ; Запись в защелку
               decfsz          Counter ; Все байты блока записаны?
               bra                $-.8 ; нет,следующий.
    ;-----------------------------------
    ; Длинная запись
    ;-----------------------------------
               bsf        EECON1,EEPGD ; Работа с Flash-памятью программ.
               bsf         EECON1,WREN ; Разрешение записи.
               bcf          INTCON,GIE ; Запрет прерывания
               movlw              055h ; =
               movwf            EECON2 ; Обязательная
               movlw              0AAh ; процедура.
               movwf            EECON2 ; =
               bsf           EECON1,WR ; Инициализация цикла записи.
               nop                     ;
               bsf          INTCON,GIE ; Разрешение прерывания.
               decfsz       Count_Blok ; Кол-во блоков по 8 байт
               call          Counter_8 ;  
               bcf         EECON1,WREN ; Запрет записи.
               return                  ; Возврат из прерывания                      
    ;-------------------------------------
    ; Указаталь TBLPTR на начало таблицы
    ; FSR0,0x0100 ; Начальный адрес В ОЗУ
    ;-------------------------------------
    Ukaz_1      clrf           TBLPTRU ; Cбрасываем верхний байт
                movlw       high (TEST); =Задание адреса "TEST"
                movwf          TBLPTRH ;  старшего байта=
                movlw        low (TEST); =Задание адреса "TEST"
                movwf          TBLPTRL ;  младшего байта=
                lfsr       FSR0,0x0100 ; Начальный адрес В ОЗУ
                return
    ;-------------------------------------
    ; ПП чтения данных из памяти программ
    ;-------------------------------------
    R_DATA     TBLRD*+                 ; Чтение байта +1 адрес
               movff      TABLAT,INDF0 ; Результат в ОЗУ
               movf           POSTINC0 ; Увеличиваем адрес FSR0L на 1
               decfsz         R_Bute_L ; Все прочитаны?
               bra              R_DATA ; нет,следующий
               decfsz         R_Bute_H ; Все прочитаны?
               bra              R_DATA ; нет,следующий   
               return                  ; Да, возврат из ПП
    ;-------------------------------------
    ; ПП предварительной записи в ОЗУ необходимых
    ; данных, 15 байт. ПРИМЕР !!!
    ;-------------------------------------
     ZAP_data  lfsr        FSR0,0x0107 ; Адрес первого регистра для изменения.
               movlw               .14 ; Всего 14 байт
               movwf              Temp ;
               clrf              INDF0 ; Очистить регистр
               movf           POSTINC0 ; Увеличиваем адрес FSR0L на 1
               decfsz             Temp ; Все очищены?
               bra                $-.6 ; нет,следующий
               lfsr        FSR0,0x013C ; Адрес  регистра для изменения.
               clrf              INDF0 ; Очистить регистр
               return                  ; Да, возврат из ПП
    ;--------------------------------------------------------
    ;ТАБЛИЦА ДАННЫХ 64 БАЙТА (ПРИМЕР)
    ;--------------------------------------------------------
              org                0100h ; размещение таблицы начиная с 0100h
    
    TEST
        db     0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,  
        db     0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x06, 0x0F, 0x10,  
        db     0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,  
        db     0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,  
        db     0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,  
        db     0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x06, 0x0F, 0x10,  
        db     0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,  
        db     0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
    
    end

     

     

    Смотреть видеоурок по теме.....

     

    Случайные статьи....

    Prev Next

    Измеритель LC на PIC18F2550 с USB.

    04-02-2012 Super User

    Измеритель LC на PIC18F2550 с USB.

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

    ПП чтения и записи двух десятичных чисел в одном байте.

    09-06-2012 Super User

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

    ПП чтения данных из Flash памяти программ.

    24-05-2012 Super User

     Для чтения содержимого памяти программ используется инструкция (команда) TBLRD. Она имеет несколько разновидностей: TBLRD*     - чтение TBLRD*+ - чтение +1 TBLRD*-  - чтение -1 TBLRD+* - +1,чтение В программе необходимо предварительно записать в указательTBLPTRадрес таблицы (байт) данных,  к примеру,  здесь  задан...

    Помехоустойчивое кодирование на примере кода Хэмминга

    13-05-2011 Иван Шевченко (R1ZK)

    Помехоустойчивое кодирование на примере кода Хэмминга

    Исправлять ошибки труднее, чем их детектировать, или предотвращать. (Не моё - одна бабка сказала...) Код Хэмминга, о котором здесь идёт речь, представляет собой блочный код, который позволяет выявить и исправить один ошибочно переданный бит в пределах переданного блока.      


    Все права принадлежат ChipMK.ru. При копировании материала ссылка обязательна. 2011-2017 © ChipMK.ru

    ChipMk.ru Яндекс.Метрика
    PRCY.ru